[Samba] ACL bug FIXes for get_nt_acl() (resend)

Sergey Zhitomirsky szh at 7ka.mipt.ru
Thu Mar 6 22:31:56 GMT 2003


It seems attached patches were lost,  resending inline :

 Two attached patches for samba 2.2.7a and 3.0-alfa22,
 that I've made today, fix 3 bugs mentioned in my previous e-mail.

 1) For each file  in addition to ALLOW ACE
    proper DENY ACE is created.
 2) "Take ownership" is shown DENIED for all except root  ACEs
 3) Read Permissions  and  read attributes  are always shown as allowed,
     as they are actually allowed.


 --
 Zhitomirsky Sergey.


--- samba-3.0alpha22/source/smbd/posix_acls.c	Mon Feb 24 18:12:33 2003
+++ samba-3.0alpha22-fixed/source/smbd/posix_acls.c	Thu Mar  6 17:09:56 2003
@@ -354,15 +354,19 @@
  not get. Deny entries are implicit on get with ace->perms = 0.
 ****************************************************************************/
 
-static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon_ace *ace)
+static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon_ace *ace,
+					SEC_ACCESS* sa_deny, int *pacl_type_deny)
 {
 	SEC_ACCESS sa;
 	uint32 nt_mask = 0;
-
-	*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+	uint32 nt_mask_deny = 0;
+ 
+ 	*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+	*pacl_type_deny = SEC_ACE_TYPE_ACCESS_DENIED;
 
 	if ((ace->perms & ALL_ACE_PERMS) == ALL_ACE_PERMS) {
-			nt_mask = UNIX_ACCESS_RWX;
+		nt_mask = UNIX_ACCESS_RWX;
+		nt_mask_deny = WRITE_OWNER_ACCESS;
 	} else if ((ace->perms & ALL_ACE_PERMS) == (mode_t)0) {
 		/*
 		 * Windows NT refuses to display ACEs with no permissions in them (but
@@ -377,15 +381,31 @@
 			nt_mask = UNIX_ACCESS_NONE;
 		else
 			nt_mask = 0;
+
+		nt_mask_deny = UNIX_ACCESS_RWX; 
+
 	} else {
 		nt_mask |= ((ace->perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
 		nt_mask |= ((ace->perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
 		nt_mask |= ((ace->perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
+
+		nt_mask_deny = ~nt_mask & UNIX_ACCESS_RWX;
 	}
 
-	DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n",
-			(unsigned int)ace->perms, (unsigned int)nt_mask ));
+	/* READ ACL & Read Attributes  afai see  are always allowed in POSIX */
+	nt_mask_deny &= ~(  READ_CONTROL_ACCESS | FILE_READ_ATTRIBUTES);
+	nt_mask |= READ_CONTROL_ACCESS | FILE_READ_ATTRIBUTES;
 
+	/* workaround for "take ownership" for root's ACE */
+	if (ace->owner_type == UID_ACE && !ace->unix_ug.uid) {
+	        nt_mask_deny &= ~WRITE_OWNER_ACCESS;
+	        nt_mask |= WRITE_OWNER_ACCESS;//UNIX_ACCESS_NONE;
+	}
+
+	DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x & ~%x\n",
+			(unsigned int)ace->perms, (unsigned int)nt_mask, (unsigned int)nt_mask_deny));
+    
+	init_sec_access(sa_deny, nt_mask_deny);
 	init_sec_access(&sa,nt_mask);
 	return sa;
 }
