home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / samba-1.9.18p7.tar.gz / samba-1.9.18p7.tar / samba-1.9.18p7 / source / username.c < prev    next >
C/C++ Source or Header  |  1998-05-04  |  8KB  |  337 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    Username handling
  5.    Copyright (C) Andrew Tridgell 1992-1998
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include "includes.h"
  23. extern int DEBUGLEVEL;
  24.  
  25. /* internal functions - modified versions of the ones in password.c */
  26. static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (char *), int N);
  27. static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (char *), int N);
  28.  
  29. /****************************************************************************
  30. get a users home directory. tries as-is then lower case
  31. ****************************************************************************/
  32. char *get_home_dir(char *user)
  33. {
  34.   static struct passwd *pass;
  35.  
  36.   pass = Get_Pwnam(user,False);
  37.  
  38.   if (!pass) return(NULL);
  39.   return(pass->pw_dir);      
  40. }
  41.  
  42.  
  43. /*******************************************************************
  44. map a username from a dos name to a unix name by looking in the username
  45. map
  46. ********************************************************************/
  47. void map_username(char *user)
  48. {
  49.   static int depth=0;
  50.   static BOOL initialised=False;
  51.   static fstring last_from,last_to;
  52.   FILE *f;
  53.   char *s;
  54.   char *mapfile = lp_username_map();
  55.   if (!*mapfile || depth) return;
  56.  
  57.   if (!*user) return;
  58.  
  59.   if (!initialised) {
  60.     *last_from = *last_to = 0;
  61.     initialised = True;
  62.   }
  63.  
  64.   if (strequal(user,last_to)) return;
  65.  
  66.   if (strequal(user,last_from)) {
  67.     DEBUG(3,("Mapped user %s to %s\n",user,last_to));
  68.     fstrcpy(user,last_to);
  69.     return;
  70.   }
  71.   
  72.   f = fopen(mapfile,"r");
  73.   if (!f) {
  74.     DEBUG(0,("can't open username map %s\n",mapfile));
  75.     return;
  76.   }
  77.  
  78.   DEBUG(4,("Scanning username map %s\n",mapfile));
  79.  
  80.   depth++;
  81.  
  82.   for (; (s=fgets_slash(NULL,80,f)); free(s)) {
  83.     char *unixname = s;
  84.     char *dosname = strchr(unixname,'=');
  85.     BOOL break_if_mapped = False;
  86.  
  87.     if (!dosname) continue;
  88.     *dosname++ = 0;
  89.  
  90.     while (isspace(*unixname)) unixname++;
  91.     if ('!' == *unixname)
  92.     {
  93.       break_if_mapped = True;
  94.       unixname++;
  95.       while (*unixname && isspace(*unixname)) unixname++;
  96.     }
  97.     
  98.     if (!*unixname || strchr("#;",*unixname)) continue;
  99.  
  100.     {
  101.       int l = strlen(unixname);
  102.       while (l && isspace(unixname[l-1])) {
  103.     unixname[l-1] = 0;
  104.     l--;
  105.       }
  106.     }
  107.  
  108.     if (strchr(dosname,'*') || user_in_list(user,dosname)) {
  109.       DEBUG(3,("Mapped user %s to %s\n",user,unixname));
  110.       StrnCpy(last_from,user,sizeof(last_from)-1);
  111.       sscanf(unixname,"%s",user);
  112.       StrnCpy(last_to,user,sizeof(last_to)-1);
  113.       if(break_if_mapped) { 
  114.         free(s);
  115.         break;
  116.       }
  117.     }
  118.   }
  119.  
  120.   fclose(f);
  121.  
  122.   depth--;
  123. }
  124.  
  125. /****************************************************************************
  126. internals of Get_Pwnam wrapper
  127. ****************************************************************************/
  128. static struct passwd *_Get_Pwnam(char *s)
  129. {
  130.   struct passwd *ret;
  131.  
  132.   ret = getpwnam(s);
  133.   if (ret)
  134.     {
  135. #ifdef GETPWANAM
  136.       struct passwd_adjunct *pwret;
  137.       pwret = getpwanam(s);
  138.       if (pwret)
  139.     {
  140.       free(ret->pw_passwd);
  141.       ret->pw_passwd = pwret->pwa_passwd;
  142.     }
  143. #endif
  144.  
  145.     }
  146.  
  147.   return(ret);
  148. }
  149.  
  150.  
  151. /****************************************************************************
  152. a wrapper for getpwnam() that tries with all lower and all upper case 
  153. if the initial name fails. Also tried with first letter capitalised
  154. Note that this changes user!
  155. ****************************************************************************/
  156. struct passwd *Get_Pwnam(char *user,BOOL allow_change)
  157. {
  158.   fstring user2;
  159.   int last_char;
  160.   int usernamelevel = lp_usernamelevel();
  161.  
  162.   struct passwd *ret;  
  163.  
  164.   if (!user || !(*user))
  165.     return(NULL);
  166.  
  167.   StrnCpy(user2,user,sizeof(user2)-1);
  168.  
  169.   if (!allow_change) {
  170.     user = &user2[0];
  171.   }
  172.  
  173.   map_username(user);
  174.  
  175.   ret = _Get_Pwnam(user);
  176.   if (ret) return(ret);
  177.  
  178.   strlower(user);
  179.   ret = _Get_Pwnam(user);
  180.   if (ret)  return(ret);
  181.  
  182.   strupper(user);
  183.   ret = _Get_Pwnam(user);
  184.   if (ret) return(ret);
  185.  
  186.   /* try with first letter capitalised */
  187.   if (strlen(user) > 1)
  188.     strlower(user+1);  
  189.   ret = _Get_Pwnam(user);
  190.   if (ret) return(ret);
  191.  
  192.   /* try with last letter capitalised */
  193.   strlower(user);
  194.   last_char = strlen(user)-1;
  195.   user[last_char] = toupper(user[last_char]);
  196.   DEBUG(3, ("Trying username %s\n", user));
  197.   ret = _Get_Pwnam(user);
  198.   if (ret) return(ret);
  199.  
  200.   /* try all combinations up to usernamelevel */
  201.   strlower(user);
  202.   ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
  203.   if (ret) return(ret);
  204.  
  205.   if (allow_change)
  206.     fstrcpy(user,user2);
  207.  
  208.   return(NULL);
  209. }
  210.  
  211.  
  212. /****************************************************************************
  213. check if a user is in a user list
  214. ****************************************************************************/
  215. BOOL user_in_list(char *user,char *list)
  216. {
  217.   pstring tok;
  218.   char *p=list;
  219.  
  220.   while (next_token(&p,tok,LIST_SEP))
  221.     {
  222.       if (strequal(user,tok))
  223.     return(True);
  224.  
  225. #ifdef NETGROUP
  226.       if (*tok == '@')
  227.     {
  228.       static char *mydomain = NULL;
  229.       if (mydomain == 0)
  230.         yp_get_default_domain(&mydomain);
  231.  
  232.       if(mydomain == 0)
  233.         {
  234.               DEBUG(5,("Unable to get default yp domain\n"));
  235.             }
  236.           else
  237.         {
  238.       
  239.             DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
  240.            user, mydomain, &tok[1]));
  241.           DEBUG(5,("innetgr is %s\n",
  242.            innetgr(&tok[1], (char *) 0, user, mydomain)
  243.            ? "TRUE" : "FALSE"));
  244.       
  245.             if (innetgr(&tok[1], (char *)0, user, mydomain))
  246.             return (True);
  247.             }
  248.     }
  249. #endif
  250.  
  251.  
  252. #if HAVE_GETGRNAM 
  253.       if (*tok == '@')
  254.     {
  255.           struct group *gptr;
  256.           char **member;  
  257.       struct passwd *pass = Get_Pwnam(user,False);
  258.  
  259.       if (pass) { 
  260.         gptr = getgrgid(pass->pw_gid);
  261.         if (gptr && strequal(gptr->gr_name,&tok[1]))
  262.           return(True); 
  263.       } 
  264.  
  265.       gptr = (struct group *)getgrnam(&tok[1]);
  266.  
  267.       if (gptr)
  268.         {
  269.           member = gptr->gr_mem;
  270.           while (member && *member)
  271.         {
  272.           if (strequal(*member,user))
  273.             return(True);
  274.           member++;
  275.         }
  276.         }
  277.     }          
  278. #endif
  279.     }
  280.   return(False);
  281. }
  282.  
  283. /* The functions below have been taken from password.c and slightly modified */
  284. /****************************************************************************
  285. apply a function to upper/lower case combinations
  286. of a string and return true if one of them returns true.
  287. try all combinations with N uppercase letters.
  288. offset is the first char to try and change (start with 0)
  289. it assumes the string starts lowercased
  290. ****************************************************************************/
  291. static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(char *),int N)
  292. {
  293.   int len = strlen(s);
  294.   int i;
  295.   struct passwd *ret;
  296.  
  297. #ifdef PASSWORD_LENGTH
  298.   len = MIN(len,PASSWORD_LENGTH);
  299. #endif
  300.  
  301.   if (N <= 0 || offset >= len)
  302.     return(fn(s));
  303.  
  304.  
  305.   for (i=offset;i<(len-(N-1));i++)
  306.  
  307.     {
  308.       char c = s[i];
  309.       if (!islower(c)) continue;
  310.       s[i] = toupper(c);
  311.       ret = uname_string_combinations2(s,i+1,fn,N-1);
  312.       if(ret) return(ret);
  313.       s[i] = c;
  314.     }
  315.   return(NULL);
  316. }
  317.  
  318. /****************************************************************************
  319. apply a function to upper/lower case combinations
  320. of a string and return true if one of them returns true.
  321. try all combinations with up to N uppercase letters.
  322. offset is the first char to try and change (start with 0)
  323. it assumes the string starts lowercased
  324. ****************************************************************************/
  325. static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(char *),int N)
  326. {
  327.   int n;
  328.   struct passwd *ret;
  329.  
  330.   for (n=1;n<=N;n++)
  331.   {
  332.     ret = uname_string_combinations2(s,0,fn,n);
  333.     if(ret) return(ret);
  334.   }
  335.   return(NULL);
  336. }
  337.