2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1997
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.
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.
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.
23 extern int DEBUGLEVEL;
25 /* internal functions - modified versions of the ones in password.c */
26 static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (), int N);
27 static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (), int N);
29 /****************************************************************************
30 get a users home directory. tries as-is then lower case
31 ****************************************************************************/
32 char *get_home_dir(char *user)
34 static struct passwd *pass;
36 pass = Get_Pwnam(user,False);
38 if (!pass) return(NULL);
43 /*******************************************************************
44 map a username from a dos name to a unix name by looking in the username
46 ********************************************************************/
47 void map_username(char *user)
50 static BOOL initialised=False;
51 static fstring last_from,last_to;
54 char *mapfile = lp_username_map();
55 if (!*mapfile || depth) return;
60 *last_from = *last_to = 0;
64 if (strequal(user,last_to)) return;
66 if (strequal(user,last_from)) {
67 DEBUG(3,("Mapped user %s to %s\n",user,last_to));
72 f = fopen(mapfile,"r");
74 DEBUG(0,("can't open username map %s\n",mapfile));
78 DEBUG(4,("Scanning username map %s\n",mapfile));
82 for (; (s=fgets_slash(NULL,80,f)); free(s)) {
84 char *dosname = strchr(unixname,'=');
86 if (!dosname) continue;
89 while (isspace(*unixname)) unixname++;
90 if (!*unixname || strchr("#;",*unixname)) continue;
93 int l = strlen(unixname);
94 while (l && isspace(unixname[l-1])) {
100 if (strchr(dosname,'*') || user_in_list(user,dosname)) {
101 DEBUG(3,("Mapped user %s to %s\n",user,unixname));
102 StrnCpy(last_from,user,sizeof(last_from)-1);
103 sscanf(unixname,"%s",user);
104 StrnCpy(last_to,user,sizeof(last_to)-1);
113 /****************************************************************************
114 internals of Get_Pwnam wrapper
115 ****************************************************************************/
116 static struct passwd *_Get_Pwnam(char *s)
124 struct passwd_adjunct *pwret;
125 pwret = getpwanam(s);
128 free(ret->pw_passwd);
129 ret->pw_passwd = pwret->pwa_passwd;
139 /****************************************************************************
140 a wrapper for getpwnam() that tries with all lower and all upper case
141 if the initial name fails. Also tried with first letter capitalised
142 Note that this changes user!
143 ****************************************************************************/
144 struct passwd *Get_Pwnam(char *user,BOOL allow_change)
148 int usernamelevel = lp_usernamelevel();
152 if (!user || !(*user))
155 StrnCpy(user2,user,sizeof(user2)-1);
163 ret = _Get_Pwnam(user);
164 if (ret) return(ret);
167 ret = _Get_Pwnam(user);
168 if (ret) return(ret);
171 ret = _Get_Pwnam(user);
172 if (ret) return(ret);
174 /* try with first letter capitalised */
175 if (strlen(user) > 1)
177 ret = _Get_Pwnam(user);
178 if (ret) return(ret);
180 /* try with last letter capitalised */
182 last_char = strlen(user)-1;
183 user[last_char] = toupper(user[last_char]);
184 DEBUG(3, ("Trying username %s\n", user));
185 ret = _Get_Pwnam(user);
186 if (ret) return(ret);
188 /* try all combinations up to usernamelevel */
190 ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
191 if (ret) return(ret);
200 /****************************************************************************
201 check if a user is in a user list
202 ****************************************************************************/
203 BOOL user_in_list(char *user,char *list)
208 while (next_token(&p,tok,LIST_SEP))
210 if (strequal(user,tok))
216 static char *mydomain = NULL;
218 yp_get_default_domain(&mydomain);
222 DEBUG(5,("Unable to get default yp domain\n"));
227 DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
228 user, mydomain, &tok[1]));
229 DEBUG(5,("innetgr is %s\n",
230 innetgr(&tok[1], (char *) 0, user, mydomain)
231 ? "TRUE" : "FALSE"));
233 if (innetgr(&tok[1], (char *)0, user, mydomain))
245 struct passwd *pass = Get_Pwnam(user,False);
248 gptr = getgrgid(pass->pw_gid);
249 if (gptr && strequal(gptr->gr_name,&tok[1]))
253 gptr = (struct group *)getgrnam(&tok[1]);
257 member = gptr->gr_mem;
258 while (member && *member)
260 if (strequal(*member,user))
271 /* The functions below have been taken from password.c and slightly modified */
272 /****************************************************************************
273 apply a function to upper/lower case combinations
274 of a string and return true if one of them returns true.
275 try all combinations with N uppercase letters.
276 offset is the first char to try and change (start with 0)
277 it assumes the string starts lowercased
278 ****************************************************************************/
279 static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(),int N)
285 #ifdef PASSWORD_LENGTH
286 len = MIN(len,PASSWORD_LENGTH);
289 if (N <= 0 || offset >= len)
293 for (i=offset;i<(len-(N-1));i++)
297 if (!islower(c)) continue;
299 ret = uname_string_combinations2(s,i+1,fn,N-1);
306 /****************************************************************************
307 apply a function to upper/lower case combinations
308 of a string and return true if one of them returns true.
309 try all combinations with up to N uppercase letters.
310 offset is the first char to try and change (start with 0)
311 it assumes the string starts lowercased
312 ****************************************************************************/
313 static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(),int N)
320 ret = uname_string_combinations2(s,0,fn,n);