Change check_path_syntax() to use the new next_mb_char_size() function
[ira/wip.git] / source3 / lib / username.c
index b8f33494ee4ad53c27a3b51be836cd284eb6767b..40327f81687d013ea7b4936bd45e7f9068a03daa 100644 (file)
@@ -219,7 +219,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
 
        /* Try in all lower case first as this is the most 
           common case on UNIX systems */
-       strlower(user2);
+       strlower_m(user2);
        DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
        ret = getpwnam_alloc(user2);
        if(ret)
@@ -234,7 +234,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
        }
 
        /* Try as uppercase, if username wasn't originally uppercase */
-       strupper(user2);
+       strupper_m(user2);
        if(strcmp(user, user2) != 0) {
                DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n", user2));
                ret = getpwnam_alloc(user2);
@@ -243,7 +243,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
        }
 
        /* Try all combinations up to usernamelevel */
-       strlower(user2);
+       strlower_m(user2);
        DEBUG(5,("Checking combinations of %d uppercase letters in %s\n", lp_usernamelevel(), user2));
        ret = uname_string_combinations(user2, getpwnam_alloc, lp_usernamelevel());
 
@@ -293,13 +293,16 @@ struct passwd *Get_Pwnam(const char *user)
 }
 
 /****************************************************************************
- Check if a user is in a netgroup user list.
+ Check if a user is in a netgroup user list. If at first we don't succeed,
+ try lower case.
 ****************************************************************************/
 
 static BOOL user_in_netgroup_list(const char *user, const char *ngname)
 {
 #ifdef HAVE_NETGROUP
        static char *mydomain = NULL;
+       fstring lowercase_user, lowercase_ngname;
+
        if (mydomain == NULL)
                yp_get_default_domain(&mydomain);
 
@@ -315,6 +318,20 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
 
        if (innetgr(ngname, NULL, user, mydomain))
                return (True);
+
+       /*
+        * Ok, innetgr is case sensitive. Try once more with lowercase
+        * just in case. Attempt to fix #703. JRA.
+        */
+
+       fstrcpy(lowercase_user, user);
+       strlower_m(lowercase_user);
+       fstrcpy(lowercase_ngname, ngname);
+       strlower_m(lowercase_ngname);
+       
+       if (innetgr(lowercase_ngname, NULL, lowercase_user, mydomain))
+               return (True);
+
 #endif /* HAVE_NETGROUP */
        return False;
 }
@@ -325,11 +342,12 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
   
 static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL *winbind_answered)
 {
-       int num_groups;
        int i;
-       gid_t *groups = NULL;
        gid_t gid, gid_low, gid_high;
        BOOL ret = False;
+       static gid_t *groups = NULL;
+       static int num_groups = 0;
+       static fstring last_user = "";
  
        *winbind_answered = False;
  
@@ -339,7 +357,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
                goto err;
        }
 
-       if (!lp_winbind_gid(&gid_low, &gid_high)) {
+       if (!lp_idmap_gid(&gid_low, &gid_high)) {
                DEBUG(4, ("winbind gid range not configured, therefore %s cannot be a winbind group\n", gname));
                goto err;
        }
@@ -349,27 +367,44 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
                goto err;
        }
  
-       /*
-        * Get the gid's that this user belongs to.
-        */
-       if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1)
-               return False;
+       /* try to user the last user we looked up */
+       /* otherwise fall back to lookups */
+       
+       if ( !strequal( last_user, user ) || !groups )
+       {
+               /* clear any cached information */
+               
+               SAFE_FREE(groups);
+               fstrcpy( last_user, "" );
+
+               /*
+                * Get the gid's that this user belongs to.
+                */
  
-       if (num_groups == 0) {
-               *winbind_answered = True;
-               return False;
-       }
+               if ((num_groups = winbind_getgroups(user, &groups)) == -1)
+                       return False;
+                       
+               if ( num_groups == -1 )
+                       return False;
  
-       if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) {
-               DEBUG(0,("user_in_winbind_group_list: malloc fail.\n"));
-               goto err;
-       }
+               if ( num_groups == 0 ) {
+                       *winbind_answered = True;
+                       return False;
+               }
+               
+               /* save the last username */
+               
+               fstrcpy( last_user, user );
+               
+       }
+       else 
+               DEBUG(10,("user_in_winbind_group_list: using cached user groups for [%s]\n", user));
  
-       if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) {
-               DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \
-failed with error %s\n", strerror(errno) ));
-               goto err;
+       if ( DEBUGLEVEL >= 10 ) {
+               DEBUG(10,("user_in_winbind_group_list: using groups -- "));
+               for ( i=0; i<num_groups; i++ )
+                       DEBUGADD(10,("%lu ", (unsigned long)groups[i]));
+               DEBUGADD(10,("\n"));    
        }
  
        /*
@@ -571,10 +606,16 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
                                fstrcpy(domain, *list);
                                domain[PTR_DIFF(p, *list)] = 0;
 
-                               /* Check to see if name is a Windows group */
-                               if (winbind_lookup_name(domain, groupname, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
+                               /* Check to see if name is a Windows group;  Win2k native mode DCs
+                                  will return domain local groups; while NT4 or mixed mode 2k DCs
+                                  will not */
+                       
+                               if ( winbind_lookup_name(domain, groupname, &g_sid, &name_type) 
+                                       && ( name_type==SID_NAME_DOM_GRP || 
+                                          (strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) )
+                               {
                                        
-                               /* Check if user name is in the Windows group */
+                                       /* Check if user name is in the Windows group */
                                        ret = user_in_winbind_group_list(user, *list, &winbind_answered);
                                        
                                        if (winbind_answered && ret == True) {