@@ -2208,6 +2228,7 @@
 	{
 		canon_ace *ace;
 		int nt_acl_type;
+		int nt_acl_type_deny;
 		int i;
 
 		if (nt4_compatible_acls()) {
@@ -2292,12 +2313,12 @@
 		num_dir_acls = count_canon_ace_list(dir_ace);
 
 		/* Allocate the ace list. */
-		if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
+		if ((nt_ace_list = (SEC_ACE *)malloc((2 * num_acls + num_profile_acls + 2 * num_dir_acls)*sizeof(SEC_ACE))) == NULL) {
 			DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
 			goto done;
 		}
 
-		memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+		memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * 2 * sizeof(SEC_ACE) );
 										                
 		/*
 		 * Create the NT ACE list from the canonical ace lists.
@@ -2307,8 +2328,10 @@
 
 		for (i = 0; i < num_acls; i++, ace = ace->next) {
 			SEC_ACCESS acc;
-
-			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+			SEC_ACCESS acc_deny;
+			
+			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace , &acc_deny, &nt_acl_type_deny);
+			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type_deny, acc_deny, 0);
 			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
 		}
 
@@ -2324,8 +2347,11 @@
 
 		for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
 			SEC_ACCESS acc;
-
-			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+			SEC_ACCESS acc_deny;
+ 
+			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace , &acc_deny, &nt_acl_type_deny);
+			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type_deny, acc_deny,
+					SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
 			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
 					SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
 		}




--- samba-2.2.7a/source/smbd/posix_acls.c	Tue Dec 10 17:58:17 2002
+++ samba-2.2.7a.fixed/source/smbd/posix_acls.c	Fri Mar  7 01:11:20 2003
@@ -336,26 +336,45 @@
  not get. Deny entries are implicit on get with ace->perms = 0.
 ****************************************************************************/
 
-static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon_ace *ace)
+static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon_ace *ace, 
+					SEC_ACCESS* sa_deny, int *pacl_type_deny)
 {
 	SEC_ACCESS sa;
 	uint32 nt_mask = 0;
-
-	*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+	uint32 nt_mask_deny = 0;
+ 
+ 	*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+	*pacl_type_deny = SEC_ACE_TYPE_ACCESS_DENIED;
 
 	if ((ace->perms & ALL_ACE_PERMS) == ALL_ACE_PERMS) {
-			nt_mask = UNIX_ACCESS_RWX;
+		nt_mask = UNIX_ACCESS_RWX;
+		nt_mask_deny = WRITE_OWNER_ACCESS;
 	} else if ((ace->perms & ALL_ACE_PERMS) == (mode_t)0) {
-		nt_mask = UNIX_ACCESS_NONE;
+		nt_mask = 0; /* not UNIX_ACCESS_NONE; */
+		nt_mask_deny = UNIX_ACCESS_RWX; 
 	} else {
 		nt_mask |= ((ace->perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
 		nt_mask |= ((ace->perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
 		nt_mask |= ((ace->perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
+
+		nt_mask_deny = ~nt_mask & UNIX_ACCESS_RWX;
 	}
 
-	DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n",
-			(unsigned int)ace->perms, (unsigned int)nt_mask ));
+	/* READ ACL & Read Attributes  afai see  are always allowed in POSIX */
+	nt_mask_deny &= ~(  READ_CONTROL_ACCESS | FILE_READ_ATTRIBUTES);
+	nt_mask |= READ_CONTROL_ACCESS | FILE_READ_ATTRIBUTES;
+
+	/* workaround for "take ownership" for root's ACE */
+	if (ace->owner_type == UID_ACE && !ace->unix_ug.uid) {
+	        nt_mask_deny &= ~WRITE_OWNER_ACCESS;
+	        nt_mask |= WRITE_OWNER_ACCESS;//UNIX_ACCESS_NONE;
+	}
 
+	DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x & ~%x\n",
+			(unsigned int)ace->perms, (unsigned int)nt_mask, (unsigned int)nt_mask_deny));
+    
+
+	init_sec_access(sa_deny, nt_mask_deny);
 	init_sec_access(&sa,nt_mask);
 	return sa;
 }
@@ -2013,12 +2032,12 @@
 	}
 
 	/* Allocate the ace list. */
-	if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
+	if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)*2* sizeof(SEC_ACE))) == NULL) {
 		DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
 		goto done;
 	}
 
-	memset(nt_ace_list, '\0', (num_acls + num_profile_acls + num_dir_acls) * sizeof(SEC_ACE) );
+	memset(nt_ace_list, '\0', (num_acls + num_profile_acls + num_dir_acls) * 2*sizeof(SEC_ACE) );
 
 	/*
 	 * Create the NT ACE list from the canonical ace lists.
@@ -2027,14 +2046,17 @@
 	{
 		canon_ace *ace;
 		int nt_acl_type;
+		int nt_acl_type_deny;
 		int i;
 
 		ace = file_ace;
 
 		for (i = 0; i < num_acls; i++, ace = ace->next) {
 			SEC_ACCESS acc;
-
-			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+			SEC_ACCESS acc_deny;
+			
+			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace , &acc_deny, &nt_acl_type_deny);
+			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type_deny, acc_deny, 0);
 			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
 		}
 
@@ -2049,8 +2071,12 @@
 
 		for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
 			SEC_ACCESS acc;
+			SEC_ACCESS acc_deny;
 
-			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+			acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace , &acc_deny, &nt_acl_type_deny);
+
+			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type_deny, acc_deny,
+					SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
 			init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 
 					SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
 		}




More information about the samba mailing list