Large commit which restructures the local password storage API.
[Samba.git] / source / passdb / passdb.c
blob5b5b2e8a98bac5ceb7df5fc9db80dff1cf36afbc
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
7 Copyright (C) Gerald (Jerry) Carter 2000
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <dlfcn.h>
25 #include "includes.h"
27 extern int DEBUGLEVEL;
30 * This is set on startup - it defines the SID for this
31 * machine, and therefore the SAM database for which it is
32 * responsible.
35 extern DOM_SID global_sam_sid;
36 extern pstring global_myname;
37 extern fstring global_myworkgroup;
40 * NOTE. All these functions are abstracted into a structure
41 * that points to the correct function for the selected database. JRA.
43 * NOTE. for the get/mod/add functions, there are two sets of functions.
44 * one supports struct sam_passwd, the other supports struct smb_passwd.
45 * for speed optimisation it is best to support both these sets.
47 * it is, however, optional to support one set but not the other: there
48 * is conversion-capability built in to passdb.c, and run-time error
49 * detection for when neither are supported.
51 * password database writers are recommended to implement the sam_passwd
52 * functions in a first pass, as struct sam_passwd contains more
53 * information, needed by the NT Domain support.
55 * a full example set of derivative functions are listed below. an API
56 * writer is expected to cut/paste these into their module, replace
57 * either one set (struct smb_passwd) or the other (struct sam_passwd)
58 * OR both, and optionally also to write display info routines
59 * (struct sam_disp_info). lkcl
63 struct passdb_ops *pdb_ops;
65 static void* pdb_handle = NULL;
67 /***************************************************************
68 Initialize the password db operations.
69 ***************************************************************/
70 BOOL initialize_password_db(BOOL reload)
73 char* modulename = lp_passdb_module_path();
75 return True;
77 /* load another module? */
78 if (reload && pdb_handle)
80 dlclose (pdb_handle);
81 pdb_handle = NULL;
84 /* do we have a module defined or use the default? */
85 if (strlen (modulename) != 0)
87 if ((pdb_handle=dlopen (modulename, RTLD_LAZY)) == NULL)
89 DEBUG(0,("initialize_password_db: ERROR - Unable to open passdb module \"%s\"!\n%s\n",
90 modulename, dlerror()));
92 else
93 DEBUG(1,("initialize_password_db: passdb module \"%s\" loaded successfully\n", modulename));
96 /* either no module name defined or the one that was failed
97 to open. Let's try the default */
98 if (pdb_handle == NULL)
100 if ((pdb_handle=dlopen ("libpdbfile.so", RTLD_LAZY)) == NULL)
102 DEBUG(0,("initialize_password_db: ERROR - Unable to open \"libpdbfile.so\" passdb module! No user authentication possible!\n%s\n",
103 dlerror()));
104 return False;
106 else
107 DEBUG(1,("initialize_password_db: passdb module \"libpdbfile.so\" loaded successfully\n"));
111 return (pdb_handle != NULL);
114 /*************************************************************
115 initialises a struct sam_disp_info.
116 **************************************************************/
117 static void pdb_init_dispinfo(struct sam_disp_info *user)
119 if (user == NULL)
120 return;
121 ZERO_STRUCTP(user);
124 /*************************************************************
125 initialises a struct sam_passwd.
126 ************************************************************/
127 void pdb_init_sam(SAM_ACCOUNT *user)
129 if (user == NULL)
130 return;
132 ZERO_STRUCTP(user);
134 user->logon_time = (time_t)-1;
135 user->logoff_time = (time_t)-1;
136 user->kickoff_time = (time_t)-1;
137 user->pass_last_set_time = (time_t)-1;
138 user->pass_can_change_time = (time_t)-1;
139 user->pass_must_change_time = (time_t)-1;
141 user->unknown_3 = 0x00ffffff; /* don't know */
142 user->logon_divs = 168; /* hours per week */
143 user->hours_len = 21; /* 21 times 8 bits = 168 */
144 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
145 user->unknown_5 = 0x00020000; /* don't know */
146 user->unknown_5 = 0x000004ec; /* don't know */
150 /************************************************************
151 free all pointer members and then reinit the SAM_ACCOUNT
152 ***********************************************************/
153 void pdb_clear_sam(SAM_ACCOUNT *user)
155 if (user == NULL)
156 return;
158 /* clear all pointer members */
159 if (user->username)
160 free(user->username);
161 if (user->full_name)
162 free(user->full_name);
163 if (user->home_dir)
164 free(user->home_dir);
165 if (user->dir_drive)
166 free(user->dir_drive);
167 if (user->logon_script)
168 free(user->logon_script);
169 if (user->profile_path)
170 free(user->profile_path);
171 if (user->acct_desc)
172 free(user->acct_desc);
173 if (user->workstations)
174 free(user->workstations);
175 if (user->unknown_str)
176 free(user->unknown_str);
177 if (user->munged_dial)
178 free(user->munged_dial);
180 if (user->lm_pw)
181 free(user->lm_pw);
182 if (user->nt_pw)
183 free(user->nt_pw);
186 /* now initialize */
187 pdb_init_sam(user);
192 /*************************************************************************
193 Routine to return the next entry in the sam passwd list.
194 *************************************************************************/
195 struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
197 static struct sam_disp_info disp_info;
199 if (user == NULL)
200 return NULL;
202 pdb_init_dispinfo(&disp_info);
204 disp_info.smb_name = user->username;
205 disp_info.full_name = user->full_name;
206 disp_info.user_rid = user->user_rid;
208 return &disp_info;
212 /**********************************************************
213 Encode the account control bits into a string.
214 length = length of string to encode into (including terminating
215 null). length *MUST BE MORE THAN 2* !
216 **********************************************************/
217 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
219 static fstring acct_str;
220 size_t i = 0;
222 acct_str[i++] = '[';
224 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
225 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
226 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
227 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
228 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
229 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
230 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
231 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
232 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
233 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
234 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
236 for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
238 i = length - 2;
239 acct_str[i++] = ']';
240 acct_str[i++] = '\0';
242 return acct_str;
245 /**********************************************************
246 Decode the account control bits from a string.
248 this function breaks coding standards minimum line width of 80 chars.
249 reason: vertical line-up code clarity - all case statements fit into
250 15 lines, which is more important.
251 **********************************************************/
253 uint16 pdb_decode_acct_ctrl(const char *p)
255 uint16 acct_ctrl = 0;
256 BOOL finished = False;
259 * Check if the account type bits have been encoded after the
260 * NT password (in the form [NDHTUWSLXI]).
263 if (*p != '[') return 0;
265 for (p++; *p && !finished; p++)
267 switch (*p)
269 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
270 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
271 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
272 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
273 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
274 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
275 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
276 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
277 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
278 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
279 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
280 case ' ': { break; }
281 case ':':
282 case '\n':
283 case '\0':
284 case ']':
285 default: { finished = True; }
289 return acct_ctrl;
292 /*************************************************************
293 Routine to set 32 hex password characters from a 16 byte array.
294 **************************************************************/
295 void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
297 if (pwd != NULL) {
298 int i;
299 for (i = 0; i < 16; i++)
300 slprintf(&p[i*2], 3, "%02X", pwd[i]);
301 } else {
302 if (acct_ctrl & ACB_PWNOTREQ)
303 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
304 else
305 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
309 /*************************************************************
310 Routine to get the 32 hex characters and turn them
311 into a 16 byte array.
312 **************************************************************/
313 BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
315 int i;
316 unsigned char lonybble, hinybble;
317 char *hexchars = "0123456789ABCDEF";
318 char *p1, *p2;
320 for (i = 0; i < 32; i += 2)
322 hinybble = toupper(p[i]);
323 lonybble = toupper(p[i + 1]);
325 p1 = strchr(hexchars, hinybble);
326 p2 = strchr(hexchars, lonybble);
328 if (!p1 || !p2)
330 return (False);
333 hinybble = PTR_DIFF(p1, hexchars);
334 lonybble = PTR_DIFF(p2, hexchars);
336 pwd[i / 2] = (hinybble << 4) | lonybble;
338 return (True);
341 /*******************************************************************
342 Group and User RID username mapping function
343 ********************************************************************/
344 BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
346 struct passwd *pw = Get_Pwnam(user_name, False);
348 if (u_rid == NULL || g_rid == NULL || user_name == NULL)
350 return False;
353 if (!pw)
355 DEBUG(1,("Username %s is invalid on this system\n", user_name));
356 return False;
359 if (user_in_list(user_name, lp_domain_guest_users()))
361 *u_rid = DOMAIN_USER_RID_GUEST;
363 else if (user_in_list(user_name, lp_domain_admin_users()))
365 *u_rid = DOMAIN_USER_RID_ADMIN;
367 else
369 /* turn the unix UID into a Domain RID. this is what the posix
370 sub-system does (adds 1000 to the uid) */
371 *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
374 /* absolutely no idea what to do about the unix GID to Domain RID mapping */
375 *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
377 return True;
380 /*******************************************************************
381 Converts NT user RID to a UNIX uid.
382 ********************************************************************/
383 uid_t pdb_user_rid_to_uid(uint32 user_rid)
385 return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
388 /*******************************************************************
389 Converts NT user RID to a UNIX gid.
390 ********************************************************************/
392 gid_t pdb_user_rid_to_gid(uint32 user_rid)
394 return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
397 /*******************************************************************
398 converts UNIX uid to an NT User RID.
399 ********************************************************************/
401 uint32 pdb_uid_to_user_rid(uid_t uid)
403 return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
406 /*******************************************************************
407 converts NT Group RID to a UNIX uid.
408 ********************************************************************/
410 uint32 pdb_gid_to_group_rid(gid_t gid)
412 return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
415 /*******************************************************************
416 Decides if a RID is a well known RID.
417 ********************************************************************/
419 static BOOL pdb_rid_is_well_known(uint32 rid)
421 return (rid < 1000);
424 /*******************************************************************
425 Decides if a RID is a user or group RID.
426 ********************************************************************/
427 BOOL pdb_rid_is_user(uint32 rid)
429 /* lkcl i understand that NT attaches an enumeration to a RID
430 * such that it can be identified as either a user, group etc
431 * type. there are 5 such categories, and they are documented.
433 if(pdb_rid_is_well_known(rid)) {
435 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
436 * and DOMAIN_USER_RID_GUEST.
438 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
439 return True;
440 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
441 return True;
443 return False;
446 /*******************************************************************
447 Convert a rid into a name. Used in the lookup SID rpc.
448 ********************************************************************/
449 BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
452 BOOL is_user = pdb_rid_is_user(rid);
454 DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
455 "group", (unsigned int)rid));
457 if(is_user) {
458 if(rid == DOMAIN_USER_RID_ADMIN) {
459 pstring admin_users;
460 char *p = admin_users;
461 pstrcpy( admin_users, lp_domain_admin_users());
462 if(!next_token(&p, name, NULL, sizeof(fstring)))
463 fstrcpy(name, "Administrator");
464 } else if (rid == DOMAIN_USER_RID_GUEST) {
465 pstring guest_users;
466 char *p = guest_users;
467 pstrcpy( guest_users, lp_domain_guest_users());
468 if(!next_token(&p, name, NULL, sizeof(fstring)))
469 fstrcpy(name, "Guest");
470 } else {
471 uid_t uid = pdb_user_rid_to_uid(rid);
472 struct passwd *pass = sys_getpwuid(uid);
474 *psid_name_use = SID_NAME_USER;
476 DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
477 pass ? "succeeded" : "failed" ));
479 if(!pass) {
480 slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
481 return True;
484 fstrcpy(name, pass->pw_name);
486 DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
487 (unsigned int)rid ));
490 } else {
491 gid_t gid = pdb_user_rid_to_gid(rid);
492 struct group *gr = getgrgid(gid);
494 *psid_name_use = SID_NAME_ALIAS;
496 DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
497 gr ? "succeeded" : "failed" ));
499 if(!gr) {
500 slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
501 return True;
504 fstrcpy( name, gr->gr_name);
506 DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
507 (unsigned int)rid ));
510 return True;
513 /*******************************************************************
514 Convert a name into a SID. Used in the lookup name rpc.
515 ********************************************************************/
517 BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
519 extern DOM_SID global_sid_World_Domain;
520 struct passwd *pass = NULL;
521 DOM_SID local_sid;
523 sid_copy(&local_sid, &global_sam_sid);
525 if(!strequal(global_myname, domain) && !strequal(global_myworkgroup, domain))
526 return False;
529 * Special case for MACHINE\Everyone. Map to the world_sid.
532 if(strequal(user, "Everyone")) {
533 sid_copy( psid, &global_sid_World_Domain);
534 sid_append_rid(psid, 0);
535 *psid_name_use = SID_NAME_ALIAS;
536 return True;
539 (void)map_username(user);
541 if(!(pass = Get_Pwnam(user, False))) {
543 * Maybe it was a group ?
545 struct group *grp = getgrnam(user);
547 if(!grp)
548 return False;
550 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
551 *psid_name_use = SID_NAME_ALIAS;
552 } else {
554 sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
555 *psid_name_use = SID_NAME_USER;
558 sid_copy( psid, &local_sid);
560 return True;
563 /****************************************************************************
564 Convert a uid to SID - locally.
565 ****************************************************************************/
566 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
568 extern DOM_SID global_sam_sid;
570 sid_copy(psid, &global_sam_sid);
571 sid_append_rid(psid, pdb_uid_to_user_rid(uid));
573 return psid;
577 /****************************************************************************
578 Convert a SID to uid - locally.
579 ****************************************************************************/
580 BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
582 extern DOM_SID global_sam_sid;
584 DOM_SID dom_sid;
585 uint32 rid;
587 *name_type = SID_NAME_UNKNOWN;
589 sid_copy(&dom_sid, psid);
590 sid_split_rid(&dom_sid, &rid);
593 * We can only convert to a uid if this is our local
594 * Domain SID (ie. we are the controling authority).
596 if (!sid_equal(&global_sam_sid, &dom_sid))
597 return False;
599 *puid = pdb_user_rid_to_uid(rid);
602 * Ensure this uid really does exist.
604 if(!sys_getpwuid(*puid))
605 return False;
607 return True;
610 /****************************************************************************
611 Convert a gid to SID - locally.
612 ****************************************************************************/
613 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
615 extern DOM_SID global_sam_sid;
617 sid_copy(psid, &global_sam_sid);
618 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
620 return psid;
623 /****************************************************************************
624 Convert a SID to gid - locally.
625 ****************************************************************************/
626 BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
628 extern DOM_SID global_sam_sid;
629 DOM_SID dom_sid;
630 uint32 rid;
632 *name_type = SID_NAME_UNKNOWN;
634 sid_copy(&dom_sid, psid);
635 sid_split_rid(&dom_sid, &rid);
638 * We can only convert to a gid if this is our local
639 * Domain SID (ie. we are the controling authority).
642 if (!sid_equal(&global_sam_sid, &dom_sid))
643 return False;
645 *pgid = pdb_user_rid_to_gid(rid);
648 * Ensure this gid really does exist.
651 if(!getgrgid(*pgid))
652 return False;
654 return True;
657 static void select_name(fstring *string, char **name, const UNISTR2 *from)
659 if (from->buffer != 0)
661 unistr2_to_ascii(*string, from, sizeof(*string));
662 *name = *string;
666 /*************************************************************
667 copies a sam passwd.
668 **************************************************************/
669 void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from)
671 static fstring smb_name;
672 static fstring full_name;
673 static fstring home_dir;
674 static fstring dir_drive;
675 static fstring logon_script;
676 static fstring profile_path;
677 static fstring acct_desc;
678 static fstring workstations;
679 static fstring unknown_str;
680 static fstring munged_dial;
682 if (from == NULL || to == NULL) return;
684 to->logon_time = nt_time_to_unix(&from->logon_time);
685 to->logoff_time = nt_time_to_unix(&from->logoff_time);
686 to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
687 to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
688 to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
689 to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
691 select_name(&smb_name , &to->username , &from->uni_user_name );
692 select_name(&full_name , &to->full_name , &from->uni_full_name );
693 select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
694 select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
695 select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
696 select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
697 select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
698 select_name(&workstations, &to->workstations, &from->uni_workstations);
699 select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
700 select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
702 to->uid = (uid_t)-1;
703 to->gid = (gid_t)-1;
704 to->user_rid = from->user_rid;
705 to->group_rid = from->group_rid;
707 to->lm_pw = NULL;
708 to->nt_pw = NULL;
710 to->acct_ctrl = from->acb_info;
711 to->unknown_3 = from->unknown_3;
713 to->logon_divs = from->logon_divs;
714 to->hours_len = from->logon_hrs.len;
715 memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
717 to->unknown_5 = from->unknown_5;
718 to->unknown_6 = from->unknown_6;
721 /*************************************************************
722 copies a sam passwd.
723 **************************************************************/
724 void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from)
726 static fstring smb_name;
727 static fstring full_name;
728 static fstring home_dir;
729 static fstring dir_drive;
730 static fstring logon_script;
731 static fstring profile_path;
732 static fstring acct_desc;
733 static fstring workstations;
734 static fstring unknown_str;
735 static fstring munged_dial;
737 if (from == NULL || to == NULL) return;
739 to->logon_time = nt_time_to_unix(&from->logon_time);
740 to->logoff_time = nt_time_to_unix(&from->logoff_time);
741 to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
742 to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
743 to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
744 to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
746 select_name(&smb_name , &to->username , &from->uni_user_name );
747 select_name(&full_name , &to->full_name , &from->uni_full_name );
748 select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
749 select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
750 select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
751 select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
752 select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
753 select_name(&workstations, &to->workstations, &from->uni_workstations);
754 select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
755 select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
757 to->uid = (uid_t)-1;
758 to->gid = (gid_t)-1;
759 to->user_rid = from->user_rid;
760 to->group_rid = from->group_rid;
762 to->lm_pw = NULL;
763 to->nt_pw = NULL;
765 to->acct_ctrl = from->acb_info;
766 to->unknown_3 = from->unknown_3;
768 to->logon_divs = from->logon_divs;
769 to->hours_len = from->logon_hrs.len;
770 memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
772 to->unknown_5 = from->unknown_5;
773 to->unknown_6 = from->unknown_6;
777 /*************************************************************
778 copies a sam passwd.
780 FIXME! Do we need to use dynamically allocated strings
781 here instead of static strings?
783 Why are password hashes not also copied? --jerry
784 **************************************************************/
785 void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from)
787 static fstring smb_name="";
788 static fstring full_name="";
789 static fstring home_dir="";
790 static fstring dir_drive="";
791 static fstring logon_script="";
792 static fstring profile_path="";
793 static fstring acct_desc="";
794 static fstring workstations="";
795 static fstring unknown_str="";
796 static fstring munged_dial="";
798 if (from == NULL || to == NULL) return;
800 memcpy(to, from, sizeof(*from));
802 if (from->username != NULL) {
803 fstrcpy(smb_name , from->username);
804 to->username = smb_name;
807 if (from->full_name != NULL) {
808 fstrcpy(full_name, from->full_name);
809 to->full_name = full_name;
812 if (from->home_dir != NULL) {
813 fstrcpy(home_dir , from->home_dir);
814 to->home_dir = home_dir;
817 if (from->dir_drive != NULL) {
818 fstrcpy(dir_drive , from->dir_drive);
819 to->dir_drive = dir_drive;
822 if (from->logon_script != NULL) {
823 fstrcpy(logon_script , from->logon_script);
824 to->logon_script = logon_script;
827 if (from->profile_path != NULL) {
828 fstrcpy(profile_path , from->profile_path);
829 to->profile_path = profile_path;
832 if (from->acct_desc != NULL) {
833 fstrcpy(acct_desc , from->acct_desc);
834 to->acct_desc = acct_desc;
837 if (from->workstations != NULL) {
838 fstrcpy(workstations , from->workstations);
839 to->workstations = workstations;
842 if (from->unknown_str != NULL) {
843 fstrcpy(unknown_str , from->unknown_str);
844 to->unknown_str = unknown_str;
847 if (from->munged_dial != NULL) {
848 fstrcpy(munged_dial , from->munged_dial);
849 to->munged_dial = munged_dial;
853 /*************************************************************
854 change a password entry in the local smbpasswd file
856 FIXME!! The function needs to be abstracted into the
857 passdb interface or something. It is currently being called
858 by _api_samr_create_user() in rpc_server/srv_samr.c
860 --jerry
861 *************************************************************/
863 BOOL local_password_change(char *user_name, int local_flags,
864 char *new_passwd,
865 char *err_str, size_t err_str_len,
866 char *msg_str, size_t msg_str_len)
868 struct passwd *pwd = NULL;
869 SAM_ACCOUNT *sam_pass;
870 SAM_ACCOUNT new_sam_acct;
871 uchar new_p16[16];
872 uchar new_nt_p16[16];
874 *err_str = '\0';
875 *msg_str = '\0';
877 if (local_flags & LOCAL_ADD_USER) {
880 * Check for a local account - if we're adding only.
883 if(!(pwd = sys_getpwnam(user_name))) {
884 slprintf(err_str, err_str_len - 1, "User %s does not \
885 exist in system password file (usually /etc/passwd). Cannot add \
886 account without a valid local system user.\n", user_name);
887 return False;
891 /* Calculate the MD4 hash (NT compatible) of the new password. */
892 nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
894 /* Get the smb passwd entry for this user */
895 sam_pass = pdb_getsampwnam(user_name);
896 if (sam_pass == NULL)
898 if(!(local_flags & LOCAL_ADD_USER))
900 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
901 return False;
904 /* create the SAM_ACCOUNT struct and call pdb_add_sam_account */
905 pdb_init_sam (&new_sam_acct);
906 pdb_set_username (&new_sam_acct, user_name);
907 pdb_set_uid (&new_sam_acct, pwd->pw_uid);
908 pdb_set_pass_last_set_time(&new_sam_acct, time(NULL));
910 /* set account flags */
911 pdb_set_acct_ctrl(&new_sam_acct,((local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL) );
912 if (local_flags & LOCAL_DISABLE_USER)
914 pdb_set_acct_ctrl (&new_sam_acct, pdb_get_acct_ctrl(&new_sam_acct)|ACB_DISABLED);
916 if (local_flags & LOCAL_SET_NO_PASSWORD)
918 pdb_set_acct_ctrl (&new_sam_acct, pdb_get_acct_ctrl(&new_sam_acct)|ACB_PWNOTREQ);
920 else
922 /* set the passwords here. if we get to here it means
923 we have a valid, active account */
924 pdb_set_lanman_passwd (&new_sam_acct, new_p16);
925 pdb_set_nt_passwd (&new_sam_acct, new_nt_p16);
929 if (pdb_add_sam_account(&new_sam_acct))
931 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
932 pdb_clear_sam (&new_sam_acct);
933 return True;
935 else
937 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
938 return False;
941 else
943 /* the entry already existed */
944 local_flags &= ~LOCAL_ADD_USER;
948 * We are root - just write the new password
949 * and the valid last change time.
952 if(local_flags & LOCAL_DISABLE_USER)
954 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
956 else if (local_flags & LOCAL_ENABLE_USER)
958 if(pdb_get_lanman_passwd(sam_pass) == NULL)
960 pdb_set_lanman_passwd (sam_pass, new_p16);
961 pdb_set_nt_passwd (sam_pass, new_nt_p16);
963 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
964 } else if (local_flags & LOCAL_SET_NO_PASSWORD)
966 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
968 /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
969 pdb_set_lanman_passwd (sam_pass, NULL);
970 pdb_set_nt_passwd (sam_pass, NULL);
972 else
975 * If we're dealing with setting a completely empty user account
976 * ie. One with a password of 'XXXX', but not set disabled (like
977 * an account created from scratch) then if the old password was
978 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
979 * We remove that as we're giving this user their first password
980 * and the decision hasn't really been made to disable them (ie.
981 * don't create them disabled). JRA.
983 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED))
984 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
985 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ));
986 pdb_set_lanman_passwd (sam_pass, new_p16);
987 pdb_set_nt_passwd (sam_pass, new_nt_p16);
990 if(local_flags & LOCAL_DELETE_USER)
992 if (!pdb_delete_sam_account(user_name))
994 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
995 return False;
997 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
999 else
1001 if(!pdb_update_sam_account(sam_pass, True))
1003 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1004 return False;
1006 if(local_flags & LOCAL_DISABLE_USER)
1007 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1008 else if (local_flags & LOCAL_ENABLE_USER)
1009 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1010 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1011 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1014 return True;
1018 /*********************************************************************
1019 collection of get...() functions for SAM_ACCOUNT_INFO
1020 ********************************************************************/
1021 uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass)
1023 if (sampass)
1024 return (sampass->acct_ctrl);
1025 else
1026 return (ACB_DISABLED);
1029 time_t pdb_get_logon_time (SAM_ACCOUNT *sampass)
1031 if (sampass)
1032 return (sampass->logon_time);
1033 else
1034 return (-1);
1037 time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass)
1039 if (sampass)
1040 return (sampass->logoff_time);
1041 else
1042 return (-1);
1045 time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass)
1047 if (sampass)
1048 return (sampass->kickoff_time);
1049 else
1050 return (-1);
1053 time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass)
1055 if (sampass)
1056 return (sampass->pass_last_set_time);
1057 else
1058 return (-1);
1061 time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass)
1063 if (sampass)
1064 return (sampass->pass_can_change_time);
1065 else
1066 return (-1);
1069 time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass)
1071 if (sampass)
1072 return (sampass->pass_must_change_time);
1073 else
1074 return (-1);
1077 uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass)
1079 if (sampass)
1080 return (sampass->logon_divs);
1081 else
1082 return (-1);
1085 uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass)
1087 if (sampass)
1088 return (sampass->hours_len);
1089 else
1090 return (-1);
1093 uint8* pdb_get_hours (SAM_ACCOUNT *sampass)
1095 if (sampass)
1096 return (sampass->hours);
1097 else
1098 return (NULL);
1101 BYTE* pdb_get_nt_passwd (SAM_ACCOUNT *sampass)
1103 if (sampass)
1104 return (sampass->nt_pw);
1105 else
1106 return (NULL);
1109 BYTE* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass)
1111 if (sampass)
1112 return (sampass->lm_pw);
1113 else
1114 return (NULL);
1118 uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass)
1120 if (sampass)
1121 return (sampass->user_rid);
1122 else
1123 return (-1);
1126 uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass)
1128 if (sampass)
1129 return (sampass->group_rid);
1130 else
1131 return (-1);
1134 uid_t pdb_get_uid (SAM_ACCOUNT *sampass)
1136 if (sampass)
1137 return (sampass->uid);
1138 else
1139 return ((uid_t)-1);
1142 gid_t pdb_get_gid (SAM_ACCOUNT *sampass)
1144 if (sampass)
1145 return (sampass->gid);
1146 else
1147 return ((gid_t)-1);
1150 char* pdb_get_username (SAM_ACCOUNT *sampass)
1152 if (sampass)
1153 return (sampass->username);
1154 else
1155 return (NULL);
1158 char* pdb_get_domain (SAM_ACCOUNT *sampass)
1160 if (sampass)
1161 return (sampass->domain);
1162 else
1163 return (NULL);
1166 char* pdb_get_nt_username (SAM_ACCOUNT *sampass)
1168 if (sampass)
1169 return (sampass->nt_username);
1170 else
1171 return (NULL);
1174 char* pdb_get_fullname (SAM_ACCOUNT *sampass)
1176 if (sampass)
1177 return (sampass->full_name);
1178 else
1179 return (NULL);
1182 char* pdb_get_homedir (SAM_ACCOUNT *sampass)
1184 if (sampass)
1185 return (sampass->home_dir);
1186 else
1187 return (NULL);
1190 char* pdb_get_dirdrive (SAM_ACCOUNT *sampass)
1192 if (sampass)
1193 return (sampass->dir_drive);
1194 else
1195 return (NULL);
1198 char* pdb_get_logon_script (SAM_ACCOUNT *sampass)
1200 if (sampass)
1201 return (sampass->logon_script);
1202 else
1203 return (NULL);
1206 char* pdb_get_profile_path (SAM_ACCOUNT *sampass)
1208 if (sampass)
1209 return (sampass->profile_path);
1210 else
1211 return (NULL);
1214 char* pdb_get_acct_desc (SAM_ACCOUNT *sampass)
1216 if (sampass)
1217 return (sampass->acct_desc);
1218 else
1219 return (NULL);
1222 char* pdb_get_workstations (SAM_ACCOUNT *sampass)
1224 if (sampass)
1225 return (sampass->workstations);
1226 else
1227 return (NULL);
1230 char* pdb_get_munged_dial (SAM_ACCOUNT *sampass)
1232 if (sampass)
1233 return (sampass->munged_dial);
1234 else
1235 return (NULL);
1238 uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass)
1240 if (sampass)
1241 return (sampass->unknown_3);
1242 else
1243 return (-1);
1246 uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass)
1248 if (sampass)
1249 return (sampass->unknown_5);
1250 else
1251 return (-1);
1254 uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass)
1256 if (sampass)
1257 return (sampass->unknown_6);
1258 else
1259 return (-1);
1262 /*********************************************************************
1263 collection of set...() functions for SAM_ACCOUNT_INFO
1264 ********************************************************************/
1265 BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags)
1267 if (sampass)
1269 sampass->acct_ctrl = flags;
1270 return True;
1273 return False;
1276 BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t time)
1278 if (sampass)
1280 sampass->logon_time = time;
1281 return True;
1284 return False;
1287 BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t time)
1289 if (sampass)
1291 sampass->logoff_time = time;
1292 return True;
1295 return False;
1298 BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t time)
1300 if (sampass)
1302 sampass->kickoff_time = time;
1303 return True;
1306 return False;
1309 BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t time)
1311 if (sampass)
1313 sampass->pass_can_change_time = time;
1314 return True;
1317 return False;
1320 BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t time)
1322 if (sampass)
1324 sampass->pass_must_change_time = time;
1325 return True;
1328 return False;
1331 BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t time)
1333 if (sampass)
1335 sampass->pass_last_set_time = time;
1336 return True;
1339 return False;
1342 BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len)
1344 if (sampass)
1346 sampass->hours_len = len;
1347 return True;
1350 return False;
1353 BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
1355 if (sampass)
1357 sampass->logon_divs = hours;
1358 return True;
1361 return False;
1364 BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
1366 if (sampass)
1368 sampass->uid = uid;
1369 return True;
1372 return False;
1375 BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
1377 if (sampass)
1379 sampass->gid = gid;
1380 return True;
1383 return False;
1386 BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
1388 if (sampass)
1390 sampass->user_rid = rid;
1391 return True;
1394 return False;
1397 BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
1399 if (sampass)
1401 sampass->group_rid = grid;
1402 return True;
1405 return False;
1408 BOOL pdb_set_username (SAM_ACCOUNT *sampass, char *username)
1410 if (sampass)
1412 sampass->username = strdup(username);
1413 return True;
1416 return False;
1419 BOOL pdb_set_domain (SAM_ACCOUNT *sampass, char *domain)
1421 if (sampass)
1423 sampass->username = strdup(domain);
1424 return True;
1427 return False;
1430 BOOL pdb_set_nt_username (SAM_ACCOUNT *sampass, char *nt_username)
1432 if (sampass)
1434 sampass->username = strdup(nt_username);
1435 return True;
1438 return False;
1441 BOOL pdb_set_fullname (SAM_ACCOUNT *sampass, char *fullname)
1443 if (sampass)
1445 sampass->full_name = strdup(fullname);
1446 return True;
1449 return False;
1452 BOOL pdb_set_logon_script (SAM_ACCOUNT *sampass, char *logon_script)
1454 if (sampass)
1456 sampass->logon_script = strdup(logon_script);
1457 return True;
1460 return False;
1463 BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
1465 if (sampass)
1467 sampass->profile_path = strdup(profile_path);
1468 return True;
1471 return False;
1474 BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
1476 if (sampass)
1478 sampass->dir_drive = strdup(dir_drive);
1479 return True;
1482 return False;
1485 BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
1487 if (sampass)
1489 sampass->home_dir = strdup(homedir);
1490 return True;
1493 return False;
1497 BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, BYTE *pwd)
1500 if (pwd == NULL)
1501 return False;
1503 /* allocate space for the password and make a copy of it */
1504 if (sampass)
1506 if ((sampass->nt_pw=(BYTE*)malloc(sizeof(BYTE)*16)) == NULL)
1508 DEBUG(0,("pdb_set_nt_passwd: ERROR - out of memory for nt_pw!\n"));
1509 return False;
1511 if (memcpy(sampass->nt_pw, pwd, 16))
1512 return True;
1515 return False;
1518 BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, BYTE *pwd)
1520 if (pwd == NULL)
1521 return False;
1523 /* allocate space for the password and make a copy of it */
1524 if (sampass)
1526 if ((sampass->lm_pw=(BYTE*)malloc(sizeof(BYTE)*16)) == NULL)
1528 DEBUG(0,("pdb_set_lanman_passwd: ERROR - out of memory for lm_pw!\n"));
1529 return False;
1531 if (memcpy(sampass->lm_pw, pwd, 16))
1532 return True;
1535 return False;