The branch, master has been updated via b05faff... added documentation for the -I flag via 843c6a0... added support for a -I flag via 4fee40e... Consolidate all set SEC_DESC into single procedure set_secdesc from 2cc612c... s3-selftest: Allow overriding the subunit formatter.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit b05faffd00a54520b49722db89ae820284e257db Author: Matthew McGillis <matt...@mcgillis.org> Date: Wed May 5 22:43:28 2010 -0700 added documentation for the -I flag commit 843c6a03c7094a58484fab10e246a8153d976de5 Author: Matthew McGillis <matt...@mcgillis.org> Date: Wed May 5 22:35:02 2010 -0700 added support for a -I flag commit 4fee40e2c0700d563386cfab686c0e6e3cb3e8f2 Author: Matthew McGillis <matt...@mcgillis.org> Date: Wed May 5 22:26:15 2010 -0700 Consolidate all set SEC_DESC into single procedure set_secdesc ----------------------------------------------------------------------- Summary of changes: docs-xml/manpages-3/smbcacls.1.xml | 14 +++ source3/utils/smbcacls.c | 201 +++++++++++++++++++++++++++++++----- 2 files changed, 191 insertions(+), 24 deletions(-) Changeset truncated at 500 lines: diff --git a/docs-xml/manpages-3/smbcacls.1.xml b/docs-xml/manpages-3/smbcacls.1.xml index 3e63b9b..571cb69 100644 --- a/docs-xml/manpages-3/smbcacls.1.xml +++ b/docs-xml/manpages-3/smbcacls.1.xml @@ -27,6 +27,7 @@ <arg choice="opt">-S acls</arg> <arg choice="opt">-C name</arg> <arg choice="opt">-G name</arg> + <arg choice="opt">-I allow|romove|copy</arg> <arg choice="opt">--numeric</arg> <arg choice="opt">-t</arg> <arg choice="opt">-U username</arg> @@ -118,6 +119,19 @@ <varlistentry> + <term>-I|--inherit allow|remove|copy</term> + <listitem><para>Set or unset the windows "Allow inheritable + permissions" check box using the <parameter>-I</parameter> + option. To set the check box pass allow. To unset the check + box pass either remove or copy. Remove will remove all + inherited acls. Copy will copy all the inherited acls. + </para></listitem> + + </varlistentry> + + + + <varlistentry> <term>--numeric</term> <listitem><para>This option displays all ACL information in numeric format. The default is to convert SIDs to names and ACE types diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 7db1f17..817b079 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -37,7 +37,7 @@ static int numeric; static int sddl; enum acl_mode {SMB_ACL_SET, SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD }; -enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP}; +enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP, REQUEST_INHERIT}; enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR}; struct perm_value { @@ -660,6 +660,34 @@ static void sec_desc_print(struct cli_state *cli, FILE *f, SEC_DESC *sd) } /***************************************************** +get fileinfo for filename +*******************************************************/ +static uint16 get_fileinfo(struct cli_state *cli, const char *filename) +{ + uint16_t fnum = (uint16_t)-1; + uint16 mode; + + /* The desired access below is the only one I could find that works + with NT4, W2KP and Samba */ + + if (!NT_STATUS_IS_OK(cli_ntcreate(cli, filename, 0, CREATE_ACCESS_READ, + 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, 0x0, 0x0, &fnum))) { + printf("Failed to open %s: %s\n", filename, cli_errstr(cli)); + } + + if (!cli_qfileinfo(cli, fnum, &mode, NULL, NULL, NULL, + NULL, NULL, NULL)) { + printf("Failed to file info %s: %s\n", filename, + cli_errstr(cli)); + } + + cli_close(cli, fnum); + + return mode; +} + +/***************************************************** get sec desc for filename *******************************************************/ static SEC_DESC *get_secdesc(struct cli_state *cli, const char *filename) @@ -689,6 +717,36 @@ static SEC_DESC *get_secdesc(struct cli_state *cli, const char *filename) } /***************************************************** +set sec desc for filename +*******************************************************/ +static bool set_secdesc(struct cli_state *cli, const char *filename, + SEC_DESC *sd) +{ + uint16_t fnum = (uint16_t)-1; + bool result=true; + + /* The desired access below is the only one I could find that works + with NT4, W2KP and Samba */ + + if (!NT_STATUS_IS_OK(cli_ntcreate(cli, filename, 0, + WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS, + 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, 0x0, 0x0, &fnum))) { + printf("Failed to open %s: %s\n", filename, cli_errstr(cli)); + return false; + } + + if (!cli_set_secdesc(cli, fnum, sd)) { + printf("ERROR: security description set failed: %s\n", + cli_errstr(cli)); + result=false; + } + + cli_close(cli, fnum); + return result; +} + +/***************************************************** dump the acls for a file *******************************************************/ static int cacl_dump(struct cli_state *cli, const char *filename) @@ -722,7 +780,6 @@ because the NT docs say this can't be done :-). JRA. static int owner_set(struct cli_state *cli, enum chown_mode change_mode, const char *filename, const char *new_username) { - uint16_t fnum; DOM_SID sid; SEC_DESC *sd, *old; size_t sd_size; @@ -741,20 +798,10 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode, (change_mode == REQUEST_CHGRP) ? &sid : NULL, NULL, NULL, &sd_size); - if (!NT_STATUS_IS_OK(cli_ntcreate(cli, filename, 0, WRITE_OWNER_ACCESS, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) { - printf("Failed to open %s: %s\n", filename, cli_errstr(cli)); + if (!set_secdesc(cli, filename, sd)) { return EXIT_FAILED; } - if (!cli_set_secdesc(cli, fnum, sd)) { - printf("ERROR: secdesc set failed: %s\n", cli_errstr(cli)); - cli_close(cli, fnum); - return EXIT_FAILED; - } - - cli_close(cli, fnum); - return EXIT_OK; } @@ -827,7 +874,6 @@ set the ACLs on a file given an ascii description static int cacl_set(struct cli_state *cli, const char *filename, char *the_acl, enum acl_mode mode) { - uint16_t fnum; SEC_DESC *sd, *old; uint32 i, j; size_t sd_size; @@ -933,25 +979,124 @@ static int cacl_set(struct cli_state *cli, const char *filename, old->owner_sid, old->group_sid, NULL, old->dacl, &sd_size); - if (!NT_STATUS_IS_OK(cli_ntcreate(cli, filename, 0, WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) { - printf("cacl_set failed to open %s: %s\n", filename, cli_errstr(cli)); + if (!set_secdesc(cli, filename, sd)) { + result = EXIT_FAILED; + } + + return result; +} + +/***************************************************** +set the inherit on a file +*******************************************************/ +static int inherit(struct cli_state *cli, const char *filename, + const char *type) +{ + SEC_DESC *old,*sd; + uint32 oldattr; + size_t sd_size; + int result = EXIT_OK; + + old = get_secdesc(cli, filename); + + if (!old) { return EXIT_FAILED; } - if (!cli_set_secdesc(cli, fnum, sd)) { - printf("ERROR: secdesc set failed: %s\n", cli_errstr(cli)); - result = EXIT_FAILED; + oldattr = get_fileinfo(cli,filename); + + if (strcmp(type,"allow")==0) { + if ((old->type & SEC_DESC_DACL_PROTECTED) == + SEC_DESC_DACL_PROTECTED) { + int i; + char *parentname,*temp; + SEC_DESC *parent; + temp = talloc_strdup(talloc_tos(), filename); + + old->type=old->type & (~SEC_DESC_DACL_PROTECTED); + + /* look at parent and copy in all its inheritable ACL's. */ + string_replace(temp, '\\', '/'); + if (!parent_dirname(talloc_tos(),temp,&parentname,NULL)) { + return EXIT_FAILED; + } + string_replace(parentname, '/', '\\'); + parent = get_secdesc(cli,parentname); + for (i=0;i<parent->dacl->num_aces;i++) { + SEC_ACE *ace=&parent->dacl->aces[i]; + if ((oldattr & aDIR) == aDIR) { + if ((ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) == + SEC_ACE_FLAG_CONTAINER_INHERIT) { + add_ace(&old->dacl, ace); + } + } else { + if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) == + SEC_ACE_FLAG_OBJECT_INHERIT) { + add_ace(&old->dacl, ace); + } + } + } + } else { + printf("Already set to inheritable permissions.\n"); + return EXIT_FAILED; + } + } else if (strcmp(type,"remove")==0) { + if ((old->type & SEC_DESC_DACL_PROTECTED) != + SEC_DESC_DACL_PROTECTED) { + old->type=old->type | SEC_DESC_DACL_PROTECTED; + + /* remove all inherited ACL's. */ + if (old->dacl) { + int i; + SEC_ACL *temp=old->dacl; + old->dacl=make_sec_acl(talloc_tos(), 3, 0, NULL); + for (i=temp->num_aces-1;i>=0;i--) { + SEC_ACE *ace=&temp->aces[i]; + /* Remove all ace with INHERITED flag set */ + if ((ace->flags & SEC_ACE_FLAG_INHERITED_ACE) != + SEC_ACE_FLAG_INHERITED_ACE) { + add_ace(&old->dacl,ace); + } + } + } + } else { + printf("Already set to no inheritable permissions.\n"); + return EXIT_FAILED; + } + } else if (strcmp(type,"copy")==0) { + if ((old->type & SEC_DESC_DACL_PROTECTED) != + SEC_DESC_DACL_PROTECTED) { + old->type=old->type | SEC_DESC_DACL_PROTECTED; + + /* convert all inherited ACL's to non inherated ACL's. */ + if (old->dacl) { + int i; + for (i=0;i<old->dacl->num_aces;i++) { + SEC_ACE *ace=&old->dacl->aces[i]; + /* Remove INHERITED FLAG from all aces */ + ace->flags=ace->flags&(~SEC_ACE_FLAG_INHERITED_ACE); + } + } + } else { + printf("Already set to no inheritable permissions.\n"); + return EXIT_FAILED; + } } - /* Clean up */ + /* Denied ACE entries must come before allowed ones */ + sort_acl(old->dacl); - cli_close(cli, fnum); + sd = make_sec_desc(talloc_tos(),old->revision, old->type, + old->owner_sid, old->group_sid, + NULL, old->dacl, &sd_size); + + if (!set_secdesc(cli, filename, sd)) { + result = EXIT_FAILED; + } return result; } - /***************************************************** Return a connection to a server. *******************************************************/ @@ -1028,6 +1173,7 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info, { "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls", "ACLS" }, { "chown", 'C', POPT_ARG_STRING, NULL, 'C', "Change ownership of a file", "USERNAME" }, { "chgrp", 'G', POPT_ARG_STRING, NULL, 'G', "Change group ownership of a file", "GROUPNAME" }, + { "inherit", 'I', POPT_ARG_STRING, NULL, 'I', "Inherit allow|remove|copy" }, { "numeric", 0, POPT_ARG_NONE, &numeric, 1, "Don't resolve sids or masks to names" }, { "sddl", 0, POPT_ARG_NONE, &sddl, 1, "Output and input acls in sddl format" }, { "test-args", 't', POPT_ARG_NONE, &test_args, 1, "Test arguments"}, @@ -1100,6 +1246,11 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info, owner_username = poptGetOptArg(pc); change_mode = REQUEST_CHGRP; break; + + case 'I': + owner_username = poptGetOptArg(pc); + change_mode = REQUEST_INHERIT; + break; } } @@ -1160,7 +1311,9 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info, /* Perform requested action */ - if (change_mode != REQUEST_NONE) { + if (change_mode == REQUEST_INHERIT) { + result = inherit(cli, filename, owner_username); + } else if (change_mode != REQUEST_NONE) { result = owner_set(cli, change_mode, filename, owner_username); } else if (the_acl) { result = cacl_set(cli, filename, the_acl, mode); -- Samba Shared Repository