getting/setting acls now works. The SIDs are still numeric, the next
authorAndrew Tridgell <tridge@samba.org>
Sun, 3 Dec 2000 07:36:15 +0000 (07:36 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 3 Dec 2000 07:36:15 +0000 (07:36 +0000)
step is to support usernames etc
(This used to be commit 6cea1647fcbc6f5a903c691273dcec44fcda1fc4)

source3/libsmb/clisecdesc.c
source3/utils/smbcacls.c

index 7667938f0254b826468e18f9fe88154970b08186..e6b57f6ad4b2ef30af54158bcec5e12ce9f3e3c9 100644 (file)
@@ -39,7 +39,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd)
        SEC_DESC *ret;
 
        SIVAL(param, 0, fd);
-       SSVAL(param, 4, 7);
+       SSVAL(param, 4, 0xf);
 
        if (!cli_send_nt_trans(cli, 
                               NT_TRANSACT_QUERY_SECURITY_DESC, 
@@ -70,6 +70,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd)
 
        if (!sec_io_desc("sd data", &psd, &pd, 1)) {
                DEBUG(1,("Failed to parse secdesc\n"));
+               talloc_destroy(mem_ctx);
                return NULL;
        }
 
@@ -80,3 +81,57 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd)
 
 
 
+
+/****************************************************************************
+  set the security descriptor for a open file
+  ****************************************************************************/
+BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd)
+{
+       char param[8];
+       char *rparam=NULL, *rdata=NULL;
+       int rparam_count=0, rdata_count=0;
+       TALLOC_CTX *mem_ctx;
+       prs_struct pd;
+
+       if ((mem_ctx = talloc_init()) == NULL) {
+               DEBUG(0,("talloc_init failed.\n"));
+               return False;
+       }
+
+       prs_init(&pd, 0, 4, mem_ctx, MARSHALL);
+       prs_give_memory(&pd, NULL, 0, True);
+
+       if (!sec_io_desc("sd data", &sd, &pd, 1)) {
+               DEBUG(1,("Failed to marshall secdesc\n"));
+               return False;
+       }
+
+       SIVAL(param, 0, fd);
+       SSVAL(param, 4, 0xf);
+
+       if (!cli_send_nt_trans(cli, 
+                              NT_TRANSACT_SET_SECURITY_DESC, 
+                              0, 
+                              NULL, 0, 0,
+                              param, 8, 0,
+                              pd.data_p, pd.data_offset, 0)) {
+               DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n"));
+               return False;
+       }
+
+
+       if (!cli_receive_nt_trans(cli, 
+                                 &rparam, &rparam_count,
+                                 &rdata, &rdata_count)) {
+               DEBUG(1,("Failed to recv NT_TRANSACT_SET_SECURITY_DESC\n"));
+               return False;
+       }
+
+       if (rparam) free(rparam);
+       if (rdata) free(rdata);
+
+       talloc_destroy(mem_ctx);
+
+       return True;
+}
+
index 52d02fed286a7f321fc3d553b46cd42a5b873a6c..414c8c78fdce401f2ab5984c07f481786ded243c 100644 (file)
@@ -34,6 +34,8 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
        fstring sidstr;
        int i;
 
+       printf("REVISION:%x TYPE:%x\n", sd->revision, sd->type);
+
        /* Print owner and group sid */
 
        if (sd->owner_sid) {
@@ -42,7 +44,7 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
                fstrcpy(sidstr, "");
        }
 
-       printf("%s\n", sidstr);
+       printf("OWNER:%s\n", sidstr);
 
        if (sd->grp_sid) {
                sid_to_string(sidstr, sd->grp_sid);
@@ -50,26 +52,130 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
                fstrcpy(sidstr, "");
        }
 
-       fprintf(f, "%s\n", sidstr);
+       fprintf(f, "GROUP:%s\n", sidstr);
 
        /* Print aces */
+       for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+               SEC_ACE *ace = &sd->dacl->ace[i];
+               fstring sidstr;
 
-       if (!sd->dacl) {
-               return;
+               sid_to_string(sidstr, &ace->sid);
+
+               fprintf(f, "DACL:%x:%x:%08x:%s\n", ace->type, ace->flags,
+                       ace->info.mask, sidstr);
        }
 
