utils/sharesec.c

ソースコードを見る。

データ構造

struct  perm_value

列挙型

enum  acl_mode {
  SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD,
  SMB_ACL_SET, SMB_ACL_VIEW
}

関数

static void print_ace (FILE *f, SEC_ACE *ace)
static void sec_desc_print (FILE *f, SEC_DESC *sd)
static BOOL parse_ace (SEC_ACE *ace, const char *orig_str)
static SEC_DESCparse_acl_string (TALLOC_CTX *mem_ctx, const char *szACL, size_t *sd_size)
static BOOL add_ace (TALLOC_CTX *mem_ctx, SEC_ACL **the_acl, SEC_ACE *ace)
static int ace_compare (SEC_ACE *ace1, SEC_ACE *ace2)
static void sort_acl (SEC_ACL *the_acl)
static int change_share_sec (TALLOC_CTX *mem_ctx, const char *sharename, char *the_acl, enum acl_mode mode)
int main (int argc, const char *argv[])

変数

static TALLOC_CTXctx
static struct perm_value special_values []
static struct perm_value standard_values []


列挙型

enum acl_mode

列挙型の値:
SMB_ACL_DELETE 
SMB_ACL_MODIFY 
SMB_ACL_ADD 
SMB_ACL_SET 
SMB_ACL_VIEW 

sharesec.c30 行で定義されています。


関数

static void print_ace ( FILE *  f,
SEC_ACE ace 
) [static]

sharesec.c62 行で定義されています。

参照先 security_ace_info::access_masksecurity_ace_info::flagsfprintf()perm_value::maskperm_value::permSEC_ACE_TYPE_ACCESS_ALLOWEDSEC_ACE_TYPE_ACCESS_DENIEDsid_string_static()standard_valuessecurity_ace_info::trusteesecurity_ace_info::type.

参照元 cacl_set()change_share_sec()sec_desc_print().

00063 {
00064         const struct perm_value *v;
00065         int do_print = 0;
00066         uint32 got_mask;
00067 
00068         fprintf(f, "%s:", sid_string_static(&ace->trustee));
00069 
00070         /* Ace type */
00071 
00072         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
00073                 fprintf(f, "ALLOWED");
00074         } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
00075                 fprintf(f, "DENIED");
00076         } else {
00077                 fprintf(f, "%d", ace->type);
00078         }
00079 
00080         /* Not sure what flags can be set in a file ACL */
00081 
00082         fprintf(f, "/%d/", ace->flags);
00083 
00084         /* Standard permissions */
00085 
00086         for (v = standard_values; v->perm; v++) {
00087                 if (ace->access_mask == v->mask) {
00088                         fprintf(f, "%s", v->perm);
00089                         return;
00090                 }
00091         }
00092 
00093         /* Special permissions.  Print out a hex value if we have
00094            leftover bits in the mask. */
00095 
00096         got_mask = ace->access_mask;
00097 
00098  again:
00099         for (v = special_values; v->perm; v++) {
00100                 if ((ace->access_mask & v->mask) == v->mask) {
00101                         if (do_print) {
00102                                 fprintf(f, "%s", v->perm);
00103                         }
00104                         got_mask &= ~v->mask;
00105                 }
00106         }
00107 
00108         if (!do_print) {
00109                 if (got_mask != 0) {
00110                         fprintf(f, "0x%08x", ace->access_mask);
00111                 } else {
00112                         do_print = 1;
00113                         goto again;
00114                 }
00115         }
00116 }

static void sec_desc_print ( FILE *  f,
SEC_DESC sd 
) [static]

sharesec.c122 行で定義されています。

参照先 security_acl_info::acessecurity_descriptor_info::daclfprintf()security_descriptor_info::group_sidsecurity_acl_info::num_acessecurity_descriptor_info::owner_sidprint_ace()security_descriptor_info::revisionsid_string_static().

参照元 cacl_dump()change_share_sec().

00123 {
00124         uint32 i;
00125 
00126         fprintf(f, "REVISION:%d\n", sd->revision);
00127 
00128         /* Print owner and group sid */
00129 
00130         fprintf(f, "OWNER:%s\n", sid_string_static(sd->owner_sid));
00131 
00132         fprintf(f, "GROUP:%s\n", sid_string_static(sd->group_sid));
00133 
00134         /* Print aces */
00135         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
00136                 SEC_ACE *ace = &sd->dacl->aces[i];
00137                 fprintf(f, "ACL:");
00138                 print_ace(f, ace);
00139                 fprintf(f, "\n");
00140         }
00141 
00142 }

