[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Mon May 17 02:22:08 MDT 2010


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 <matthew at mcgillis.org>
Date:   Wed May 5 22:43:28 2010 -0700

    added documentation for the -I flag

commit 843c6a03c7094a58484fab10e246a8153d976de5
Author: Matthew McGillis <matthew at mcgillis.org>
Date:   Wed May 5 22:35:02 2010 -0700

    added support for a -I flag

commit 4fee40e2c0700d563386cfab686c0e6e3cb3e8f2
Author: Matthew McGillis <matthew at 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


More information about the samba-cvs mailing list