-       for (i = 0; i < sd->dacl->num_aces; i++) {
-               SEC_ACE *ace = &sd->dacl->ace[i];
+       for (i = 0; sd->sacl && i < sd->sacl->num_aces; i++) {
+               SEC_ACE *ace = &sd->sacl->ace[i];
                fstring sidstr;
 
                sid_to_string(sidstr, &ace->sid);
 
-               fprintf(f, "%d %d 0x%08x %s\n", ace->type, ace->flags,
+               fprintf(f, "SACL:%x:%x:%08x:%s\n", ace->type, ace->flags,
                        ace->info.mask, sidstr);
        }
 }
 
 
+/* add an ACE to a list of ACEs in a SEC_ACL */
+static BOOL add_acl(SEC_ACL **acl, SEC_ACE *ace)
+{
+       if (! *acl) {
+               *acl = (SEC_ACL *)calloc(1, sizeof(*acl));
+               if (! *acl) return False;
+               (*acl)->revision = 3;
+       }
+
+       (*acl)->ace = Realloc((*acl)->ace,(1+((*acl)->num_aces))*sizeof(SEC_ACE));
+       if (!(*acl)->ace) return False;
+       memcpy(&((*acl)->ace[(*acl)->num_aces]), ace, sizeof(SEC_ACE));
+       (*acl)->num_aces++;
+       return True;
+}
+
+/* parse a ascii version of a security descriptor */
+static SEC_DESC *sec_desc_parse(char *str)
+{
+       char *p = str;
+       fstring tok;
+       SEC_DESC *sd, *ret;
+       int sd_size;
+
+       sd = (SEC_DESC *)calloc(1, sizeof(SEC_DESC));
+       if (!sd) return NULL;
+
+       while (next_token(&p, tok, " \t,\r\n", sizeof(tok))) {
+
+               if (strncmp(tok,"REVISION:", 9) == 0) {
+                       sd->revision = strtol(tok+9, NULL, 16);
+               }
+
+               if (strncmp(tok,"TYPE:", 5) == 0) {
+                       sd->type = strtol(tok+5, NULL, 16);
+               }
+
+               if (strncmp(tok,"OWNER:", 6) == 0) {
+                       sd->owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
+                       if (!sd->owner_sid ||
+                           !string_to_sid(sd->owner_sid, tok+6)) {
+                               printf("Failed to parse owner sid\n");
+                               return NULL;
+                       }
+               }
+
+               if (strncmp(tok,"GROUP:", 6) == 0) {
+                       sd->grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
+                       if (!sd->grp_sid ||
+                           !string_to_sid(sd->grp_sid, tok+6)) {
+                               printf("Failed to parse group sid\n");
+                               return NULL;
+                       }
+               }
+
+               if (strncmp(tok,"DACL:", 5) == 0) {
+                       fstring s;
+                       unsigned atype, aflags, amask;
+                       SEC_ACE ace;
+                       ZERO_STRUCT(ace);
+                       if (sscanf(tok+5, "%x:%x:%08x:%s", 
+                                  &atype, &aflags, &amask,s) != 4 ||
+                           !string_to_sid(&ace.sid, s)) {
+                               printf("Failed to parse DACL\n");
+                               return NULL;
+                       }
+                       ace.type = atype;
+                       ace.flags = aflags;
+                       ace.info.mask = amask;
+                       add_acl(&sd->dacl, &ace);
+               }
+
+               if (strncmp(tok,"SACL:", 5) == 0) {
+                       fstring s;
+                       unsigned atype, aflags, amask;
+                       SEC_ACE ace;
+                       ZERO_STRUCT(ace);
+                       if (sscanf(tok+5, "%x:%x:%08x:%s", 
+                                  &atype, &aflags, &amask,s) != 4 ||
+                           !string_to_sid(&ace.sid, s)) {
+                               printf("Failed to parse SACL\n");
+                               return NULL;
+                       }
+                       ace.type = atype;
+                       ace.flags = aflags;
+                       ace.info.mask = amask;
+                       add_acl(&sd->sacl, &ace);
+               }
+       }
+
+       ret = make_sec_desc(sd->revision, sd->type, sd->owner_sid, sd->grp_sid, 
+                           sd->sacl, sd->dacl, &sd_size);
+
+       free_sec_desc(&sd);
+
+       return ret;
+}
+
+
 
 
 /***************************************************** 
@@ -100,6 +206,38 @@ static void cacl_dump(struct cli_state *cli, char *filename)
        cli_close(cli, fnum);
 }
 
+/***************************************************** 
+set the ACLs on a file given an ascii description
+*******************************************************/
+static void cacl_set(struct cli_state *cli, char *filename, char *set_acl)
+{
+       int fnum;
+       SEC_DESC *sd;
+
+       sd = sec_desc_parse(set_acl);
+       if (!sd) {
+               printf("Failed to parse security descriptor\n");
+               return;
+       }
+
+       fnum = cli_open(cli, filename, O_RDONLY, 0);
+       if (fnum == -1) {
+               printf("Failed to open %s\n", filename);
+               return;
+       }
+
+       /* sec_desc_print(stdout, sd); */
+
+       if (!cli_set_secdesc(cli, fnum, sd)) {
+               printf("ERROR: secdesc set failed\n");
+               return;
+       }
+
+       free_sec_desc(&sd);
+
+       cli_close(cli, fnum);
+}
+
 
 /***************************************************** 
 return a connection to a server
@@ -215,6 +353,7 @@ static void usage(void)
        int seed;
        static pstring servicesf = CONFIGFILE;
        struct cli_state *cli;
+       char *set_acl = NULL;
 
        setlinebuf(stdout);
 
@@ -247,7 +386,7 @@ static void usage(void)
 
        seed = time(NULL);
 
-       while ((opt = getopt(argc, argv, "U:h")) != EOF) {
+       while ((opt = getopt(argc, argv, "U:hs:")) != EOF) {
                switch (opt) {
                case 'U':
                        pstrcpy(username,optarg);
@@ -258,6 +397,9 @@ static void usage(void)
                                got_pass = 1;
                        }
                        break;
+               case 's':
+                       set_acl = optarg;
+                       break;
                case 'h':
                        usage();
                        exit(1);
@@ -273,7 +415,11 @@ static void usage(void)
        cli = connect_one(share);
        if (!cli) exit(1);
 
-       cacl_dump(cli, filename);
+       if (set_acl) {
+               cacl_set(cli, filename, set_acl);
+       } else {
+               cacl_dump(cli, filename);
+       }
 
        return(0);
 }