static BOOL parse_ace ( SEC_ACE ace,
const char *  orig_str 
) [static]

sharesec.c148 行で定義されています。

参照先 perm_value::masknext_token()perm_value::permprintf()SEC_ACE_TYPE_ACCESS_ALLOWEDSEC_ACE_TYPE_ACCESS_DENIEDstandard_valuesstrchr_m()string_to_sid().

00149 {
00150         char *p;
00151         const char *cp;
00152         fstring tok;
00153         unsigned int atype = 0;
00154         unsigned int aflags = 0;
00155         unsigned int amask = 0;
00156         DOM_SID sid;
00157         SEC_ACCESS mask;
00158         const struct perm_value *v;
00159         char *str = SMB_STRDUP(orig_str);
00160 
00161         if (!str) {
00162                 return False;
00163         }
00164 
00165         ZERO_STRUCTP(ace);
00166         p = strchr_m(str,':');
00167         if (!p) {
00168                 printf("ACE '%s': missing ':'.\n", orig_str);
00169                 SAFE_FREE(str);
00170                 return False;
00171         }
00172         *p = '\0';
00173         p++;
00174         /* Try to parse numeric form */
00175 
00176         if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
00177             string_to_sid(&sid, str)) {
00178                 goto done;
00179         }
00180 
00181         /* Try to parse text form */
00182 
00183         if (!string_to_sid(&sid, str)) {
00184                 printf("ACE '%s': failed to convert '%s' to SID\n",
00185                         orig_str, str);
00186                 SAFE_FREE(str);
00187                 return False;
00188         }
00189 
00190         cp = p;
00191         if (!next_token(&cp, tok, "/", sizeof(fstring))) {
00192                 printf("ACE '%s': failed to find '/' character.\n",
00193                         orig_str);
00194                 SAFE_FREE(str);
00195                 return False;
00196         }
00197 
00198         if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
00199                 atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
00200         } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
00201                 atype = SEC_ACE_TYPE_ACCESS_DENIED;
00202         } else {
00203                 printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n",
00204                         orig_str, tok);
00205                 SAFE_FREE(str);
00206                 return False;
00207         }
00208 
00209         /* Only numeric form accepted for flags at present */
00210         /* no flags on share permissions */
00211 
00212         if (!(next_token(&cp, tok, "/", sizeof(fstring)) &&
00213               sscanf(tok, "%i", &aflags) && aflags == 0)) {
00214                 printf("ACE '%s': bad integer flags entry at '%s'\n",
00215                         orig_str, tok);
00216                 SAFE_FREE(str);
00217                 return False;
00218         }
00219 
00220         if (!next_token(&cp, tok, "/", sizeof(fstring))) {
00221                 printf("ACE '%s': missing / at '%s'\n",
00222                         orig_str, tok);
00223                 SAFE_FREE(str);
00224                 return False;
00225         }
00226 
00227         if (strncmp(tok, "0x", 2) == 0) {
00228                 if (sscanf(tok, "%i", &amask) != 1) {
00229                         printf("ACE '%s': bad hex number at '%s'\n",
00230                                 orig_str, tok);
00231                         SAFE_FREE(str);
00232                         return False;
00233                 }
00234                 goto done;
00235         }
00236 
00237         for (v = standard_values; v->perm; v++) {
00238                 if (strcmp(tok, v->perm) == 0) {
00239                         amask = v->mask;
00240                         goto done;
00241                 }
00242         }
00243 
00244         p = tok;
00245 
00246         while(*p) {
00247                 BOOL found = False;
00248 
00249                 for (v = special_values; v->perm; v++) {
00250                         if (v->perm[0] == *p) {
00251                                 amask |= v->mask;
00252                                 found = True;
00253                         }
00254                 }
00255 
00256                 if (!found) {
00257                         printf("ACE '%s': bad permission value at '%s'\n",
00258                                 orig_str, p);
00259                         SAFE_FREE(str);
00260                         return False;
00261                 }
00262                 p++;
00263         }
00264 
00265         if (*p) {
00266                 SAFE_FREE(str);
00267                 return False;
00268         }
00269 
00270  done:
00271         mask = amask;
00272         init_sec_ace(ace, &sid, atype, mask, aflags);
00273         SAFE_FREE(str);
00274         return True;
00275 }

static SEC_DESC* parse_acl_string ( TALLOC_CTX mem_ctx,
const char *  szACL,
size_t *  sd_size 
) [static]

sharesec.c281 行で定義されています。

参照先 count_chars()make_sec_acl()make_sec_desc()parse_ace()strchr_m().

参照元 change_share_sec().

