summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2000-12-07 06:05:57 +0000
committerTim Potter <tpot@samba.org>2000-12-07 06:05:57 +0000
commit34402b75b5628684ee527c0fd2e263412ee2a008 (patch)
treedb7e3cc6017ab01ae5a540f51b36bfad6763fbdd
parent423227d7ca87a6a4b9412e9ecbc3d6dd073818b1 (diff)
downloadsamba-34402b75b5628684ee527c0fd2e263412ee2a008.tar.gz
samba-34402b75b5628684ee527c0fd2e263412ee2a008.tar.bz2
samba-34402b75b5628684ee527c0fd2e263412ee2a008.zip
Added undocumented -t command for testing parsing of acl entries.
Print out hex value for ace mask if we can't decode it. We can now parse FULL,CHANGE,READ as well as combos of RWXDPO as ace mask values. Clarified usage message. Bomb out if excess args are given. (This used to be commit ed5bda119a984e124d24f168db15e15da62ceaa5)
-rw-r--r--source3/utils/smbcacls.c129
1 files changed, 118 insertions, 11 deletions
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 570a0b3155..4d6622b0ef 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -25,6 +25,7 @@
static fstring password;
static fstring username;
static int got_pass;
+static int test_args;
/* numeric is set when the user wants numeric SIDs and ACEs rather
than going via LSA calls to resolve them */
@@ -88,6 +89,8 @@ static void print_ace(FILE *f, SEC_ACE *ace)
{
struct perm_value *v;
fstring sidstr;
+ int do_print = 0;
+ uint32 got_mask;
SidToString(sidstr, &ace->sid);
@@ -122,11 +125,27 @@ static void print_ace(FILE *f, SEC_ACE *ace)
}
}
- /* Special permissions */
+ /* Special permissions. Print out a hex value if we have
+ leftover bits in the mask. */
+ got_mask = ace->info.mask;
+
+ again:
for (v = special_values; v->perm; v++) {
if ((ace->info.mask & v->mask) == v->mask) {
- fprintf(f, "%s", v->perm);
+ if (do_print) {
+ fprintf(f, "%s", v->perm);
+ }
+ got_mask &= ~v->mask;
+ }
+ }
+
+ if (!do_print) {
+ if (got_mask != 0) {
+ fprintf(f, "0x%08x", ace->info.mask);
+ } else {
+ do_print = 1;
+ goto again;
}
}
@@ -138,18 +157,89 @@ static void print_ace(FILE *f, SEC_ACE *ace)
static BOOL parse_ace(SEC_ACE *ace, char *str)
{
char *p;
+ fstring tok;
unsigned atype, aflags, amask;
DOM_SID sid;
SEC_ACCESS mask;
+ struct perm_value *v;
+
ZERO_STRUCTP(ace);
p = strchr(str,':');
if (!p) return False;
- *p = 0;
- if (sscanf(p+1, "%i/%i/%i",
- &atype, &aflags, &amask) != 3 ||
- !StringToSid(&sid, str)) {
+ *p = '\0';
+ p++;
+
+ /* Try to parse numeric form */
+
+ if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
+ StringToSid(&sid, str)) {
+ goto done;
+ }
+
+ /* Try to parse text form */
+
+ if (!string_to_sid(&sid, str)) {
+ return False;
+ }
+
+ if (!next_token(&p, tok, "/", sizeof(fstring))) {
+ return False;
+ }
+
+ if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
+ atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
+ } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
+ atype = SEC_ACE_TYPE_ACCESS_DENIED;
+ } else {
+ return False;
+ }
+
+ /* Only numeric form accepted for flags at present */
+
+ if (!(next_token(NULL, tok, "/", sizeof(fstring)) &&
+ sscanf(tok, "%i", &aflags))) {
+ return False;
+ }
+
+ if (!next_token(NULL, tok, "/", sizeof(fstring))) {
return False;
}
+
+ if (strncmp(tok, "0x", 2) == 0) {
+ if (sscanf(tok, "%i", &amask) != 1) {
+ return False;
+ }
+ goto done;
+ }
+
+ for (v = standard_values; v->perm; v++) {
+ if (strcmp(tok, v->perm) == 0) {
+ amask = v->mask;
+ goto done;
+ }
+ }
+
+ p = tok;
+
+ while(*p) {
+ BOOL found = False;
+
+ for (v = special_values; v->perm; v++) {
+ if (v->perm[0] == *p) {
+ amask |= v->mask;
+ found = True;
+ }
+ }
+
+ if (!found) return False;
+ p++;
+ }
+
+ if (*p) {
+ return False;
+ }
+
+ done:
mask.mask = amask;
init_sec_ace(ace, &sid, atype, mask, aflags);
return True;
@@ -229,6 +319,7 @@ static SEC_DESC *sec_desc_parse(char *str)
NULL, dacl, &sd_size);
free_sec_acl(&dacl);
+
if (grp_sid) free(grp_sid);
if (owner_sid) free(owner_sid);
@@ -280,6 +371,8 @@ static void cacl_dump(struct cli_state *cli, char *filename)
int fnum;
SEC_DESC *sd;
+ if (test_args) return;
+
fnum = cli_nt_create(cli, filename, 0x20000);
if (fnum == -1) {
printf("Failed to open %s: %s\n", filename, cli_errstr(cli));
@@ -317,6 +410,8 @@ static void cacl_set(struct cli_state *cli, char *filename,
return;
}
+ if (test_args) return;
+
/* the desired access below is the only one I could find that works with
NT4, W2KP and Samba */
fnum = cli_nt_create(cli, filename, MAXIMUM_ALLOWED_ACCESS | 0x60000);
@@ -492,16 +587,17 @@ struct cli_state *connect_one(char *share)
static void usage(void)
{
printf(
-"Usage: smbcacls //server1/share1 filename [options]\n\n\
+"Usage: smbcacls //server1/share1 filename -U username [options]\n\
\n\
\t-D <acls> delete an acl\n\
\t-M <acls> modify an acl\n\
\t-A <acls> add an acl\n\
\t-S <acls> set acls\n\
-\t-U username set the network username\n\
\t-n don't resolve sids or masks to names\n\
\t-h print help\n\
\n\
+The username can be of the form username%%password or\n\
+workgroup\\username%%password.\n\n\
An acl is of the form ACL:<SID>:type/flags/mask\n\
You can string acls together with spaces, commas or newlines\n\
");
@@ -556,7 +652,7 @@ You can string acls together with spaces, commas or newlines\n\
seed = time(NULL);
- while ((opt = getopt(argc, argv, "U:nhS:D:A:M:")) != EOF) {
+ while ((opt = getopt(argc, argv, "U:nhS:D:A:M:t")) != EOF) {
switch (opt) {
case 'U':
pstrcpy(username,optarg);
@@ -592,6 +688,10 @@ You can string acls together with spaces, commas or newlines\n\
numeric = 1;
break;
+ case 't':
+ test_args = 1;
+ break;
+
case 'h':
usage();
exit(1);
@@ -604,9 +704,16 @@ You can string acls together with spaces, commas or newlines\n\
argc -= optind;
argv += optind;
+
+ if (argc > 0) {
+ usage();
+ exit(1);
+ }
- cli = connect_one(share);
- if (!cli) exit(1);
+ if (!test_args) {
+ cli = connect_one(share);
+ if (!cli) exit(1);
+ }
if (acl) {
cacl_set(cli, filename, acl, mode);