root/source3/lib/username.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_user_home_dir
  2. Get_Pwnam_internals
  3. Get_Pwnam_alloc
  4. uname_string_combinations2
  5. uname_string_combinations

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    Username handling
   4    Copyright (C) Andrew Tridgell 1992-1998
   5    Copyright (C) Jeremy Allison 1997-2001.
   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 3 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, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 
  23 /* internal functions */
  24 static struct passwd *uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
  25                                                 struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
  26                                                 int N);
  27 static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, int offset,
  28                                                  struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
  29                                                  int N);
  30 
  31 /****************************************************************************
  32  Get a users home directory.
  33 ****************************************************************************/
  34 
  35 char *get_user_home_dir(TALLOC_CTX *mem_ctx, const char *user)
     /* [<][>][^][v][top][bottom][index][help] */
  36 {
  37         struct passwd *pass;
  38         char *result;
  39 
  40         /* Ensure the user exists. */
  41 
  42         pass = Get_Pwnam_alloc(mem_ctx, user);
  43 
  44         if (!pass)
  45                 return(NULL);
  46 
  47         /* Return home directory from struct passwd. */
  48 
  49         result = talloc_move(mem_ctx, &pass->pw_dir);
  50 
  51         TALLOC_FREE(pass);
  52         return result;
  53 }
  54 
  55 /****************************************************************************
  56  * A wrapper for sys_getpwnam().  The following variations are tried:
  57  *   - as transmitted
  58  *   - in all lower case if this differs from transmitted
  59  *   - in all upper case if this differs from transmitted
  60  *   - using lp_usernamelevel() for permutations.
  61 ****************************************************************************/
  62 
  63 static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  64                                           const char *user, char *user2)
  65 {
  66         struct passwd *ret = NULL;
  67 
  68         if (!user2 || !(*user2))
  69                 return(NULL);
  70 
  71         if (!user || !(*user))
  72                 return(NULL);
  73 
  74         /* Try in all lower case first as this is the most 
  75            common case on UNIX systems */
  76         strlower_m(user2);
  77         DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
  78         ret = getpwnam_alloc(mem_ctx, user2);
  79         if(ret)
  80                 goto done;
  81 
  82         /* Try as given, if username wasn't originally lowercase */
  83         if(strcmp(user, user2) != 0) {
  84                 DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n",
  85                          user));
  86                 ret = getpwnam_alloc(mem_ctx, user);
  87                 if(ret)
  88                         goto done;
  89         }
  90 
  91         /* Try as uppercase, if username wasn't originally uppercase */
  92         strupper_m(user2);
  93         if(strcmp(user, user2) != 0) {
  94                 DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",
  95                          user2));
  96                 ret = getpwnam_alloc(mem_ctx, user2);
  97                 if(ret)
  98                         goto done;
  99         }
 100 
 101         /* Try all combinations up to usernamelevel */
 102         strlower_m(user2);
 103         DEBUG(5,("Checking combinations of %d uppercase letters in %s\n",
 104                  lp_usernamelevel(), user2));
 105         ret = uname_string_combinations(user2, mem_ctx, getpwnam_alloc,
 106                                         lp_usernamelevel());
 107 
 108 done:
 109         DEBUG(5,("Get_Pwnam_internals %s find user [%s]!\n",ret ?
 110                  "did":"didn't", user));
 111 
 112         return ret;
 113 }
 114 
 115 /****************************************************************************
 116  Get_Pwnam wrapper without modification.
 117   NOTE: This with NOT modify 'user'! 
 118   This will return an allocated structure
 119 ****************************************************************************/
 120 
 121 struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
     /* [<][>][^][v][top][bottom][index][help] */
 122 {
 123         fstring user2;
 124         struct passwd *ret;
 125 
 126         if ( *user == '\0' ) {
 127                 DEBUG(10,("Get_Pwnam: empty username!\n"));
 128                 return NULL;
 129         }
 130 
 131         fstrcpy(user2, user);
 132 
 133         DEBUG(5,("Finding user %s\n", user));
 134 
 135         ret = Get_Pwnam_internals(mem_ctx, user, user2);
 136         
 137         return ret;  
 138 }
 139 
 140 /* The functions below have been taken from password.c and slightly modified */
 141 /****************************************************************************
 142  Apply a function to upper/lower case combinations
 143  of a string and return true if one of them returns true.
 144  Try all combinations with N uppercase letters.
 145  offset is the first char to try and change (start with 0)
 146  it assumes the string starts lowercased
 147 ****************************************************************************/
 148 
 149 static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 150                                                  int offset,
 151                                                  struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *),
 152                                                  int N)
 153 {
 154         ssize_t len = (ssize_t)strlen(s);
 155         int i;
 156         struct passwd *ret;
 157 
 158         if (N <= 0 || offset >= len)
 159                 return(fn(mem_ctx, s));
 160 
 161         for (i=offset;i<(len-(N-1));i++) {
 162                 char c = s[i];
 163                 if (!islower_ascii((int)c))
 164                         continue;
 165                 s[i] = toupper_ascii(c);
 166                 ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
 167                 if(ret)
 168                         return(ret);
 169                 s[i] = c;
 170         }
 171         return(NULL);
 172 }
 173 
 174 /****************************************************************************
 175  Apply a function to upper/lower case combinations
 176  of a string and return true if one of them returns true.
 177  Try all combinations with up to N uppercase letters.
 178  offset is the first char to try and change (start with 0)
 179  it assumes the string starts lowercased
 180 ****************************************************************************/
 181 
 182 static struct passwd * uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 183                                                  struct passwd * (*fn)(TALLOC_CTX *mem_ctx, const char *),
 184                                                  int N)
 185 {
 186         int n;
 187         struct passwd *ret;
 188 
 189         for (n=1;n<=N;n++) {
 190                 ret = uname_string_combinations2(s,mem_ctx,0,fn,n);
 191                 if(ret)
 192                         return(ret);
 193         }  
 194         return(NULL);
 195 }
 196 

/* [<][>][^][v][top][bottom][index][help] */