r23782: I tested this against NT4 PDC, W2K Server, W2K3 Dc, and a Win XP std alone
[ab/samba.git/.git] / source3 / utils / smbcacls.c
index cff3bc5dde44cf3fe2b5c4a989969b9854800601..3bcf9885bcfaa239d8e407499fe5fd46391ffa92 100644 (file)
@@ -9,7 +9,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -108,7 +108,7 @@ static void SidToString(fstring str, DOM_SID *sid)
 {
        char **domains = NULL;
        char **names = NULL;
-       uint32 *types = NULL;
+       enum lsa_SidType *types = NULL;
 
        sid_to_string(str, sid);
 
@@ -135,7 +135,7 @@ static void SidToString(fstring str, DOM_SID *sid)
 /* convert a string to a SID, either numeric or username/group */
 static BOOL StringToSid(DOM_SID *sid, const char *str)
 {
-       uint32 *types = NULL;
+       enum lsa_SidType *types = NULL;
        DOM_SID *sids = NULL;
        BOOL result = True;
 
@@ -145,7 +145,7 @@ static BOOL StringToSid(DOM_SID *sid, const char *str)
 
        if (!cacls_open_policy_hnd() ||
            !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, global_hack_cli->mem_ctx, 
-                                                 &pol, 1, &str, NULL, &sids, 
+                                                 &pol, 1, &str, NULL, 1, &sids, 
                                                  &types))) {
                result = False;
                goto done;
@@ -172,7 +172,7 @@ static void print_ace(FILE *f, SEC_ACE *ace)
 
        if (numeric) {
                fprintf(f, "%d/%d/0x%08x", 
-                       ace->type, ace->flags, ace->info.mask);
+                       ace->type, ace->flags, ace->access_mask);
                return;
        }
 
@@ -193,7 +193,7 @@ static void print_ace(FILE *f, SEC_ACE *ace)
        /* Standard permissions */
 
        for (v = standard_values; v->perm; v++) {
-               if (ace->info.mask == v->mask) {
+               if (ace->access_mask == v->mask) {
                        fprintf(f, "%s", v->perm);
                        return;
                }
@@ -202,11 +202,11 @@ static void print_ace(FILE *f, SEC_ACE *ace)
        /* Special permissions.  Print out a hex value if we have
           leftover bits in the mask. */
 
-       got_mask = ace->info.mask;
+       got_mask = ace->access_mask;
 
  again:
        for (v = special_values; v->perm; v++) {
-               if ((ace->info.mask & v->mask) == v->mask) {
+               if ((ace->access_mask & v->mask) == v->mask) {
                        if (do_print) {
                                fprintf(f, "%s", v->perm);
                        }
@@ -216,7 +216,7 @@ static void print_ace(FILE *f, SEC_ACE *ace)
 
        if (!do_print) {
                if (got_mask != 0) {
-                       fprintf(f, "0x%08x", ace->info.mask);
+                       fprintf(f, "0x%08x", ace->access_mask);
                } else {
                        do_print = 1;
                        goto again;
@@ -348,7 +348,7 @@ static BOOL parse_ace(SEC_ACE *ace, const char *orig_str)
        }
 
  done:
-       mask.mask = amask;
+       mask = amask;
        init_sec_ace(ace, &sid, atype, mask, aflags);
        SAFE_FREE(str);
        return True;
@@ -360,12 +360,13 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace)
        SEC_ACL *new_ace;
        SEC_ACE *aces;
        if (! *the_acl) {
-               (*the_acl) = make_sec_acl(ctx, 3, 1, ace);
-               return True;
+               return (((*the_acl) = make_sec_acl(ctx, 3, 1, ace)) != NULL);
        }
 
-       aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces);
-       memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
+       if (!(aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces))) {
+               return False;
+       }
+       memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE));
        memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
        new_ace = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
        SAFE_FREE(aces);
@@ -378,7 +379,7 @@ static SEC_DESC *sec_desc_parse(char *str)
 {
        const char *p = str;
        fstring tok;
-       SEC_DESC *ret;
+       SEC_DESC *ret = NULL;
        size_t sd_size;
        DOM_SID *grp_sid=NULL, *owner_sid=NULL;
        SEC_ACL *dacl=NULL;
@@ -392,21 +393,29 @@ static SEC_DESC *sec_desc_parse(char *str)
                }
 
                if (strncmp(tok,"OWNER:", 6) == 0) {
+                       if (owner_sid) {
+                               printf("Only specify owner once\n");
+                               goto done;
+                       }
                        owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
                        if (!owner_sid ||
                            !StringToSid(owner_sid, tok+6)) {
                                printf("Failed to parse owner sid\n");
-                               return NULL;
+                               goto done;
                        }
                        continue;
                }
 
                if (strncmp(tok,"GROUP:", 6) == 0) {
+                       if (grp_sid) {
+                               printf("Only specify group once\n");
+                               goto done;
+                       }
                        grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
                        if (!grp_sid ||
                            !StringToSid(grp_sid, tok+6)) {
                                printf("Failed to parse group sid\n");
-                               return NULL;
+                               goto done;
                        }
                        continue;
                }
@@ -414,22 +423,23 @@ static SEC_DESC *sec_desc_parse(char *str)
                if (strncmp(tok,"ACL:", 4) == 0) {
                        SEC_ACE ace;
                        if (!parse_ace(&ace, tok+4)) {
-                               return NULL;
+                               goto done;
                        }
                        if(!add_ace(&dacl, &ace)) {
                                printf("Failed to add ACL %s\n", tok);
-                               return NULL;
+                               goto done;
                        }
                        continue;
                }
 
                printf("Failed to parse token '%s' in security descriptor,\n", tok);
-               return NULL;
+               goto done;
        }
 
        ret = make_sec_desc(ctx,revision, SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, 
                            NULL, dacl, &sd_size);
 