00282 {
00283         SEC_DESC *sd = NULL;
00284         SEC_ACE *ace;
00285         SEC_ACL *acl;
00286         int num_ace;
00287         const char *pacl;
00288         int i;
00289         
00290         if ( !szACL )
00291                 return NULL;
00292 
00293         pacl = szACL;
00294         num_ace = count_chars( pacl, ',' ) + 1;
00295         
00296         if ( !(ace = TALLOC_ZERO_ARRAY( mem_ctx, SEC_ACE, num_ace )) ) 
00297                 return NULL;
00298         
00299         for ( i=0; i<num_ace; i++ ) {
00300                 char *end_acl = strchr_m( pacl, ',' );
00301                 fstring acl_string;
00302 
00303                 strncpy( acl_string, pacl, MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1) );
00304                 acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0';
00305                 
00306                 if ( !parse_ace( &ace[i], acl_string ) )
00307                         return NULL;
00308 
00309                 pacl = end_acl;
00310                 pacl++;
00311         }
00312         
00313         if ( !(acl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) )
00314                 return NULL;
00315                 
00316         sd = make_sec_desc( mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, 
00317                 NULL, NULL, NULL, acl, sd_size);
00318 
00319         return sd;
00320 }

static BOOL add_ace ( TALLOC_CTX mem_ctx,
SEC_ACL **  the_acl,
SEC_ACE ace 
) [static]

sharesec.c323 行で定義されています。

参照先 make_sec_acl().

00324 {
00325         SEC_ACL *new_ace;
00326         SEC_ACE *aces;
00327         if (! *the_acl) {
00328                 return (((*the_acl) = make_sec_acl(mem_ctx, 3, 1, ace)) != NULL);
00329         }
00330 
00331         if (!(aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces))) {
00332                 return False;
00333         }
00334         memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE));
00335         memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
00336         new_ace = make_sec_acl(mem_ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
00337         SAFE_FREE(aces);
00338         (*the_acl) = new_ace;
00339         return True;
00340 }

static int ace_compare ( SEC_ACE ace1,
SEC_ACE ace2 
) [static]

sharesec.c347 行で定義されています。

参照先 security_ace_info::access_masksecurity_ace_info::flagssec_ace_equal()sid_compare()security_ace_info::sizesecurity_ace_info::trusteesecurity_ace_info::type.

00348 {
00349         if (sec_ace_equal(ace1, ace2)) 
00350                 return 0;
00351 
00352         if (ace1->type != ace2->type) 
00353                 return ace2->type - ace1->type;
00354 
00355         if (sid_compare(&ace1->trustee, &ace2->trustee)) 
00356                 return sid_compare(&ace1->trustee, &ace2->trustee);
00357 
00358         if (ace1->flags != ace2->flags) 
00359                 return ace1->flags - ace2->flags;
00360 
00361         if (ace1->access_mask != ace2->access_mask) 
00362                 return ace1->access_mask - ace2->access_mask;
00363 
00364         if (ace1->size != ace2->size) 
00365                 return ace1->size - ace2->size;
00366 
00367         return memcmp(ace1, ace2, sizeof(SEC_ACE));
00368 }

static void sort_acl ( SEC_ACL the_acl  )  [static]

sharesec.c370 行で定義されています。

参照先 ace_compare()security_acl_info::acessecurity_acl_info::num_acessec_ace_equal().

00371 {
00372         uint32 i;
00373         if (!the_acl) return;
00374 
00375         qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare);
00376 
00377         for (i=1;i<the_acl->num_aces;) {
00378                 if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
00379                         int j;
00380                         for (j=i; j<the_acl->num_aces-1; j++) {
00381                                 the_acl->aces[j] = the_acl->aces[j+1];
00382                         }
00383                         the_acl->num_aces--;
00384                 } else {
00385                         i++;
00386                 }
00387         }
00388 }

static int change_share_sec ( TALLOC_CTX mem_ctx,
const char *  sharename,
char *  the_acl,
enum acl_mode  mode 
) [static]

sharesec.c391 行で定義されています。

参照先 security_acl_info::acessecurity_descriptor_info::daclfprintf()get_share_security()security_acl_info::num_acesparse_acl_string()print_ace()printf()sec_ace_equal()sec_desc_print()sid_equal()sid_string_static()SMB_ACL_DELETESMB_ACL_MODIFYSMB_ACL_SETSMB_ACL_VIEWsecurity_ace_info::trustee.

参照元 main().

