Changeset 745 for trunk/server/source3/libsmb/libsmb_xattr.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/libsmb/libsmb_xattr.c
r414 r745 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" 28 29 #include "../librpc/gen_ndr/ndr_lsa.h" 30 #include "rpc_client/rpc_client.h" 31 #include "rpc_client/cli_lsarpc.h" 32 #include "../libcli/security/security.h" 29 33 30 34 /* … … 35 39 { 36 40 struct rpc_pipe_client *pipe_hnd; 37 41 38 42 for (pipe_hnd = ipc_cli->pipe_list; 39 43 pipe_hnd; 40 44 pipe_hnd = pipe_hnd->next) { 41 42 45 if (ndr_syntax_id_equal(&pipe_hnd->abstract_syntax, 43 46 &ndr_table_lsarpc.syntax_id)) { … … 45 48 } 46 49 } 47 48 50 return NULL; 49 51 } … … 56 58 57 59 static int 58 ace_compare( SEC_ACE*ace1,59 SEC_ACE*ace2)60 ace_compare(struct security_ace *ace1, 61 struct security_ace *ace2) 60 62 { 61 63 bool b1; 62 64 bool b2; 63 65 64 66 /* If the ACEs are equal, we have nothing more to do. */ 65 67 if (sec_ace_equal(ace1, ace2)) { 66 68 return 0; 67 69 } 68 70 69 71 /* Inherited follow non-inherited */ 70 72 b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); … … 73 75 return (b1 ? 1 : -1); 74 76 } 75 77 76 78 /* 77 79 * What shall we do with AUDITs and ALARMs? It's undefined. We'll … … 89 91 return (b1 ? 1 : -1); 90 92 } 91 93 92 94 /* Allowed ACEs follow denied ACEs */ 93 95 b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || … … 98 100 return (b1 ? 1 : -1); 99 101 } 100 102 101 103 /* 102 104 * ACEs applying to an entity's object follow those applying to the … … 110 112 return (b1 ? 1 : -1); 111 113 } 112 114 113 115 /* 114 116 * If we get this far, the ACEs are similar as far as the … … 117 119 * just seems reasonable. 118 120 */ 119 121 120 122 if (ace1->type != ace2->type) { 121 123 return ace2->type - ace1->type; 122 124 } 123 124 if ( sid_compare(&ace1->trustee, &ace2->trustee)) {125 return sid_compare(&ace1->trustee, &ace2->trustee);126 } 127 125 126 if (dom_sid_compare(&ace1->trustee, &ace2->trustee)) { 127 return dom_sid_compare(&ace1->trustee, &ace2->trustee); 128 } 129 128 130 if (ace1->flags != ace2->flags) { 129 131 return ace1->flags - ace2->flags; 130 132 } 131 133 132 134 if (ace1->access_mask != ace2->access_mask) { 133 135 return ace1->access_mask - ace2->access_mask; 134 136 } 135 137 136 138 if (ace1->size != ace2->size) { 137 139 return ace1->size - ace2->size; 138 140 } 139 140 return memcmp(ace1, ace2, sizeof( SEC_ACE));141 142 return memcmp(ace1, ace2, sizeof(struct security_ace)); 141 143 } 142 144 143 145 144 146 static void 145 sort_acl( SEC_ACL*the_acl)147 sort_acl(struct security_acl *the_acl) 146 148 { 147 149 uint32 i; 148 150 if (!the_acl) return; 149 150 qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), 151 QSORT_CAST ace_compare); 152 151 152 TYPESAFE_QSORT(the_acl->aces, the_acl->num_aces, ace_compare); 153 153 154 for (i=1;i<the_acl->num_aces;) { 154 155 if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { … … 170 171 fstring str, 171 172 bool numeric, 172 DOM_SID*sid)173 struct dom_sid *sid) 173 174 { 174 175 char **domains = NULL; … … 177 178 struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); 178 179 TALLOC_CTX *ctx; 179 180 180 181 sid_to_fstring(str, sid); 181 182 182 183 if (numeric) { 183 184 return; /* no lookup desired */ 184 185 } 185 186 186 187 if (!pipe_hnd) { 187 188 return; 188 189 } 189 190 190 191 /* Ask LSA to convert the sid to a name */ 191 192 192 193 ctx = talloc_stackframe(); 193 194 194 195 if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, 195 196 pol, 1, sid, &domains, … … 199 200 return; 200 201 } 201 202 202 203 /* Converted OK */ 203 204 204 205 slprintf(str, sizeof(fstring) - 1, "%s%s%s", 205 206 domains[0], lp_winbind_separator(), … … 214 215 struct policy_handle *pol, 215 216 bool numeric, 216 DOM_SID*sid,217 struct dom_sid *sid, 217 218 const char *str) 218 219 { 219 220 enum lsa_SidType *types = NULL; 220 DOM_SID*sids = NULL;221 struct dom_sid *sids = NULL; 221 222 bool result = True; 222 223 TALLOC_CTX *ctx = NULL; 223 224 struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); 224 225 225 226 if (!pipe_hnd) { 226 227 return False; 227 228 } 228 229 229 230 if (numeric) { 230 231 if (strncmp(str, "S-", 2) == 0) { 231 232 return string_to_sid(sid, str); 232 233 } 233 234 234 235 result = False; 235 236 goto done; 236 237 } 237 238 238 239 ctx = talloc_stackframe(); 239 240 if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, … … 244 245 goto done; 245 246 } 246 247 247 248 sid_copy(sid, &sids[0]); 248 249 done: 249 250 250 TALLOC_FREE(ctx); 251 251 return result; … … 253 253 254 254 255 /* parse an ACEin the same format as print_ace() */255 /* parse an struct security_ace in the same format as print_ace() */ 256 256 static bool 257 257 parse_ace(struct cli_state *ipc_cli, 258 258 struct policy_handle *pol, 259 SEC_ACE*ace,259 struct security_ace *ace, 260 260 bool numeric, 261 261 char *str) … … 267 267 unsigned int aflags; 268 268 unsigned int amask; 269 DOM_SIDsid;269 struct dom_sid sid; 270 270 uint32_t mask; 271 271 const struct perm_value *v; … … 275 275 }; 276 276 TALLOC_CTX *frame = talloc_stackframe(); 277 277 278 278 /* These values discovered by inspection */ 279 279 static const struct perm_value special_values[] = { … … 286 286 { "", 0 }, 287 287 }; 288 288 289 289 static const struct perm_value standard_values[] = { 290 290 { "READ", 0x001200a9 }, … … 293 293 { "", 0 }, 294 294 }; 295 296 295 297 296 ZERO_STRUCTP(ace); 298 297 p = strchr_m(str,':'); … … 304 303 p++; 305 304 /* Try to parse numeric form */ 306 305 307 306 if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && 308 307 convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { 309 308 goto done; 310 309 } 311 310 312 311 /* Try to parse text form */ 313 312 314 313 if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { 315 314 TALLOC_FREE(frame); 316 315 return false; 317 316 } 318 317 319 318 cp = p; 320 319 if (!next_token_talloc(frame, &cp, &tok, "/")) { … … 322 321 return false; 323 322 } 324 323 325 324 if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { 326 325 atype = SEC_ACE_TYPE_ACCESS_ALLOWED; … … 331 330 return false; 332 331 } 333 332 334 333 /* Only numeric form accepted for flags at present */ 335 334 336 335 if (!(next_token_talloc(frame, &cp, &tok, "/") && 337 336 sscanf(tok, "%i", &aflags))) { … … 339 338 return false; 340 339 } 341 340 342 341 if (!next_token_talloc(frame, &cp, &tok, "/")) { 343 342 TALLOC_FREE(frame); 344 343 return false; 345 344 } 346 345 347 346 if (strncmp(tok, "0x", 2) == 0) { 348 347 if (sscanf(tok, "%i", &amask) != 1) { … … 352 351 goto done; 353 352 } 354 353 355 354 for (v = standard_values; v->perm; v++) { 356 355 if (strcmp(tok, v->perm) == 0) { … … 359 358 } 360 359 } 361 360 362 361 p = tok; 363 362 364 363 while(*p) { 365 364 bool found = False; 366 365 367 366 for (v = special_values; v->perm; v++) { 368 367 if (v->perm[0] == *p) { … … 371 370 } 372 371 } 373 372 374 373 if (!found) { 375 374 TALLOC_FREE(frame); … … 378 377 p++; 379 378 } 380 379 381 380 if (*p) { 382 381 TALLOC_FREE(frame); 383 382 return false; 384 383 } 385 384 386 385 done: 387 386 mask = amask; … … 391 390 } 392 391 393 /* add an ACE to a list of ACEs in a SEC_ACL*/392 /* add an struct security_ace to a list of struct security_aces in a struct security_acl */ 394 393 static bool 395 add_ace( SEC_ACL**the_acl,396 SEC_ACE*ace,394 add_ace(struct security_acl **the_acl, 395 struct security_ace *ace, 397 396 TALLOC_CTX *ctx) 398 397 { 399 SEC_ACL*newacl;400 SEC_ACE*aces;401 398 struct security_acl *newacl; 399 struct security_ace *aces; 400 402 401 if (! *the_acl) { 403 402 (*the_acl) = make_sec_acl(ctx, 3, 1, ace); 404 403 return True; 405 404 } 406 407 if ((aces = SMB_CALLOC_ARRAY( SEC_ACE,405 406 if ((aces = SMB_CALLOC_ARRAY(struct security_ace, 408 407 1+(*the_acl)->num_aces)) == NULL) { 409 408 return False; 410 409 } 411 memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof( SEC_ACE));412 memcpy(aces+(*the_acl)->num_aces, ace, sizeof( SEC_ACE));410 memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(struct security_ace)); 411 memcpy(aces+(*the_acl)->num_aces, ace, sizeof(struct security_ace)); 413 412 newacl = make_sec_acl(ctx, (*the_acl)->revision, 414 413 1+(*the_acl)->num_aces, aces); … … 420 419 421 420 /* parse a ascii version of a security descriptor */ 422 static SEC_DESC*421 static struct security_descriptor * 423 422 sec_desc_parse(TALLOC_CTX *ctx, 424 423 struct cli_state *ipc_cli, … … 429 428 const char *p = str; 430 429 char *tok; 431 SEC_DESC*ret = NULL;430 struct security_descriptor *ret = NULL; 432 431 size_t sd_size; 433 DOM_SID*group_sid=NULL;434 DOM_SID*owner_sid=NULL;435 SEC_ACL*dacl=NULL;432 struct dom_sid *group_sid=NULL; 433 struct dom_sid *owner_sid=NULL; 434 struct security_acl *dacl=NULL; 436 435 int revision=1; 437 436 438 437 while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { 439 438 440 439 if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { 441 440 revision = strtol(tok+9, NULL, 16); 442 441 continue; 443 442 } 444 443 445 444 if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { 446 445 if (owner_sid) { … … 448 447 goto done; 449 448 } 450 owner_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);449 owner_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 451 450 if (!owner_sid || 452 451 !convert_string_to_sid(ipc_cli, pol, … … 458 457 continue; 459 458 } 460 459 461 460 if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { 462 461 if (owner_sid) { … … 464 463 goto done; 465 464 } 466 owner_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);465 owner_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 467 466 if (!owner_sid || 468 467 !convert_string_to_sid(ipc_cli, pol, … … 474 473 continue; 475 474 } 476 475 477 476 if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { 478 477 if (group_sid) { … … 480 479 goto done; 481 480 } 482 group_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);481 group_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 483 482 if (!group_sid || 484 483 !convert_string_to_sid(ipc_cli, pol, … … 490 489 continue; 491 490 } 492 491 493 492 if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { 494 493 if (group_sid) { … … 496 495 goto done; 497 496 } 498 group_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);497 group_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 499 498 if (!group_sid || 500 499 !convert_string_to_sid(ipc_cli, pol, … … 506 505 continue; 507 506 } 508 507 509 508 if (StrnCaseCmp(tok,"ACL:", 4) == 0) { 510 SEC_ACEace;509 struct security_ace ace; 511 510 if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { 512 511 DEBUG(5, ("Failed to parse ACL %s\n", tok)); … … 519 518 continue; 520 519 } 521 520 522 521 if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { 523 SEC_ACEace;522 struct security_ace ace; 524 523 if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { 525 524 DEBUG(5, ("Failed to parse ACL %s\n", tok)); … … 532 531 continue; 533 532 } 534 533 535 534 DEBUG(5, ("Failed to parse security descriptor\n")); 536 535 goto done; 537 536 } 538 537 539 538 ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, 540 539 owner_sid, group_sid, NULL, dacl, &sd_size); 541 540 542 541 done: 543 542 SAFE_FREE(group_sid); 544 543 SAFE_FREE(owner_sid); 545 546 544 return ret; 547 545 } … … 563 561 SMB_INO_T inode = 0; 564 562 DOS_ATTR_DESC *ret; 565 563 566 564 ret = TALLOC_P(ctx, DOS_ATTR_DESC); 567 565 if (!ret) { … … 569 567 return NULL; 570 568 } 571 569 572 570 /* Obtain the DOS attributes */ 573 571 if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), … … 582 580 return NULL; 583 581 } 584 582 585 583 ret->mode = mode; 586 584 ret->size = size; … … 590 588 ret->change_time = convert_timespec_to_time_t(change_time_ts); 591 589 ret->inode = inode; 592 590 593 591 return ret; 594 592 } … … 612 610 const char * change_time_attr; 613 611 } attr_strings; 614 612 615 613 /* Determine whether to use old-style or new-style attribute names */ 616 614 if (context->internal->full_time_names) { … … 627 625 attr_strings.change_time_attr = "C_TIME"; 628 626 } 629 627 630 628 /* if this is to set the entire ACL... */ 631 629 if (*str == '*') { … … 637 635 } 638 636 } 639 637 640 638 frame = talloc_stackframe(); 641 639 while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { … … 652 650 continue; 653 651 } 654 652 655 653 if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { 656 654 dad->size = (SMB_OFF_T)atof(tok+5); 657 655 continue; 658 656 } 659 657 660 658 n = strlen(attr_strings.access_time_attr); 661 659 if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { … … 663 661 continue; 664 662 } 665 663 666 664 n = strlen(attr_strings.change_time_attr); 667 665 if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { … … 669 667 continue; 670 668 } 671 669 672 670 n = strlen(attr_strings.write_time_attr); 673 671 if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { … … 675 673 continue; 676 674 } 677 675 678 676 if (attr_strings.create_time_attr != NULL) { 679 677 n = strlen(attr_strings.create_time_attr); … … 685 683 } 686 684 } 687 685 688 686 if (StrnCaseCmp(tok, "INODE:", 6) == 0) { 689 687 dad->inode = (SMB_INO_T)atof(tok+6); … … 732 730 bool determine_size = (bufsize == 0); 733 731 uint16_t fnum; 734 SEC_DESC*sd;732 struct security_descriptor *sd; 735 733 fstring sidstr; 736 734 fstring name_sandbox; … … 762 760 const char * change_time_attr; 763 761 } excl_attr_strings; 764 762 765 763 /* Determine whether to use old-style or new-style attribute names */ 766 764 if (context->internal->full_time_names) { … … 770 768 attr_strings.write_time_attr = "WRITE_TIME"; 771 769 attr_strings.change_time_attr = "CHANGE_TIME"; 772 770 773 771 excl_attr_strings.create_time_attr = "CREATE_TIME"; 774 772 excl_attr_strings.access_time_attr = "ACCESS_TIME"; … … 781 779 attr_strings.write_time_attr = "M_TIME"; 782 780 attr_strings.change_time_attr = "C_TIME"; 783 781 784 782 excl_attr_strings.create_time_attr = NULL; 785 783 excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; … … 787 785 excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; 788 786 } 789 787 790 788 /* Copy name so we can strip off exclusions (if any are specified) */ 791 789 strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); 792 790 793 791 /* Ensure name is null terminated */ 794 792 name_sandbox[sizeof(name_sandbox) - 1] = '\0'; 795 793 796 794 /* Play in the sandbox */ 797 795 name = name_sandbox; 798 796 799 797 /* If there are any exclusions, point to them and mask them from name */ 800 798 if ((pExclude = strchr(name, '!')) != NULL) … … 802 800 *pExclude++ = '\0'; 803 801 } 804 802 805 803 all = (StrnCaseCmp(name, "system.*", 8) == 0); 806 804 all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); … … 810 808 some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); 811 809 numeric = (* (name + strlen(name) - 1) != '+'); 812 810 813 811 /* Look for exclusions from "all" requests */ 814 812 if (all || all_nt || all_dos) { 815 816 813 /* Exclusions are delimited by '!' */ 817 814 for (; 818 815 pExclude != NULL; 819 816 pExclude = (p == NULL ? NULL : p + 1)) { 820 817 821 818 /* Find end of this exclusion name */ 822 819 if ((p = strchr(pExclude, '!')) != NULL) … … 824 821 *p = '\0'; 825 822 } 826 823 827 824 /* Which exclusion name is this? */ 828 825 if (StrCaseCmp(pExclude, … … 878 875 } 879 876 } 880 877 881 878 n_used = 0; 882 879 883 880 /* 884 881 * If we are (possibly) talking to an NT or new system and some NT … … 951 948 } 952 949 } 953 950 954 951 if (!determine_size && n > bufsize) { 955 952 errno = ERANGE; … … 961 958 n = 0; 962 959 } 963 960 964 961 if (! exclude_nt_owner) { 965 962 /* Get owner and group sid */ … … 972 969 fstrcpy(sidstr, ""); 973 970 } 974 971 975 972 if (all || all_nt) { 976 973 if (determine_size) { … … 999 996 } 1000 997 } 1001 998 1002 999 if (!determine_size && n > bufsize) { 1003 1000 errno = ERANGE; … … 1009 1006 n = 0; 1010 1007 } 1011 1008 1012 1009 if (! exclude_nt_group) { 1013 1010 if (sd->group_sid) { … … 1018 1015 fstrcpy(sidstr, ""); 1019 1016 } 1020 1017 1021 1018 if (all || all_nt) { 1022 1019 if (determine_size) { … … 1045 1042 } 1046 1043 } 1047 1044 1048 1045 if (!determine_size && n > bufsize) { 1049 1046 errno = ERANGE; … … 1055 1052 n = 0; 1056 1053 } 1057 1054 1058 1055 if (! exclude_nt_acl) { 1059 1056 /* Add aces to value buffer */ 1060 1057 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { 1061 1062 SEC_ACE*ace = &sd->dacl->aces[i];1058 1059 struct security_ace *ace = &sd->dacl->aces[i]; 1063 1060 convert_sid_to_string(ipc_cli, pol, 1064 1061 sidstr, numeric, 1065 1062 &ace->trustee); 1066 1063 1067 1064 if (all || all_nt) { 1068 1065 if (determine_size) { … … 1147 1144 } 1148 1145 } 1149 1146 1150 1147 /* Restore name pointer to its original value */ 1151 1148 name -= 19; 1152 1149 } 1153 1150 1154 1151 if (all || some_dos) { 1155 1152 /* Point to the portion after "system.dos_attr." */ 1156 1153 name += 16; /* if (all) this will be invalid but unused */ 1157 1154 1158 1155 /* Obtain the DOS attributes */ 1159 1156 if (!SMBC_getatr(context, srv, filename, &mode, &size, … … 1163 1160 &change_time_ts, 1164 1161 &ino)) { 1165 1162 1166 1163 errno = SMBC_errno(context, srv->cli); 1167 1164 return -1; 1168 1169 } 1170 1165 } 1166 1171 1167 create_time = convert_timespec_to_time_t(create_time_ts); 1172 1168 access_time = convert_timespec_to_time_t(access_time_ts); 1173 1169 write_time = convert_timespec_to_time_t(write_time_ts); 1174 1170 change_time = convert_timespec_to_time_t(change_time_ts); 1175 1171 1176 1172 if (! exclude_dos_mode) { 1177 1173 if (all || all_dos) { … … 1211 1207 } 1212 1208 } 1213 1209 1214 1210 if (!determine_size && n > bufsize) { 1215 1211 errno = ERANGE; … … 1221 1217 n = 0; 1222 1218 } 1223 1219 1224 1220 if (! exclude_dos_size) { 1225 1221 if (all || all_dos) { … … 1256 1252 } 1257 1253 } 1258 1254 1259 1255 if (!determine_size && n > bufsize) { 1260 1256 errno = ERANGE; … … 1266 1262 n = 0; 1267 1263 } 1268 1264 1269 1265 if (! exclude_dos_create_time && 1270 1266 attr_strings.create_time_attr != NULL) { … … 1299 1295 } 1300 1296 } 1301 1297 1302 1298 if (!determine_size && n > bufsize) { 1303 1299 errno = ERANGE; … … 1309 1305 n = 0; 1310 1306 } 1311 1307 1312 1308 if (! exclude_dos_access_time) { 1313 1309 if (all || all_dos) { … … 1341 1337 } 1342 1338 } 1343 1339 1344 1340 if (!determine_size && n > bufsize) { 1345 1341 errno = ERANGE; … … 1351 1347 n = 0; 1352 1348 } 1353 1349 1354 1350 if (! exclude_dos_write_time) { 1355 1351 if (all || all_dos) { … … 1383 1379 } 1384 1380 } 1385 1381 1386 1382 if (!determine_size && n > bufsize) { 1387 1383 errno = ERANGE; … … 1393 1389 n = 0; 1394 1390 } 1395 1391 1396 1392 if (! exclude_dos_change_time) { 1397 1393 if (all || all_dos) { … … 1425 1421 } 1426 1422 } 1427 1423 1428 1424 if (!determine_size && n > bufsize) { 1429 1425 errno = ERANGE; … … 1435 1431 n = 0; 1436 1432 } 1437 1433 1438 1434 if (! exclude_dos_inode) { 1439 1435 if (all || all_dos) { … … 1470 1466 } 1471 1467 } 1472 1468 1473 1469 if (!determine_size && n > bufsize) { 1474 1470 errno = ERANGE; … … 1480 1476 n = 0; 1481 1477 } 1482 1478 1483 1479 /* Restore name pointer to its original value */ 1484 1480 name -= 16; 1485 1481 } 1486 1482 1487 1483 if (n_used == 0) { 1488 1484 errno = ENOATTR; 1489 1485 return -1; 1490 1486 } 1491 1487 1492 1488 return n_used; 1493 1489 } … … 1509 1505 uint16_t fnum = (uint16_t)-1; 1510 1506 int err = 0; 1511 SEC_DESC*sd = NULL, *old;1512 SEC_ACL*dacl = NULL;1513 DOM_SID*owner_sid = NULL;1514 DOM_SID*group_sid = NULL;1507 struct security_descriptor *sd = NULL, *old; 1508 struct security_acl *dacl = NULL; 1509 struct dom_sid *owner_sid = NULL; 1510 struct dom_sid *group_sid = NULL; 1515 1511 uint32 i, j; 1516 1512 size_t sd_size; … … 1520 1516 char *targetpath = NULL; 1521 1517 struct cli_state *targetcli = NULL; 1518 NTSTATUS status; 1522 1519 1523 1520 /* the_acl will be null for REMOVE_ALL operations */ … … 1526 1523 p > the_acl && 1527 1524 p[-1] != '+'); 1528 1525 1529 1526 /* if this is to set the entire ACL... */ 1530 1527 if (*the_acl == '*') { … … 1532 1529 the_acl = p + 1; 1533 1530 } 1534 1531 1535 1532 sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl); 1536 1537 1533 if (!sd) { 1538 1534 errno = EINVAL; … … 1540 1536 } 1541 1537 } 1542 1538 1543 1539 /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller 1544 1540 that doesn't deref sd */ 1545 1541 1546 1542 if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { 1547 1543 errno = EINVAL; … … 1602 1598 } 1603 1599 } 1604 1600 1605 1601 if (!found) { 1606 1602 err = ENOATTR; … … 1610 1606 } 1611 1607 break; 1612 1608 1613 1609 case SMBC_XATTR_MODE_ADD: 1614 1610 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 1615 1611 bool found = False; 1616 1612 1617 1613 for (j=0;old->dacl && j<old->dacl->num_aces;j++) { 1618 if ( sid_equal(&sd->dacl->aces[i].trustee,1614 if (dom_sid_equal(&sd->dacl->aces[i].trustee, 1619 1615 &old->dacl->aces[j].trustee)) { 1620 1616 if (!(flags & SMBC_XATTR_FLAG_CREATE)) { … … 1628 1624 } 1629 1625 } 1630 1626 1631 1627 if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { 1632 1628 err = ENOATTR; … … 1634 1630 goto failed; 1635 1631 } 1636 1632 1637 1633 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 1638 1634 add_ace(&old->dacl, &sd->dacl->aces[i], ctx); … … 1641 1637 dacl = old->dacl; 1642 1638 break; 1643 1639 1644 1640 case SMBC_XATTR_MODE_SET: 1645 1641 old = sd; … … 1648 1644 dacl = old->dacl; 1649 1645 break; 1650 1646 1651 1647 case SMBC_XATTR_MODE_CHOWN: 1652 1648 owner_sid = sd->owner_sid; 1653 1649 break; 1654 1650 1655 1651 case SMBC_XATTR_MODE_CHGRP: 1656 1652 group_sid = sd->group_sid; 1657 1653 break; 1658 1654 } 1659 1655 1660 1656 /* Denied ACE entries must come before allowed ones */ 1661 1657 sort_acl(old->dacl); 1662 1658 1663 1659 /* Create new security descriptor and set it */ 1664 1660 sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, 1665 1661 owner_sid, group_sid, NULL, dacl, &sd_size); 1666 1662 1667 1663 if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0, 1668 1664 WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0, … … 1673 1669 return -1; 1674 1670 } 1675 1676 if (!cli_set_secdesc(targetcli, fnum, sd)) { 1671 1672 status = cli_set_secdesc(targetcli, fnum, sd); 1673 if (!NT_STATUS_IS_OK(status)) { 1677 1674 DEBUG(5, ("ERROR: secdesc set failed: %s\n", 1678 cli_errstr(targetcli)));1675 nt_errstr(status))); 1679 1676 ret = -1; 1680 1677 } 1681 1678 1682 1679 /* Clean up */ 1683 1680 1684 1681 failed: 1685 1682 cli_close(targetcli, fnum); 1686 1683 1687 1684 if (err != 0) { 1688 1685 errno = err; 1689 1686 } 1690 1687 1691 1688 return ret; 1692 1689 } … … 1719 1716 } attr_strings; 1720 1717 TALLOC_CTX *frame = talloc_stackframe(); 1721 1718 1722 1719 if (!context || !context->internal->initialized) { 1723 1724 1720 errno = EINVAL; /* Best I can think of ... */ 1725 1721 TALLOC_FREE(frame); 1726 1722 return -1; 1727 1723 } 1728 1724 1729 1725 if (!fname) { 1730 1726 errno = EINVAL; … … 1732 1728 return -1; 1733 1729 } 1734 1730 1735 1731 DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", 1736 1732 fname, name, (int) size, (const char*)value)); 1737 1733 1738 1734 if (SMBC_parse_path(frame, 1739 1735 context, … … 1750 1746 return -1; 1751 1747 } 1752 1748 1753 1749 if (!user || user[0] == (char)0) { 1754 1750 user = talloc_strdup(frame, smbc_getUser(context)); … … 1759 1755 } 1760 1756 } 1761 1757 1762 1758 srv = SMBC_server(frame, context, True, 1763 1759 server, share, &workgroup, &user, &password); … … 1766 1762 return -1; /* errno set by SMBC_server */ 1767 1763 } 1768 1764 1769 1765 if (! srv->no_nt_session) { 1770 1766 ipc_srv = SMBC_attr_server(frame, context, server, share, … … 1776 1772 ipc_srv = NULL; 1777 1773 } 1778 1774 1779 1775 /* 1780 1776 * Are they asking to set the entire set of known attributes? … … 1792 1788 return -1; 1793 1789 } 1794 1790 1795 1791 if (ipc_srv) { 1796 1792 ret = cacl_set(context, talloc_tos(), srv->cli, … … 1804 1800 ret = 0; 1805 1801 } 1806 1802 1807 1803 /* get a DOS Attribute Descriptor with current attributes */ 1808 1804 dad = dos_attr_query(context, talloc_tos(), path, srv); … … 1810 1806 /* Overwrite old with new, using what was provided */ 1811 1807 dos_attr_parse(context, dad, srv, namevalue); 1812 1808 1813 1809 /* Set the new DOS attributes */ 1814 1810 if (! SMBC_setatr(context, srv, path, … … 1818 1814 dad->change_time, 1819 1815 dad->mode)) { 1820 1816 1821 1817 /* cause failure if NT failed too */ 1822 1818 dad = NULL; 1823 1819 } 1824 1820 } 1825 1821 1826 1822 /* we only fail if both NT and DOS sets failed */ 1827 1823 if (ret < 0 && ! dad) { … … 1831 1827 ret = 0; 1832 1828 } 1833 1829 1834 1830 TALLOC_FREE(frame); 1835 1831 return ret; 1836 1832 } 1837 1833 1838 1834 /* 1839 1835 * Are they asking to set an access control element or to set … … 1845 1841 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 1846 1842 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { 1847 1843 1848 1844 /* Yup. */ 1849 1845 char *namevalue = 1850 1846 talloc_asprintf(talloc_tos(), "%s:%s", 1851 1847 name+19, (const char *) value); 1852 1848 1853 1849 if (! ipc_srv) { 1854 1850 ret = -1; /* errno set by SMBC_server() */ … … 1869 1865 return ret; 1870 1866 } 1871 1867 1872 1868 /* 1873 1869 * Are they asking to set the owner? … … 1875 1871 if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || 1876 1872 StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { 1877 1873 1878 1874 /* Yup. */ 1879 1875 char *namevalue = 1880 1876 talloc_asprintf(talloc_tos(), "%s:%s", 1881 1877 name+19, (const char *) value); 1882 1878 1883 1879 if (! ipc_srv) { 1884 1880 ret = -1; /* errno set by SMBC_server() */ … … 1895 1891 return ret; 1896 1892 } 1897 1893 1898 1894 /* 1899 1895 * Are they asking to set the group? … … 1901 1897 if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || 1902 1898 StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { 1903 1899 1904 1900 /* Yup. */ 1905 1901 char *namevalue = 1906 1902 talloc_asprintf(talloc_tos(), "%s:%s", 1907 1903 name+19, (const char *) value); 1908 1904 1909 1905 if (! ipc_srv) { 1910 1906 /* errno set by SMBC_server() */ … … 1922 1918 return ret; 1923 1919 } 1924 1920 1925 1921 /* Determine whether to use old-style or new-style attribute names */ 1926 1922 if (context->internal->full_time_names) { … … 1937 1933 attr_strings.change_time_attr = "system.dos_attr.C_TIME"; 1938 1934 } 1939 1935 1940 1936 /* 1941 1937 * Are they asking to set a DOS attribute? … … 1948 1944 StrCaseCmp(name, attr_strings.write_time_attr) == 0 || 1949 1945 StrCaseCmp(name, attr_strings.change_time_attr) == 0) { 1950 1946 1951 1947 /* get a DOS Attribute Descriptor with current attributes */ 1952 1948 dad = dos_attr_query(context, talloc_tos(), path, srv); … … 1961 1957 /* Overwrite old with provided new params */ 1962 1958 dos_attr_parse(context, dad, srv, namevalue); 1963 1959 1964 1960 /* Set the new DOS attributes */ 1965 1961 ret2 = SMBC_setatr(context, srv, path, … … 1969 1965 dad->change_time, 1970 1966 dad->mode); 1971 1967 1972 1968 /* ret2 has True (success) / False (failure) */ 1973 1969 if (ret2) { … … 1980 1976 ret = -1; 1981 1977 } 1982 1978 1983 1979 TALLOC_FREE(frame); 1984 1980 return ret; 1985 1981 } 1986 1982 1987 1983 /* Unsupported attribute name */ 1988 1984 errno = EINVAL; … … 2014 2010 } attr_strings; 2015 2011 TALLOC_CTX *frame = talloc_stackframe(); 2016 2012 2017 2013 if (!context || !context->internal->initialized) { 2018 2019 2014 errno = EINVAL; /* Best I can think of ... */ 2020 2015 TALLOC_FREE(frame); 2021 2016 return -1; 2022 2017 } 2023 2018 2024 2019 if (!fname) { 2025 2020 errno = EINVAL; … … 2027 2022 return -1; 2028 2023 } 2029 2024 2030 2025 DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); 2031 2026 2032 2027 if (SMBC_parse_path(frame, 2033 2028 context, … … 2044 2039 return -1; 2045 2040 } 2046 2041 2047 2042 if (!user || user[0] == (char)0) { 2048 2043 user = talloc_strdup(frame, smbc_getUser(context)); … … 2053 2048 } 2054 2049 } 2055 2050 2056 2051 srv = SMBC_server(frame, context, True, 2057 2052 server, share, &workgroup, &user, &password); … … 2060 2055 return -1; /* errno set by SMBC_server */ 2061 2056 } 2062 2057 2063 2058 if (! srv->no_nt_session) { 2064 2059 ipc_srv = SMBC_attr_server(frame, context, server, share, … … 2070 2065 ipc_srv = NULL; 2071 2066 } 2072 2067 2073 2068 /* Determine whether to use old-style or new-style attribute names */ 2074 2069 if (context->internal->full_time_names) { … … 2085 2080 attr_strings.change_time_attr = "system.dos_attr.C_TIME"; 2086 2081 } 2087 2082 2088 2083 /* Are they requesting a supported attribute? */ 2089 2084 if (StrCaseCmp(name, "system.*") == 0 || … … 2112 2107 StrCaseCmp(name, attr_strings.change_time_attr) == 0 || 2113 2108 StrCaseCmp(name, "system.dos_attr.inode") == 0) { 2114 2109 2115 2110 /* Yup. */ 2116 2111 char *filename = (char *) name; … … 2127 2122 return ret; 2128 2123 } 2129 2124 2130 2125 /* Unsupported attribute name */ 2131 2126 errno = EINVAL; … … 2150 2145 char *path = NULL; 2151 2146 TALLOC_CTX *frame = talloc_stackframe(); 2152 2147 2153 2148 if (!context || !context->internal->initialized) { 2154 2155 2149 errno = EINVAL; /* Best I can think of ... */ 2156 2150 TALLOC_FREE(frame); 2157 2151 return -1; 2158 2152 } 2159 2153 2160 2154 if (!fname) { 2161 2155 errno = EINVAL; … … 2163 2157 return -1; 2164 2158 } 2165 2159 2166 2160 DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); 2167 2161 2168 2162 if (SMBC_parse_path(frame, 2169 2163 context, … … 2180 2174 return -1; 2181 2175 } 2182 2176 2183 2177 if (!user || user[0] == (char)0) { 2184 2178 user = talloc_strdup(frame, smbc_getUser(context)); … … 2189 2183 } 2190 2184 } 2191 2185 2192 2186 srv = SMBC_server(frame, context, True, 2193 2187 server, share, &workgroup, &user, &password); … … 2196 2190 return -1; /* errno set by SMBC_server */ 2197 2191 } 2198 2192 2199 2193 if (! srv->no_nt_session) { 2200 2194 ipc_srv = SMBC_attr_server(frame, context, server, share, … … 2206 2200 ipc_srv = NULL; 2207 2201 } 2208 2202 2209 2203 if (! ipc_srv) { 2210 2204 TALLOC_FREE(frame); 2211 2205 return -1; /* errno set by SMBC_attr_server */ 2212 2206 } 2213 2207 2214 2208 /* Are they asking to set the entire ACL? */ 2215 2209 if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || 2216 2210 StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { 2217 2211 2218 2212 /* Yup. */ 2219 2213 ret = cacl_set(context, talloc_tos(), srv->cli, … … 2223 2217 return ret; 2224 2218 } 2225 2219 2226 2220 /* 2227 2221 * Are they asking to remove one or more spceific security descriptor … … 2235 2229 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 2236 2230 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { 2237 2231 2238 2232 /* Yup. */ 2239 2233 ret = cacl_set(context, talloc_tos(), srv->cli, … … 2244 2238 return ret; 2245 2239 } 2246 2240 2247 2241 /* Unsupported attribute name */ 2248 2242 errno = EINVAL; … … 2303 2297 ; 2304 2298 const char * supported; 2305 2299 2306 2300 if (context->internal->full_time_names) { 2307 2301 supported = supported_new; … … 2311 2305 retsize = sizeof(supported_old); 2312 2306 } 2313 2307 2314 2308 if (size == 0) { 2315 2309 return retsize; 2316 2310 } 2317 2311 2318 2312 if (retsize > size) { 2319 2313 errno = ERANGE; 2320 2314 return -1; 2321 2315 } 2322 2316 2323 2317 /* this can't be strcpy() because there are embedded null characters */ 2324 2318 memcpy(list, supported, retsize);
Note:
See TracChangeset
for help on using the changeset viewer.