2
Unix SMB/CIFS implementation.
4
Copyright (C) Andrew Tridgell 1992-1998
5
Copyright (C) Jeremy Allison 1997-2001.
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.
24
/* internal functions */
25
static struct passwd *uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
26
struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
28
static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, int offset,
29
struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
32
/****************************************************************************
33
Get a users home directory.
34
****************************************************************************/
36
char *get_user_home_dir(const char *user)
38
static struct passwd *pass;
40
/* Ensure the user exists. */
42
pass = Get_Pwnam(user);
46
/* Return home directory from struct passwd. */
51
/****************************************************************************
52
* A wrapper for sys_getpwnam(). The following variations are tried:
54
* - in all lower case if this differs from transmitted
55
* - in all upper case if this differs from transmitted
56
* - using lp_usernamelevel() for permutations.
57
****************************************************************************/
59
static struct passwd *Get_Pwnam_ret = NULL;
61
static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
62
const char *user, char *user2)
64
struct passwd *ret = NULL;
66
if (!user2 || !(*user2))
69
if (!user || !(*user))
72
/* Try in all lower case first as this is the most
73
common case on UNIX systems */
75
DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
76
ret = getpwnam_alloc(mem_ctx, user2);
80
/* Try as given, if username wasn't originally lowercase */
81
if(strcmp(user, user2) != 0) {
82
DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n",
84
ret = getpwnam_alloc(mem_ctx, user);
89
/* Try as uppercase, if username wasn't originally uppercase */
91
if(strcmp(user, user2) != 0) {
92
DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",
94
ret = getpwnam_alloc(mem_ctx, user2);
99
/* Try all combinations up to usernamelevel */
101
DEBUG(5,("Checking combinations of %d uppercase letters in %s\n",
102
lp_usernamelevel(), user2));
103
ret = uname_string_combinations(user2, mem_ctx, getpwnam_alloc,
107
DEBUG(5,("Get_Pwnam_internals %s find user [%s]!\n",ret ?
108
"did":"didn't", user));
113
/****************************************************************************
114
Get_Pwnam wrapper without modification.
115
NOTE: This with NOT modify 'user'!
116
This will return an allocated structure
117
****************************************************************************/
119
struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
124
if ( *user == '\0' ) {
125
DEBUG(10,("Get_Pwnam: empty username!\n"));
129
fstrcpy(user2, user);
131
DEBUG(5,("Finding user %s\n", user));
133
ret = Get_Pwnam_internals(mem_ctx, user, user2);
138
/****************************************************************************
139
Get_Pwnam wrapper without modification.
140
NOTE: This with NOT modify 'user'!
141
****************************************************************************/
143
struct passwd *Get_Pwnam(const char *user)
147
ret = Get_Pwnam_alloc(NULL, user);
149
/* This call used to just return the 'passwd' static buffer.
150
This could then have accidental reuse implications, so
151
we now malloc a copy, and free it in the next use.
153
This should cause the (ab)user to segfault if it
156
This is better than useing the wrong data in security
159
The real fix is to make the callers free the returned
164
TALLOC_FREE(Get_Pwnam_ret);
172
/* The functions below have been taken from password.c and slightly modified */
173
/****************************************************************************
174
Apply a function to upper/lower case combinations
175
of a string and return true if one of them returns true.
176
Try all combinations with N uppercase letters.
177
offset is the first char to try and change (start with 0)
178
it assumes the string starts lowercased
179
****************************************************************************/
181
static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx,
183
struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *),
186
ssize_t len = (ssize_t)strlen(s);
190
if (N <= 0 || offset >= len)
191
return(fn(mem_ctx, s));
193
for (i=offset;i<(len-(N-1));i++) {
195
if (!islower_ascii((int)c))
197
s[i] = toupper_ascii(c);
198
ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
206
/****************************************************************************
207
Apply a function to upper/lower case combinations
208
of a string and return true if one of them returns true.
209
Try all combinations with up to N uppercase letters.
210
offset is the first char to try and change (start with 0)
211
it assumes the string starts lowercased
212
****************************************************************************/
214
static struct passwd * uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
215
struct passwd * (*fn)(TALLOC_CTX *mem_ctx, const char *),
222
ret = uname_string_combinations2(s,mem_ctx,0,fn,n);