00392 {
00393         SEC_DESC *sd;
00394         SEC_DESC *old = NULL;
00395         size_t sd_size = 0;
00396         uint32 i, j;
00397         
00398         if (mode != SMB_ACL_SET) {
00399             if (!(old = get_share_security( mem_ctx, sharename, &sd_size )) ) {
00400                 fprintf(stderr, "Unable to retrieve permissions for share [%s]\n", sharename);
00401                 return -1;
00402             }
00403         }
00404 
00405         if ( (mode != SMB_ACL_VIEW) && !(sd = parse_acl_string(mem_ctx, the_acl, &sd_size )) ) {
00406                 fprintf( stderr, "Failed to parse acl\n");
00407                 return -1;
00408         }
00409         
00410         switch (mode) {
00411         case SMB_ACL_VIEW:
00412                 sec_desc_print( stdout, old);
00413                 return 0;
00414         case SMB_ACL_DELETE:
00415             for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
00416                 BOOL found = False;
00417 
00418                 for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
00419                     if (sec_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) {
00420                         uint32 k;
00421                         for (k=j; k<old->dacl->num_aces-1;k++) {
00422                             old->dacl->aces[k] = old->dacl->aces[k+1];
00423                         }
00424                         old->dacl->num_aces--;
00425                         found = True;
00426                         break;
00427                     }
00428                 }
00429 
00430                 if (!found) {
00431                 printf("ACL for ACE:");
00432                 print_ace(stdout, &sd->dacl->aces[i]);
00433                 printf(" not found\n");
00434                 }
00435             }
00436 
00437             break;
00438         case SMB_ACL_MODIFY:
00439             for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
00440                 BOOL found = False;
00441 
00442                 for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
00443                     if (sid_equal(&sd->dacl->aces[i].trustee,
00444                         &old->dacl->aces[j].trustee)) {
00445                         old->dacl->aces[j] = sd->dacl->aces[i];
00446                         found = True;
00447                     }
00448                 }
00449 
00450                 if (!found) {
00451                     printf("ACL for SID %s not found\n", sid_string_static(&sd->dacl->aces[i].trustee));
00452                 }
00453             }
00454 
00455             if (sd->owner_sid) {
00456                 old->owner_sid = sd->owner_sid;
00457             }
00458 
00459             if (sd->group_sid) {
00460                 old->group_sid = sd->group_sid;
00461             }
00462             break;
00463         case SMB_ACL_ADD:
00464             for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
00465                 add_ace(mem_ctx, &old->dacl, &sd->dacl->aces[i]);
00466             }
00467             break;
00468         case SMB_ACL_SET:
00469             old = sd;
00470             break;
00471         }
00472 
00473         /* Denied ACE entries must come before allowed ones */
00474         sort_acl(old->dacl);
00475 
00476         if ( !set_share_security( sharename, old ) ) {
00477             fprintf( stderr, "Failed to store acl for share [%s]\n", sharename );
00478             return 2;
00479         }
00480         return 0;
00481 }

int main ( int  argc,
const char *  argv[] 
)

sharesec.c487 行で定義されています。

参照先 change_share_sec()ctxdbfDEBUGLEVEL_CLASSdyn_CONFIGFILEfprintf()get_global_sam_sid()load_case_tables()modepoptGetArg()poptGetContext()poptGetNextOpt()poptGetOptArg()poptPeekArg()poptPrintUsage()poptSetOtherOptionHelp()printf()setup_logging()sid_string_static()SMB_ACL_ADDSMB_ACL_DELETESMB_ACL_MODIFYSMB_ACL_SETSMB_ACL_VIEWsmb_xstrdup()talloc_init()x_setbuf()x_stderr.