+  done:
        SAFE_FREE(grp_sid);
        SAFE_FREE(owner_sid);
 
@@ -455,8 +465,8 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
 
        fprintf(f, "OWNER:%s\n", sidstr);
 
-       if (sd->grp_sid) {
-               SidToString(sidstr, sd->grp_sid);
+       if (sd->group_sid) {
+               SidToString(sidstr, sd->group_sid);
        } else {
                fstrcpy(sidstr, "");
        }
@@ -465,7 +475,7 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
 
        /* Print aces */
        for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
-               SEC_ACE *ace = &sd->dacl->ace[i];
+               SEC_ACE *ace = &sd->dacl->aces[i];
                fprintf(f, "ACL:");
                print_ace(f, ace);
                fprintf(f, "\n");
@@ -583,8 +593,8 @@ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
        if (ace1->flags != ace2->flags) 
                return ace1->flags - ace2->flags;
 
-       if (ace1->info.mask != ace2->info.mask) 
-               return ace1->info.mask - ace2->info.mask;
+       if (ace1->access_mask != ace2->access_mask) 
+               return ace1->access_mask - ace2->access_mask;
 
        if (ace1->size != ace2->size) 
                return ace1->size - ace2->size;
@@ -597,13 +607,13 @@ static void sort_acl(SEC_ACL *the_acl)
        uint32 i;
        if (!the_acl) return;
 
-       qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare);
+       qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare);
 
        for (i=1;i<the_acl->num_aces;) {
-               if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) {
+               if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
                        int j;
                        for (j=i; j<the_acl->num_aces-1; j++) {
-                               the_acl->ace[j] = the_acl->ace[j+1];
+                               the_acl->aces[j] = the_acl->aces[j+1];
                        }
                        the_acl->num_aces--;
                } else {
@@ -655,11 +665,11 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        BOOL found = False;
 
                        for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
-                               if (sec_ace_equal(&sd->dacl->ace[i],
-                                                 &old->dacl->ace[j])) {
+                               if (sec_ace_equal(&sd->dacl->aces[i],
+                                                 &old->dacl->aces[j])) {
                                        uint32 k;
                                        for (k=j; k<old->dacl->num_aces-1;k++) {
-                                               old->dacl->ace[k] = old->dacl->ace[k+1];
+                                               old->dacl->aces[k] = old->dacl->aces[k+1];
                                        }
                                        old->dacl->num_aces--;
                                        found = True;
@@ -669,7 +679,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
 
                        if (!found) {
                                printf("ACL for ACE:"); 
-                               print_ace(stdout, &sd->dacl->ace[i]);
+                               print_ace(stdout, &sd->dacl->aces[i]);
                                printf(" not found\n");
                        }
                }
@@ -680,9 +690,9 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        BOOL found = False;
 
                        for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
-                               if (sid_equal(&sd->dacl->ace[i].trustee,
-                                             &old->dacl->ace[j].trustee)) {
-                                       old->dacl->ace[j] = sd->dacl->ace[i];
+                               if (sid_equal(&sd->dacl->aces[i].trustee,
+                                             &old->dacl->aces[j].trustee)) {
+                                       old->dacl->aces[j] = sd->dacl->aces[i];
                                        found = True;
                                }
                        }
@@ -690,7 +700,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        if (!found) {
                                fstring str;
 
-                               SidToString(str, &sd->dacl->ace[i].trustee);
+                               SidToString(str, &sd->dacl->aces[i].trustee);
                                printf("ACL for SID %s not found\n", str);
                        }
                }
@@ -699,15 +709,15 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        old->owner_sid = sd->owner_sid;
                }
 
-               if (sd->grp_sid) { 
-                       old->grp_sid = sd->grp_sid;
+               if (sd->group_sid) { 
+                       old->group_sid = sd->group_sid;
                }
 
                break;
 
        case SMB_ACL_ADD:
                for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
-                       add_ace(&old->dacl, &sd->dacl->ace[i]);
+                       add_ace(&old->dacl, &sd->dacl->aces[i]);
                }
                break;
 
@@ -720,7 +730,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
        sort_acl(old->dacl);
 
        /* Create new security descriptor and set it */
-#if 0
+
        /* We used to just have "WRITE_DAC_ACCESS" without WRITE_OWNER.
           But if we're sending an owner, even if it's the same as the one
           that already exists then W2K3 insists we open with WRITE_OWNER access.
@@ -732,12 +742,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
                           NULL, old->dacl, &sd_size);
 
        fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS);
-#else
-       sd = make_sec_desc(ctx,old->revision, old->type, NULL, NULL,
-                          NULL, old->dacl, &sd_size);
 
-       fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS);
-#endif
        if (fnum == -1) {
                printf("cacl_set failed to open %s: %s\n", filename, cli_errstr(cli));
                return EXIT_FAILED;
@@ -892,11 +897,8 @@ static struct cli_state *connect_one(const char *share)
        fstrcpy(server,path+2);
        share = strchr_m(server,'\\');
        if (!share) {
-               share = strchr_m(server,'/');
-               if (!share) {
-                       printf("Invalid argument: %s\n", share);
-                       return -1;
-               }
+               printf("Invalid argument: %s\n", share);
+               return -1;
        }
 
        *share = 0;