Author: vlendec
Date: 2006-02-10 23:00:35 +0000 (Fri, 10 Feb 2006)
New Revision: 13441

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=13441

Log:
For the well-known reasons user_in_group is broken (winbind can't always
reliably tell). Replace two uses by an appropriate check going via
create_token_from_username. 

Sounds expensive and probably is, but user_in_group is potentially much more
expensive as it lists all group members and checks for membership. Potentially
even much more expensive.

The change in auth_sam is for the "+" in the list of allowed
workstations. This only makes sense on for workstations defined locally
anyway, thus unix_in_group->unix_in_user_group.

Volker

Modified:
   trunk/source/auth/auth_sam.c
   trunk/source/auth/auth_util.c
   trunk/source/lib/username.c
   trunk/source/smbd/posix_acls.c
   trunk/source/smbd/service.c


Changeset:
Modified: trunk/source/auth/auth_sam.c
===================================================================
--- trunk/source/auth/auth_sam.c        2006-02-10 21:16:30 UTC (rev 13440)
+++ trunk/source/auth/auth_sam.c        2006-02-10 23:00:35 UTC (rev 13441)
@@ -192,7 +192,7 @@
                        if (tok[0] == '+') {
                                DEBUG(10,("sam_account_ok: checking for 
workstation %s in group: %s\n", 
                                        machine_name, tok + 1));
-                               if (user_in_group(machine_name, tok + 1)) {
+                               if (user_in_unix_group(machine_name, tok + 1)) {
                                        invalid_ws = False;
                                        break;
                                }

Modified: trunk/source/auth/auth_util.c
===================================================================
--- trunk/source/auth/auth_util.c       2006-02-10 21:16:30 UTC (rev 13440)
+++ trunk/source/auth/auth_util.c       2006-02-10 23:00:35 UTC (rev 13441)
@@ -1021,6 +1021,46 @@
 }
 
 /***************************************************************************
+ Build upon create_token_from_username:
+
+ Expensive helper function to figure out whether a user given its name is
+ member of a particular group.
+
+ (Justification: Before this function existed, the callers of this function
+  called user_in_group() which was potentially even more expensive as
+  it lists all group members which can be *huge* -- vl )
+
+***************************************************************************/
+BOOL username_in_group(const char *username, const DOM_SID *group_sid)
+{
+       NTSTATUS status;
+       uid_t uid;
+       gid_t gid;
+       char *found_username;
+       struct nt_user_token *token;
+       BOOL result;
+
+       TALLOC_CTX *mem_ctx;
+
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               DEBUG(0, ("talloc_new failed\n"));
+               return False;
+       }
+
+       status = create_token_from_username(mem_ctx, username, False,
+                                           &uid, &gid, &found_username,
+                                           &token);
+
+       result = nt_token_check_sid(group_sid, token);
+
+       talloc_free(mem_ctx);
+       return result;
+       
+}
+
+
+/***************************************************************************
  Make (and fill) a user_info struct from a Kerberos PAC logon_info by
  conversion to a SAM_ACCOUNT
 ***************************************************************************/

Modified: trunk/source/lib/username.c
===================================================================
--- trunk/source/lib/username.c 2006-02-10 21:16:30 UTC (rev 13440)
+++ trunk/source/lib/username.c 2006-02-10 23:00:35 UTC (rev 13441)
@@ -529,7 +529,7 @@
  Check if a user is in a group list. Ask winbind first, then use UNIX.
 ****************************************************************************/
 
-BOOL user_in_group(const char *user, const char *gname)
+static BOOL user_in_group(const char *user, const char *gname)
 {
        BOOL winbind_answered = False;
        BOOL ret;

Modified: trunk/source/smbd/posix_acls.c
===================================================================
--- trunk/source/smbd/posix_acls.c      2006-02-10 21:16:30 UTC (rev 13440)
+++ trunk/source/smbd/posix_acls.c      2006-02-10 23:00:35 UTC (rev 13441)
@@ -1015,7 +1015,6 @@
 static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
 {
        fstring u_name;
-       fstring g_name;
 
        /* "Everyone" always matches every uid. */
 
@@ -1028,14 +1027,7 @@
                return True;
 
        fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid));
-       fstrcpy(g_name, gidtoname(group_ace->unix_ug.gid));
-
-       /*
-        * Due to the winbind interfaces we need to do this via names,
-        * not uids/gids.
-        */
-
-       return user_in_group(u_name, g_name);
+       return username_in_group(u_name, &group_ace->trustee);
 }
 
 /****************************************************************************

Modified: trunk/source/smbd/service.c
===================================================================
--- trunk/source/smbd/service.c 2006-02-10 21:16:30 UTC (rev 13440)
+++ trunk/source/smbd/service.c 2006-02-10 23:00:35 UTC (rev 13441)
@@ -473,7 +473,7 @@
         */
 
        if (force_user && user_must_be_member) {
-               if (user_in_group(username, groupname)) {
+               if (username_in_group(username, &group_sid)) {
                        sid_copy(pgroup_sid, &group_sid);
                        *pgid = gid;
                        DEBUG(3,("Forced group %s for member %s\n",

Reply via email to