Changeset 988 for vendor/current/source3/utils/sharesec.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/utils/sharesec.c
r740 r988 22 22 */ 23 23 24 struct cli_state; 24 25 25 26 #include "includes.h" … … 27 28 #include "../libcli/security/security.h" 28 29 #include "passdb/machine_sid.h" 30 #include "util_sd.h" 29 31 30 32 static TALLOC_CTX *ctx; … … 35 37 SMB_ACL_SET, 36 38 SMB_SD_DELETE, 37 SMB_ACL_VIEW }; 38 39 struct perm_value { 40 const char *perm; 41 uint32 mask; 42 }; 43 44 /* These values discovered by inspection */ 45 46 static const struct perm_value special_values[] = { 47 { "R", SEC_RIGHTS_FILE_READ }, 48 { "W", SEC_RIGHTS_FILE_WRITE }, 49 { "X", SEC_RIGHTS_FILE_EXECUTE }, 50 { "D", SEC_STD_DELETE }, 51 { "P", SEC_STD_WRITE_DAC }, 52 { "O", SEC_STD_WRITE_OWNER }, 53 { NULL, 0 }, 54 }; 55 56 #define SEC_RIGHTS_DIR_CHANGE ( SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\ 57 SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE ) 58 59 static const struct perm_value standard_values[] = { 60 { "READ", SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE }, 61 { "CHANGE", SEC_RIGHTS_DIR_CHANGE }, 62 { "FULL", SEC_RIGHTS_DIR_ALL }, 63 { NULL, 0 }, 64 }; 65 66 /******************************************************************** 67 print an ACE on a FILE 68 ********************************************************************/ 69 70 static void print_ace(FILE *f, struct security_ace *ace) 71 { 72 const struct perm_value *v; 73 int do_print = 0; 74 uint32 got_mask; 75 76 fprintf(f, "%s:", sid_string_tos(&ace->trustee)); 77 78 /* Ace type */ 79 80 if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) { 81 fprintf(f, "ALLOWED"); 82 } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) { 83 fprintf(f, "DENIED"); 84 } else { 85 fprintf(f, "%d", ace->type); 86 } 87 88 /* Not sure what flags can be set in a file ACL */ 89 90 fprintf(f, "/%d/", ace->flags); 91 92 /* Standard permissions */ 93 94 for (v = standard_values; v->perm; v++) { 95 if (ace->access_mask == v->mask) { 96 fprintf(f, "%s", v->perm); 97 return; 98 } 99 } 100 101 /* Special permissions. Print out a hex value if we have 102 leftover bits in the mask. */ 103 104 got_mask = ace->access_mask; 105 106 again: 107 for (v = special_values; v->perm; v++) { 108 if ((ace->access_mask & v->mask) == v->mask) { 109 if (do_print) { 110 fprintf(f, "%s", v->perm); 111 } 112 got_mask &= ~v->mask; 113 } 114 } 115 116 if (!do_print) { 117 if (got_mask != 0) { 118 fprintf(f, "0x%08x", ace->access_mask); 119 } else { 120 do_print = 1; 121 goto again; 122 } 123 } 124 } 125 126 /******************************************************************** 127 print an ascii version of a security descriptor on a FILE handle 128 ********************************************************************/ 129 130 static void sec_desc_print(FILE *f, struct security_descriptor *sd) 131 { 132 uint32 i; 133 134 fprintf(f, "REVISION:%d\n", sd->revision); 135 136 /* Print owner and group sid */ 137 138 fprintf(f, "OWNER:%s\n", sid_string_tos(sd->owner_sid)); 139 140 fprintf(f, "GROUP:%s\n", sid_string_tos(sd->group_sid)); 141 142 /* Print aces */ 143 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { 144 struct security_ace *ace = &sd->dacl->aces[i]; 145 fprintf(f, "ACL:"); 146 print_ace(f, ace); 147 fprintf(f, "\n"); 148 } 149 } 150 151 /******************************************************************** 152 parse an ACE in the same format as print_ace() 153 ********************************************************************/ 154 155 static bool parse_ace(struct security_ace *ace, const char *orig_str) 156 { 157 char *p; 158 const char *cp; 159 char *tok; 160 unsigned int atype = 0; 161 unsigned int aflags = 0; 162 unsigned int amask = 0; 163 struct dom_sid sid; 164 uint32_t mask; 165 const struct perm_value *v; 166 char *str = SMB_STRDUP(orig_str); 167 TALLOC_CTX *frame = talloc_stackframe(); 168 169 if (!str) { 170 TALLOC_FREE(frame); 171 return False; 172 } 173 174 ZERO_STRUCTP(ace); 175 p = strchr_m(str,':'); 176 if (!p) { 177 fprintf(stderr, "ACE '%s': missing ':'.\n", orig_str); 178 SAFE_FREE(str); 179 TALLOC_FREE(frame); 180 return False; 181 } 182 *p = '\0'; 183 p++; 184 /* Try to parse numeric form */ 185 186 if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && 187 string_to_sid(&sid, str)) { 188 goto done; 189 } 190 191 /* Try to parse text form */ 192 193 if (!string_to_sid(&sid, str)) { 194 fprintf(stderr, "ACE '%s': failed to convert '%s' to SID\n", 195 orig_str, str); 196 SAFE_FREE(str); 197 TALLOC_FREE(frame); 198 return False; 199 } 200 201 cp = p; 202 if (!next_token_talloc(frame, &cp, &tok, "/")) { 203 fprintf(stderr, "ACE '%s': failed to find '/' character.\n", 204 orig_str); 205 SAFE_FREE(str); 206 TALLOC_FREE(frame); 207 return False; 208 } 209 210 if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { 211 atype = SEC_ACE_TYPE_ACCESS_ALLOWED; 212 } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) { 213 atype = SEC_ACE_TYPE_ACCESS_DENIED; 214 } else { 215 fprintf(stderr, "ACE '%s': missing 'ALLOWED' or 'DENIED' " 216 "entry at '%s'\n", orig_str, tok); 217 SAFE_FREE(str); 218 TALLOC_FREE(frame); 219 return False; 220 } 221 222 /* Only numeric form accepted for flags at present */ 223 /* no flags on share permissions */ 224 225 if (!(next_token_talloc(frame, &cp, &tok, "/") && 226 sscanf(tok, "%i", &aflags) && aflags == 0)) { 227 fprintf(stderr, "ACE '%s': bad integer flags entry at '%s'\n", 228 orig_str, tok); 229 SAFE_FREE(str); 230 TALLOC_FREE(frame); 231 return False; 232 } 233 234 if (!next_token_talloc(frame, &cp, &tok, "/")) { 235 fprintf(stderr, "ACE '%s': missing / at '%s'\n", 236 orig_str, tok); 237 SAFE_FREE(str); 238 TALLOC_FREE(frame); 239 return False; 240 } 241 242 if (strncmp(tok, "0x", 2) == 0) { 243 if (sscanf(tok, "%i", &amask) != 1) { 244 fprintf(stderr, "ACE '%s': bad hex number at '%s'\n", 245 orig_str, tok); 246 TALLOC_FREE(frame); 247 SAFE_FREE(str); 248 return False; 249 } 250 goto done; 251 } 252 253 for (v = standard_values; v->perm; v++) { 254 if (strcmp(tok, v->perm) == 0) { 255 amask = v->mask; 256 goto done; 257 } 258 } 259 260 p = tok; 261 262 while(*p) { 263 bool found = False; 264 265 for (v = special_values; v->perm; v++) { 266 if (v->perm[0] == *p) { 267 amask |= v->mask; 268 found = True; 269 } 270 } 271 272 if (!found) { 273 fprintf(stderr, "ACE '%s': bad permission value at " 274 "'%s'\n", orig_str, p); 275 TALLOC_FREE(frame); 276 SAFE_FREE(str); 277 return False; 278 } 279 p++; 280 } 281 282 if (*p) { 283 TALLOC_FREE(frame); 284 SAFE_FREE(str); 285 return False; 286 } 287 288 done: 289 mask = amask; 290 init_sec_ace(ace, &sid, atype, mask, aflags); 291 SAFE_FREE(str); 292 TALLOC_FREE(frame); 293 return True; 294 } 295 39 SMB_SD_SETSDDL, 40 SMB_SD_VIEWSDDL, 41 SMB_ACL_VIEW, 42 SMB_ACL_VIEW_ALL }; 296 43 297 44 /******************************************************************** … … 313 60 num_ace = count_chars( pacl, ',' ) + 1; 314 61 315 if ( !(ace = TALLOC_ZERO_ARRAY( mem_ctx, struct security_ace, num_ace )) )62 if ( !(ace = talloc_zero_array( mem_ctx, struct security_ace, num_ace )) ) 316 63 return NULL; 317 64 … … 323 70 acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0'; 324 71 325 if ( !parse_ace( &ace[i], acl_string ) )72 if ( !parse_ace(NULL, &ace[i], acl_string ) ) 326 73 return NULL; 327 74 … … 367 114 static int ace_compare(struct security_ace *ace1, struct security_ace *ace2) 368 115 { 369 if (sec _ace_equal(ace1, ace2))116 if (security_ace_equal(ace1, ace2)) 370 117 return 0; 371 118 … … 390 137 static void sort_acl(struct security_acl *the_acl) 391 138 { 392 uint32 i;139 uint32_t i; 393 140 if (!the_acl) return; 394 141 … … 396 143 397 144 for (i=1;i<the_acl->num_aces;) { 398 if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { 145 if (security_ace_equal(&the_acl->aces[i-1], 146 &the_acl->aces[i])) { 399 147 int j; 400 148 for (j=i; j<the_acl->num_aces-1; j++) { … … 414 162 struct security_descriptor *old = NULL; 415 163 size_t sd_size = 0; 416 uint32 i, j;164 uint32_t i, j; 417 165 418 166 if (mode != SMB_ACL_SET && mode != SMB_SD_DELETE) { … … 431 179 432 180 switch (mode) { 181 case SMB_ACL_VIEW_ALL: 182 /* should not happen */ 183 return 0; 433 184 case SMB_ACL_VIEW: 434 sec_desc_print( stdout, old);185 sec_desc_print(NULL, stdout, old, false); 435 186 return 0; 436 187 case SMB_ACL_DELETE: … … 439 190 440 191 for (j=0;old->dacl && j<old->dacl->num_aces;j++) { 441 if (sec_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) { 442 uint32 k; 192 if (security_ace_equal(&sd->dacl->aces[i], 193 &old->dacl->aces[j])) { 194 uint32_t k; 443 195 for (k=j; k<old->dacl->num_aces-1;k++) { 444 196 old->dacl->aces[k] = old->dacl->aces[k+1]; … … 451 203 452 204 if (!found) { 453 printf("ACL for ACE:");454 print_ace(stdout, &sd->dacl->aces[i]);455 printf(" not found\n");205 printf("ACL for ACE:"); 206 print_ace(NULL, stdout, &sd->dacl->aces[i], false); 207 printf(" not found\n"); 456 208 } 457 209 } … … 498 250 } 499 251 return 0; 252 default: 253 fprintf(stderr, "invalid command\n"); 254 return -1; 500 255 } 501 256 … … 510 265 } 511 266 267 static int set_sharesec_sddl(const char *sharename, const char *sddl) 268 { 269 struct security_descriptor *sd; 270 bool ret; 271 272 sd = sddl_decode(talloc_tos(), sddl, get_global_sam_sid()); 273 if (sd == NULL) { 274 fprintf(stderr, "Failed to parse acl\n"); 275 return -1; 276 } 277 278 ret = set_share_security(sharename, sd); 279 TALLOC_FREE(sd); 280 if (!ret) { 281 fprintf(stderr, "Failed to store acl for share [%s]\n", 282 sharename); 283 return -1; 284 } 285 286 return 0; 287 } 288 289 static int view_sharesec_sddl(const char *sharename) 290 { 291 struct security_descriptor *sd; 292 size_t sd_size; 293 char *acl; 294 295 sd = get_share_security(talloc_tos(), sharename, &sd_size); 296 if (sd == NULL) { 297 fprintf(stderr, "Unable to retrieve permissions for share " 298 "[%s]\n", sharename); 299 return -1; 300 } 301 302 acl = sddl_encode(talloc_tos(), sd, get_global_sam_sid()); 303 TALLOC_FREE(sd); 304 if (acl == NULL) { 305 fprintf(stderr, "Unable to sddl-encode permissions for share " 306 "[%s]\n", sharename); 307 return -1; 308 } 309 printf("%s\n", acl); 310 TALLOC_FREE(acl); 311 return 0; 312 } 313 512 314 /******************************************************************** 513 315 main program 514 316 ********************************************************************/ 317 318 enum { 319 OPT_VIEW_ALL = 1000, 320 }; 515 321 516 322 int main(int argc, const char *argv[]) … … 532 338 { "replace", 'R', POPT_ARG_STRING, &the_acl, 'R', "Overwrite share permission ACL", "ACLS" }, 533 339 { "delete", 'D', POPT_ARG_NONE, NULL, 'D', "Delete the entire security descriptor" }, 340 { "setsddl", 'S', POPT_ARG_STRING, the_acl, 'S', 341 "Set the SD in sddl format" }, 342 { "viewsddl", 'V', POPT_ARG_NONE, the_acl, 'V', 343 "View the SD in sddl format" }, 534 344 { "view", 'v', POPT_ARG_NONE, NULL, 'v', "View current share permissions" }, 345 { "view-all", 0, POPT_ARG_NONE, NULL, OPT_VIEW_ALL, 346 "View all current share permissions" }, 535 347 { "machine-sid", 'M', POPT_ARG_NONE, NULL, 'M', "Initialize the machine SID" }, 536 348 { "force", 'F', POPT_ARG_NONE, NULL, 'F', "Force storing the ACL", "ACLS" }, … … 547 359 setup_logging( "sharesec", DEBUG_STDERR); 548 360 549 load_case_tables();361 smb_init_locale(); 550 362 551 363 lp_set_cmdline("log level", "1"); … … 581 393 break; 582 394 395 case 'S': 396 mode = SMB_SD_SETSDDL; 397 the_acl = smb_xstrdup(poptGetOptArg(pc)); 398 break; 399 400 case 'V': 401 mode = SMB_SD_VIEWSDDL; 402 break; 403 583 404 case 'v': 584 405 mode = SMB_ACL_VIEW; … … 592 413 initialize_sid = True; 593 414 break; 415 case OPT_VIEW_ALL: 416 mode = SMB_ACL_VIEW_ALL; 417 break; 594 418 } 595 419 } … … 597 421 setlinebuf(stdout); 598 422 599 lp_load_with_registry_shares( get_dyn_CONFIGFILE(), False, False, False, 600 True ); 423 lp_load_with_registry_shares(get_dyn_CONFIGFILE()); 601 424 602 425 /* check for initializing secrets.tdb first */ … … 619 442 } 620 443 444 if (mode == SMB_ACL_VIEW_ALL) { 445 int i; 446 447 for (i=0; i<lp_numservices(); i++) { 448 TALLOC_CTX *frame = talloc_stackframe(); 449 const char *service = lp_servicename(frame, i); 450 451 if (service == NULL) { 452 continue; 453 } 454 455 printf("[%s]\n", service); 456 change_share_sec(frame, service, NULL, SMB_ACL_VIEW); 457 printf("\n"); 458 TALLOC_FREE(frame); 459 } 460 goto done; 461 } 462 621 463 /* get the sharename */ 622 464 … … 635 477 } 636 478 637 retval = change_share_sec(ctx, sharename, the_acl, mode); 638 479 switch (mode) { 480 case SMB_SD_SETSDDL: 481 retval = set_sharesec_sddl(sharename, the_acl); 482 break; 483 case SMB_SD_VIEWSDDL: 484 retval = view_sharesec_sddl(sharename); 485 break; 486 default: 487 retval = change_share_sec(ctx, sharename, the_acl, mode); 488 break; 489 } 490 491 done: 639 492 talloc_destroy(ctx); 640 493
Note:
See TracChangeset
for help on using the changeset viewer.