fixed an uninitialized variable in lookupsmbgrpgid() and
[Samba/gbeck.git] / source / lib / util_pwdb.c
blob6a37f1bf747935b4565e19546ee40a435ade475f
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Password and authentication handling
5 Copyright (C) Jeremy Allison 1996-1998
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
24 #include "nterr.h"
26 extern int DEBUGLEVEL;
27 extern DOM_SID global_sam_sid;
28 extern fstring global_sam_name;
30 extern DOM_SID global_member_sid;
31 extern fstring global_myworkgroup;
33 extern DOM_SID global_sid_S_1_5_20;
35 extern pstring global_myname;
38 * A list of the rids of well known BUILTIN and Domain users
39 * and groups.
42 rid_name builtin_alias_rids[] =
44 { BUILTIN_ALIAS_RID_ADMINS , "Administrators" },
45 { BUILTIN_ALIAS_RID_USERS , "Users" },
46 { BUILTIN_ALIAS_RID_GUESTS , "Guests" },
47 { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" },
49 { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" },
50 { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" },
51 { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" },
52 { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" },
53 { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" },
54 { 0 , NULL }
57 /* array lookup of well-known Domain RID users. */
58 rid_name domain_user_rids[] =
60 { DOMAIN_USER_RID_ADMIN , "Administrator" },
61 { DOMAIN_USER_RID_GUEST , "Guest" },
62 { 0 , NULL }
65 /* array lookup of well-known Domain RID groups. */
66 rid_name domain_group_rids[] =
68 { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" },
69 { DOMAIN_GROUP_RID_USERS , "Domain Users" },
70 { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" },
71 { 0 , NULL }
75 /*******************************************************************
76 lookup_wk_group_name
77 ********************************************************************/
78 uint32 lookup_wk_group_name(const char *group_name, const char *domain,
79 DOM_SID *sid, uint8 *type)
81 char *grp_name;
82 int i = -1; /* start do loop at -1 */
83 uint32 rid;
84 (*type) = SID_NAME_WKN_GRP;
86 if (strequal(domain, global_sam_name))
88 sid_copy(sid, &global_sam_sid);
90 else if (strequal(domain, "BUILTIN"))
92 sid_copy(sid, &global_sid_S_1_5_20);
94 else
96 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
99 do /* find, if it exists, a group rid for the group name */
101 i++;
102 rid = domain_group_rids[i].rid;
103 grp_name = domain_group_rids[i].name;
105 if (strequal(grp_name, group_name))
107 sid_append_rid(sid, rid);
109 return 0x0;
112 } while (grp_name != NULL);
114 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
117 /*******************************************************************
118 lookup_wk_user_name
119 ********************************************************************/
120 uint32 lookup_wk_user_name(const char *user_name, const char *domain,
121 DOM_SID *sid, uint8 *type)
123 char *usr_name;
124 int i = -1; /* start do loop at -1 */
125 (*type) = SID_NAME_USER;
127 if (strequal(domain, global_sam_name))
129 sid_copy(sid, &global_sam_sid);
131 else if (strequal(domain, "BUILTIN"))
133 sid_copy(sid, &global_sid_S_1_5_20);
135 else
137 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
140 do /* find, if it exists, a alias rid for the alias name */
142 i++;
143 usr_name = domain_user_rids[i].name;
145 } while (usr_name != NULL && !strequal(usr_name, user_name));
147 if (usr_name != NULL)
149 sid_append_rid(sid, domain_user_rids[i].rid);
150 return 0;
153 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
156 /*******************************************************************
157 lookup_builtin_alias_name
158 ********************************************************************/
159 uint32 lookup_builtin_alias_name(const char *alias_name, const char *domain,
160 DOM_SID *sid, uint8 *type)
162 char *als_name;
163 int i = 0;
164 uint32 rid;
166 if (strequal(domain, "BUILTIN"))
168 if (sid != NULL)
170 sid_copy(sid, &global_sid_S_1_5_20);
173 else
175 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
178 do /* find, if it exists, a alias rid for the alias name*/
180 rid = builtin_alias_rids[i].rid;
181 als_name = builtin_alias_rids[i].name;
183 if (strequal(als_name, alias_name))
185 if (sid != NULL)
187 sid_append_rid(sid, rid);
190 if (type != NULL)
192 (*type) = SID_NAME_ALIAS;
195 return 0x0;
198 i++;
200 } while (als_name != NULL);
202 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
204 /**********************************************************
205 Encode the account control bits into a string.
206 length = length of string to encode into (including terminating
207 null). length *MUST BE MORE THAN 2* !
208 **********************************************************/
210 char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
212 static fstring acct_str;
213 size_t i = 0;
215 acct_str[i++] = '[';
217 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
218 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
219 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
220 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
221 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
222 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
223 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
224 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
225 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
226 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
227 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
229 for ( ; i < length - 2 ; i++ )
231 acct_str[i] = ' ';
234 i = length - 2;
235 acct_str[i++] = ']';
236 acct_str[i++] = '\0';
238 return acct_str;
241 /**********************************************************
242 Decode the account control bits from a string.
244 this function breaks coding standards minimum line width of 80 chars.
245 reason: vertical line-up code clarity - all case statements fit into
246 15 lines, which is more important.
247 **********************************************************/
249 uint16 pwdb_decode_acct_ctrl(const char *p)
251 uint16 acct_ctrl = 0;
252 BOOL finished = False;
255 * Check if the account type bits have been encoded after the
256 * NT password (in the form [NDHTUWSLXI]).
259 if (*p != '[') return 0;
261 for (p++; *p && !finished; p++)
263 switch (*p)
265 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
266 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
267 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
268 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
269 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
270 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
271 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
272 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
273 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
274 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
275 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
276 case ' ': { break; }
277 case ':':
278 case '\n':
279 case '\0':
280 case ']':
281 default: { finished = True; }
285 return acct_ctrl;
288 /*******************************************************************
289 gets password-database-format time from a string.
290 ********************************************************************/
292 static time_t get_time_from_string(const char *p)
294 int i;
296 for (i = 0; i < 8; i++)
298 if (p[i] == '\0' || !isxdigit((int)(p[i]&0xFF)))
300 break;
303 if (i == 8)
306 * p points at 8 characters of hex digits -
307 * read into a time_t as the seconds since
308 * 1970 that the password was last changed.
310 return (time_t)strtol(p, NULL, 16);
312 return (time_t)-1;
315 /*******************************************************************
316 gets password last set time
317 ********************************************************************/
319 time_t pwdb_get_last_set_time(const char *p)
321 if (*p && !StrnCaseCmp(p, "LCT-", 4))
323 return get_time_from_string(p + 4);
325 return (time_t)-1;
329 /*******************************************************************
330 sets password-database-format time in a string.
331 ********************************************************************/
332 static void set_time_in_string(char *p, int max_len, char *type, time_t t)
334 slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
337 /*******************************************************************
338 sets logon time
339 ********************************************************************/
340 void pwdb_set_logon_time(char *p, int max_len, time_t t)
342 set_time_in_string(p, max_len, "LNT", t);
345 /*******************************************************************
346 sets logoff time
347 ********************************************************************/
348 void pwdb_set_logoff_time(char *p, int max_len, time_t t)
350 set_time_in_string(p, max_len, "LOT", t);
353 /*******************************************************************
354 sets kickoff time
355 ********************************************************************/
356 void pwdb_set_kickoff_time(char *p, int max_len, time_t t)
358 set_time_in_string(p, max_len, "KOT", t);
361 /*******************************************************************
362 sets password can change time
363 ********************************************************************/
364 void pwdb_set_can_change_time(char *p, int max_len, time_t t)
366 set_time_in_string(p, max_len, "CCT", t);
369 /*******************************************************************
370 sets password last set time
371 ********************************************************************/
372 void pwdb_set_must_change_time(char *p, int max_len, time_t t)
374 set_time_in_string(p, max_len, "MCT", t);
377 /*******************************************************************
378 sets password last set time
379 ********************************************************************/
380 void pwdb_set_last_set_time(char *p, int max_len, time_t t)
382 set_time_in_string(p, max_len, "LCT", t);
386 /*************************************************************
387 Routine to set 32 hex password characters from a 16 byte array.
388 **************************************************************/
389 void pwdb_sethexpwd(char *p, const char *pwd, uint16 acct_ctrl)
391 if (pwd != NULL)
393 int i;
394 for (i = 0; i < 16; i++)
396 slprintf(&p[i*2], 33, "%02X", pwd[i]);
399 else
401 if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
403 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
405 else
407 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
412 /*************************************************************
413 Routine to get the 32 hex characters and turn them
414 into a 16 byte array.
415 **************************************************************/
416 BOOL pwdb_gethexpwd(const char *p, char *pwd)
418 return strhex_to_str(pwd, 32, p) == 16;
422 /*************************************************************
423 initialise password databases, domain names, domain sid.
424 **************************************************************/
425 BOOL pwdb_initialise(BOOL is_server)
427 get_sam_domain_name();
429 if (!init_myworkgroup())
431 return False;
434 generate_wellknown_sids();
436 if (is_server)
438 if (!generate_sam_sid(global_sam_name))
440 DEBUG(0,("ERROR: Samba cannot create a SAM SID for its domain (%s).\n",
441 global_sam_name));
442 return False;
445 else
447 if (!get_domain_sids(&global_member_sid, &global_sam_sid, global_myname))
449 return False;
453 return initialise_password_db();