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 3 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, see <http://www.gnu.org/licenses/>.
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 *),
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 *),
31
/****************************************************************************
32
Get a users home directory.
33
****************************************************************************/
35
char *get_user_home_dir(TALLOC_CTX *mem_ctx, const char *user)
40
/* Ensure the user exists. */
42
pass = Get_Pwnam_alloc(mem_ctx, user);
47
/* Return home directory from struct passwd. */
49
result = talloc_move(mem_ctx, &pass->pw_dir);
55
/****************************************************************************
56
* A wrapper for sys_getpwnam(). The following variations are tried:
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
****************************************************************************/
63
static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
64
const char *user, char *user2)
66
struct passwd *ret = NULL;
68
if (!user2 || !(*user2))
71
if (!user || !(*user))
74
/* Try in all lower case first as this is the most
75
common case on UNIX systems */
77
DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
78
ret = getpwnam_alloc(mem_ctx, user2);
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",
86
ret = getpwnam_alloc(mem_ctx, user);
91
/* Try as uppercase, if username wasn't originally uppercase */
93
if(strcmp(user, user2) != 0) {
94
DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",
96
ret = getpwnam_alloc(mem_ctx, user2);
101
/* Try all combinations up to usernamelevel */
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,
109
DEBUG(5,("Get_Pwnam_internals %s find user [%s]!\n",ret ?
110
"did":"didn't", user));
115
/****************************************************************************
116
Get_Pwnam wrapper without modification.
117
NOTE: This with NOT modify 'user'!
118
This will return an allocated structure
119
****************************************************************************/
121
struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
126
if ( *user == '\0' ) {
127
DEBUG(10,("Get_Pwnam: empty username!\n"));
131
fstrcpy(user2, user);
133
DEBUG(5,("Finding user %s\n", user));
135
ret = Get_Pwnam_internals(mem_ctx, user, user2);
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
****************************************************************************/
149
static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx,
151
struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *),
154
ssize_t len = (ssize_t)strlen(s);
158
if (N <= 0 || offset >= len)
159
return(fn(mem_ctx, s));
161
for (i=offset;i<(len-(N-1));i++) {
163
if (!islower_ascii((int)c))
165
s[i] = toupper_ascii(c);
166
ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
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
****************************************************************************/
182
static struct passwd * uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
183
struct passwd * (*fn)(TALLOC_CTX *mem_ctx, const char *),
190
ret = uname_string_combinations2(s,mem_ctx,0,fn,n);