s3:smbd: fix posix acls when setting an ACL without explicit ACE for the owner (bug...
authorStefan Metzmacher <metze@samba.org>
Fri, 8 May 2009 12:33:49 +0000 (14:33 +0200)
committerKarolin Seeger <kseeger@samba.org>
Tue, 2 Jun 2009 10:41:55 +0000 (12:41 +0200)
The problem of bug #2346 remains for users exported by
winbindd, because create_token_from_username() just fakes
the token when the user is not in the local sam domain. This causes
user_in_group_sid() to give totally wrong results.
In uid_entry_in_group() we need to check if we already
have the full unix token in the current_user struct.
If so we should use the current_user unix token,
instead of doing a very complex user_in_group_sid()
which doesn't give reliable results anyway.

metze
(cherry picked from commit b79eff843be392f3065e912edca1434081d93c44)
(cherry picked from commit cb5c72c0a05a78ff1b86eb02cf5ecd3d7d69623d)
(cherry picked from commit ef0d72513b5404f176186632aab67d7b87039ba2)

source/smbd/posix_acls.c

index b538825b9517528f7f42b3ba3abe98c7062daf67..562776e798d6c161f758a82fe6272751542c1c7e 100644 (file)
@@ -1119,16 +1119,31 @@ static bool uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
        if (sid_equal(&group_ace->trustee, &global_sid_World))
                return True;
 
-       /* Assume that the current user is in the current group (force group) */
+       /*
+        * if it's the current user, we already have the unix token
+        * and don't need to do the complex user_in_group_sid() call
+        */
+       if (uid_ace->unix_ug.uid == current_user.ut.uid) {
+               size_t i;
 
-       if (uid_ace->unix_ug.uid == current_user.ut.uid && group_ace->unix_ug.gid == current_user.ut.gid)
-               return True;
+               if (group_ace->unix_ug.gid == current_user.ut.gid) {
+                       return True;
+               }
+
+               for (i=0; i < current_user.ut.ngroups; i++) {
+                       if (group_ace->unix_ug.gid == current_user.ut.groups[i]) {
+                               return True;
+                       }
+               }
+       }
 
        /* u_name talloc'ed off tos. */
        u_name = uidtoname(uid_ace->unix_ug.uid);
        if (!u_name) {
                return False;
        }
+
+       /* notice that this is not reliable for users exported by winbindd! */
        return user_in_group_sid(u_name, &group_ace->trustee);
 }