00488 {
00489         int opt;
00490         int retval = 0;
00491         enum acl_mode mode = SMB_ACL_SET;
00492         static char *the_acl = NULL;
00493         fstring sharename;
00494         BOOL force_acl = False;
00495         int snum;
00496         poptContext pc;
00497         BOOL initialize_sid = False;
00498         struct poptOption long_options[] = {
00499                 POPT_AUTOHELP
00500                 { "remove", 'r', POPT_ARG_STRING, &the_acl, 'r', "Delete an ACE", "ACL" },
00501                 { "modify", 'm', POPT_ARG_STRING, &the_acl, 'm', "Modify an acl", "ACL" },
00502                 { "add", 'a', POPT_ARG_STRING, &the_acl, 'a', "Add an ACE", "ACL" },
00503                 { "replace", 'R', POPT_ARG_STRING, &the_acl, 'R', "Set share mission ACL", "ACLS" },
00504                 { "view", 'v', POPT_ARG_NONE, NULL, 'v', "View current share permissions" },
00505                 { "machine-sid", 'M', POPT_ARG_NONE, NULL, 'M', "Initialize the machine SID" },
00506                 { "force", 'F', POPT_ARG_NONE, NULL, 'F', "Force storing the ACL", "ACLS" },
00507                 POPT_COMMON_SAMBA
00508                 { NULL }
00509         };
00510 
00511         if ( !(ctx = talloc_init("main")) ) {
00512                 fprintf( stderr, "Failed to initialize talloc context!\n");
00513                 return -1;
00514         }
00515 
00516         /* set default debug level to 1 regardless of what smb.conf sets */
00517         setup_logging( "sharesec", True );
00518         DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
00519         dbf = x_stderr;
00520         x_setbuf( x_stderr, NULL );
00521 
00522         pc = poptGetContext("sharesec", argc, argv, long_options, 0);
00523         
00524         poptSetOtherOptionHelp(pc, "sharename\n");
00525 
00526         while ((opt = poptGetNextOpt(pc)) != -1) {
00527                 switch (opt) {
00528                 case 'r':
00529                         the_acl = smb_xstrdup(poptGetOptArg(pc));
00530                         mode = SMB_ACL_DELETE;
00531                         break;
00532 
00533                 case 'm':
00534                         the_acl = smb_xstrdup(poptGetOptArg(pc));
00535                         mode = SMB_ACL_MODIFY;
00536                         break;
00537 
00538                 case 'a':
00539                         the_acl = smb_xstrdup(poptGetOptArg(pc));
00540                         mode = SMB_ACL_ADD;
00541                         break;
00542                 case 'R':
00543                         the_acl = smb_xstrdup(poptGetOptArg(pc));
00544                         mode = SMB_ACL_SET;
00545                         break;
00546 
00547                 case 'v':
00548                         mode = SMB_ACL_VIEW;
00549                         break;
00550 
00551                 case 'F':
00552                         force_acl = True;
00553                         break;
00554                         
00555                 case 'M':
00556                         initialize_sid = True;
00557                         break;
00558                 }
00559         }
00560         
00561         setlinebuf(stdout);
00562 
00563         load_case_tables();
00564 
00565         lp_load( dyn_CONFIGFILE, False, False, False, True );
00566 
00567         /* check for initializing secrets.tdb first */
00568         
00569         if ( initialize_sid ) {
00570                 DOM_SID *sid = get_global_sam_sid();
00571                 
00572                 if ( !sid ) {
00573                         fprintf( stderr, "Failed to retrieve Machine SID!\n");
00574                         return 3;
00575                 }
00576                 
00577                 printf ("%s\n", sid_string_static( sid ) );
00578                 return 0;
00579         }
00580 
00581         if ( mode == SMB_ACL_VIEW && force_acl ) {
00582                 fprintf( stderr, "Invalid combination of -F and -v\n");
00583                 return -1;
00584         }
00585 
00586         /* get the sharename */
00587 
00588         if(!poptPeekArg(pc)) { 
00589                 poptPrintUsage(pc, stderr, 0);  
00590                 return -1;
00591         }
00592         
00593         fstrcpy(sharename, poptGetArg(pc));
00594         
00595         snum = lp_servicenumber( sharename );
00596         
00597         if ( snum == -1 && !force_acl ) {
00598                 fprintf( stderr, "Invalid sharename: %s\n", sharename);
00599                 return -1;
00600         }
00601                 
00602         retval = change_share_sec(ctx, sharename, the_acl, mode);
00603         
00604         talloc_destroy(ctx);
00605 
00606         return retval;
00607 }


変数

TALLOC_CTX* ctx [static]

sharesec.c28 行で定義されています。

struct perm_value special_values[] [static]

初期値:

 {
        { "R", SEC_RIGHTS_FILE_READ },
        { "W", SEC_RIGHTS_FILE_WRITE },
        { "X", SEC_RIGHTS_FILE_EXECUTE },
        { "D", SEC_STD_DELETE },
        { "P", SEC_STD_WRITE_DAC },
        { "O", SEC_STD_WRITE_OWNER },
        { NULL, 0 },
}

sharesec.c39 行で定義されています。

参照元 parse_ace().

struct perm_value standard_values[] [static]

初期値:

 {
        { "READ",   SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
        { "CHANGE", SEC_RIGHTS_DIR_CHANGE },
        { "FULL",   SEC_RIGHTS_DIR_ALL },
        { NULL, 0 },
}

sharesec.c51 行で定義されています。

参照元 parse_ace()print_ace().


Sambaに対してSat Aug 29 21:23:37 2009に生成されました。  doxygen 1.4.7