summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/libsmb/clisecdesc.c57
-rw-r--r--source3/utils/smbcacls.c164
2 files changed, 211 insertions, 10 deletions
diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c
index 7667938f02..e6b57f6ad4 100644
--- a/source3/libsmb/clisecdesc.c
+++ b/source3/libsmb/clisecdesc.c
@@ -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;
+}
+
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 52d02fed28..414c8c78fd 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -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);
}