Another large patch for the passdb rewrite.
[Samba/gbeck.git] / source / passdb / passdb.c
blob217916bc9823c0c2cf5e1cb44b7fd4e5a71c3fb7
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;
39 struct passdb_ops *pdb_ops;
41 static void* pdb_handle = NULL;
43 /***************************************************************
44 Initialize the password db operations.
45 ***************************************************************/
46 BOOL initialize_password_db(BOOL reload)
49 char* modulename = lp_passdb_module_path();
51 return True;
53 /* load another module? */
54 if (reload && pdb_handle)
56 dlclose (pdb_handle);
57 pdb_handle = NULL;
60 /* do we have a module defined or use the default? */
61 if (strlen (modulename) != 0)
63 if ((pdb_handle=dlopen (modulename, RTLD_LAZY)) == NULL)
65 DEBUG(0,("initialize_password_db: ERROR - Unable to open passdb module \"%s\"!\n%s\n",
66 modulename, dlerror()));
68 else
69 DEBUG(1,("initialize_password_db: passdb module \"%s\" loaded successfully\n", modulename));
72 /* either no module name defined or the one that was failed
73 to open. Let's try the default */
74 if (pdb_handle == NULL)
76 if ((pdb_handle=dlopen ("libpdbfile.so", RTLD_LAZY)) == NULL)
78 DEBUG(0,("initialize_password_db: ERROR - Unable to open \"libpdbfile.so\" passdb module! No user authentication possible!\n%s\n",
79 dlerror()));
80 return False;
82 else
83 DEBUG(1,("initialize_password_db: passdb module \"libpdbfile.so\" loaded successfully\n"));
87 return (pdb_handle != NULL);
90 /*************************************************************
91 initialises a struct sam_disp_info.
92 **************************************************************/
93 static void pdb_init_dispinfo(struct sam_disp_info *user)
95 if (user == NULL)
96 return;
97 ZERO_STRUCTP(user);
100 /*************************************************************
101 initialises a struct sam_passwd.
102 ************************************************************/
103 void pdb_init_sam(SAM_ACCOUNT *user)
105 if (user == NULL)
106 return;
108 ZERO_STRUCTP(user);
110 user->logon_time = (time_t)-1;
111 user->logoff_time = (time_t)-1;
112 user->kickoff_time = (time_t)-1;
113 user->pass_last_set_time = (time_t)-1;
114 user->pass_can_change_time = (time_t)-1;
115 user->pass_must_change_time = (time_t)-1;
117 user->unknown_3 = 0x00ffffff; /* don't know */
118 user->logon_divs = 168; /* hours per week */
119 user->hours_len = 21; /* 21 times 8 bits = 168 */
120 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
121 user->unknown_5 = 0x00020000; /* don't know */
122 user->unknown_5 = 0x000004ec; /* don't know */
126 /************************************************************
127 free all pointer members and then reinit the SAM_ACCOUNT
128 ***********************************************************/
129 void pdb_clear_sam(SAM_ACCOUNT *user)
131 /* do we have a SAM_CCOUTN struct to work with? */
132 if (user == NULL)
133 return;
135 /* do we own the memory? */
136 if (user->own_memory)
138 /* clear all pointer members */
139 if (user->username) free(user->username);
140 if (user->full_name) free(user->full_name);
141 if (user->domain) free(user->domain);
142 if (user->nt_username) free(user->nt_username);
143 if (user->home_dir) free(user->home_dir);
144 if (user->dir_drive) free(user->dir_drive);
145 if (user->logon_script) free(user->logon_script);
146 if (user->profile_path) free(user->profile_path);
147 if (user->acct_desc) free(user->acct_desc);
148 if (user->workstations) free(user->workstations);
149 if (user->unknown_str) free(user->unknown_str);
150 if (user->munged_dial) free(user->munged_dial);
152 if (user->lm_pw) free(user->lm_pw);
153 if (user->nt_pw) free(user->nt_pw);
156 /* now initialize */
157 pdb_init_sam(user);
162 /*************************************************************************
163 Routine to return the next entry in the sam passwd list.
164 *************************************************************************/
165 struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
167 static struct sam_disp_info disp_info;
169 if (user == NULL)
170 return NULL;
172 pdb_init_dispinfo(&disp_info);
174 disp_info.smb_name = user->username;
175 disp_info.full_name = user->full_name;
176 disp_info.user_rid = user->user_rid;
178 return &disp_info;
182 /**********************************************************
183 Encode the account control bits into a string.
184 length = length of string to encode into (including terminating
185 null). length *MUST BE MORE THAN 2* !
186 **********************************************************/
187 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
189 static fstring acct_str;
190 size_t i = 0;
192 acct_str[i++] = '[';
194 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
195 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
196 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
197 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
198 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
199 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
200 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
201 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
202 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
203 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
204 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
206 for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
208 i = length - 2;
209 acct_str[i++] = ']';
210 acct_str[i++] = '\0';
212 return acct_str;
215 /**********************************************************
216 Decode the account control bits from a string.
218 this function breaks coding standards minimum line width of 80 chars.
219 reason: vertical line-up code clarity - all case statements fit into
220 15 lines, which is more important.
221 **********************************************************/
223 uint16 pdb_decode_acct_ctrl(const char *p)
225 uint16 acct_ctrl = 0;
226 BOOL finished = False;
229 * Check if the account type bits have been encoded after the
230 * NT password (in the form [NDHTUWSLXI]).
233 if (*p != '[') return 0;
235 for (p++; *p && !finished; p++)
237 switch (*p)
239 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
240 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
241 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
242 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
243 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
244 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
245 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
246 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
247 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
248 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
249 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
250 case ' ': { break; }
251 case ':':
252 case '\n':
253 case '\0':
254 case ']':
255 default: { finished = True; }
259 return acct_ctrl;
262 /*************************************************************
263 Routine to set 32 hex password characters from a 16 byte array.
264 **************************************************************/
265 void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
267 if (pwd != NULL) {
268 int i;
269 for (i = 0; i < 16; i++)
270 slprintf(&p[i*2], 3, "%02X", pwd[i]);
271 } else {
272 if (acct_ctrl & ACB_PWNOTREQ)
273 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
274 else
275 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
279 /*************************************************************
280 Routine to get the 32 hex characters and turn them
281 into a 16 byte array.
282 **************************************************************/
283 BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
285 int i;
286 unsigned char lonybble, hinybble;
287 char *hexchars = "0123456789ABCDEF";
288 char *p1, *p2;
290 for (i = 0; i < 32; i += 2)
292 hinybble = toupper(p[i]);
293 lonybble = toupper(p[i + 1]);
295 p1 = strchr(hexchars, hinybble);
296 p2 = strchr(hexchars, lonybble);
298 if (!p1 || !p2)
300 return (False);
303 hinybble = PTR_DIFF(p1, hexchars);
304 lonybble = PTR_DIFF(p2, hexchars);
306 pwd[i / 2] = (hinybble << 4) | lonybble;
308 return (True);
311 /*******************************************************************
312 Group and User RID username mapping function
313 ********************************************************************/
314 BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
316 struct passwd *pw = Get_Pwnam(user_name, False);
318 if (u_rid == NULL || g_rid == NULL || user_name == NULL)
320 return False;
323 if (!pw)
325 DEBUG(1,("Username %s is invalid on this system\n", user_name));
326 return False;
329 if (user_in_list(user_name, lp_domain_guest_users()))
331 *u_rid = DOMAIN_USER_RID_GUEST;
333 else if (user_in_list(user_name, lp_domain_admin_users()))
335 *u_rid = DOMAIN_USER_RID_ADMIN;
337 else
339 /* turn the unix UID into a Domain RID. this is what the posix
340 sub-system does (adds 1000 to the uid) */
341 *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
344 /* absolutely no idea what to do about the unix GID to Domain RID mapping */
345 *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
347 return True;
350 /*******************************************************************
351 Converts NT user RID to a UNIX uid.
352 ********************************************************************/
353 uid_t pdb_user_rid_to_uid(uint32 user_rid)
355 return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
358 /*******************************************************************
359 Converts NT user RID to a UNIX gid.
360 ********************************************************************/
362 gid_t pdb_user_rid_to_gid(uint32 user_rid)
364 return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
367 /*******************************************************************
368 converts UNIX uid to an NT User RID.
369 ********************************************************************/
371 uint32 pdb_uid_to_user_rid(uid_t uid)
373 return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
376 /*******************************************************************
377 converts NT Group RID to a UNIX uid.
378 ********************************************************************/
380 uint32 pdb_gid_to_group_rid(gid_t gid)
382 return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
385 /*******************************************************************
386 Decides if a RID is a well known RID.
387 ********************************************************************/
389 static BOOL pdb_rid_is_well_known(uint32 rid)
391 return (rid < 1000);
394 /*******************************************************************
395 Decides if a RID is a user or group RID.
396 ********************************************************************/
397 BOOL pdb_rid_is_user(uint32 rid)
399 /* lkcl i understand that NT attaches an enumeration to a RID
400 * such that it can be identified as either a user, group etc
401 * type. there are 5 such categories, and they are documented.
403 if(pdb_rid_is_well_known(rid)) {
405 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
406 * and DOMAIN_USER_RID_GUEST.
408 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
409 return True;
410 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
411 return True;
413 return False;
416 /*******************************************************************
417 Convert a rid into a name. Used in the lookup SID rpc.
418 ********************************************************************/
419 BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
422 BOOL is_user = pdb_rid_is_user(rid);
424 DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
425 "group", (unsigned int)rid));
427 if(is_user) {
428 if(rid == DOMAIN_USER_RID_ADMIN) {
429 pstring admin_users;
430 char *p = admin_users;
431 pstrcpy( admin_users, lp_domain_admin_users());
432 if(!next_token(&p, name, NULL, sizeof(fstring)))
433 fstrcpy(name, "Administrator");
434 } else if (rid == DOMAIN_USER_RID_GUEST) {
435 pstring guest_users;
436 char *p = guest_users;
437 pstrcpy( guest_users, lp_domain_guest_users());
438 if(!next_token(&p, name, NULL, sizeof(fstring)))
439 fstrcpy(name, "Guest");
440 } else {
441 uid_t uid = pdb_user_rid_to_uid(rid);
442 struct passwd *pass = sys_getpwuid(uid);
444 *psid_name_use = SID_NAME_USER;
446 DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
447 pass ? "succeeded" : "failed" ));
449 if(!pass) {
450 slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
451 return True;
454 fstrcpy(name, pass->pw_name);
456 DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
457 (unsigned int)rid ));
460 } else {
461 gid_t gid = pdb_user_rid_to_gid(rid);
462 struct group *gr = getgrgid(gid);
464 *psid_name_use = SID_NAME_ALIAS;
466 DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
467 gr ? "succeeded" : "failed" ));
469 if(!gr) {
470 slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
471 return True;
474 fstrcpy( name, gr->gr_name);
476 DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
477 (unsigned int)rid ));
480 return True;
483 /*******************************************************************
484 Convert a name into a SID. Used in the lookup name rpc.
485 ********************************************************************/
487 BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
489 extern DOM_SID global_sid_World_Domain;
490 struct passwd *pass = NULL;
491 DOM_SID local_sid;
493 sid_copy(&local_sid, &global_sam_sid);
495 if(!strequal(global_myname, domain) && !strequal(global_myworkgroup, domain))
496 return False;
499 * Special case for MACHINE\Everyone. Map to the world_sid.
502 if(strequal(user, "Everyone")) {
503 sid_copy( psid, &global_sid_World_Domain);
504 sid_append_rid(psid, 0);
505 *psid_name_use = SID_NAME_ALIAS;
506 return True;
509 (void)map_username(user);
511 if(!(pass = Get_Pwnam(user, False))) {
513 * Maybe it was a group ?
515 struct group *grp = getgrnam(user);
517 if(!grp)
518 return False;
520 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
521 *psid_name_use = SID_NAME_ALIAS;
522 } else {
524 sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
525 *psid_name_use = SID_NAME_USER;
528 sid_copy( psid, &local_sid);
530 return True;
533 /****************************************************************************
534 Convert a uid to SID - locally.
535 ****************************************************************************/
536 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
538 extern DOM_SID global_sam_sid;
540 sid_copy(psid, &global_sam_sid);
541 sid_append_rid(psid, pdb_uid_to_user_rid(uid));
543 return psid;
547 /****************************************************************************
548 Convert a SID to uid - locally.
549 ****************************************************************************/
550 BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
552 extern DOM_SID global_sam_sid;
554 DOM_SID dom_sid;
555 uint32 rid;
557 *name_type = SID_NAME_UNKNOWN;
559 sid_copy(&dom_sid, psid);
560 sid_split_rid(&dom_sid, &rid);
563 * We can only convert to a uid if this is our local
564 * Domain SID (ie. we are the controling authority).
566 if (!sid_equal(&global_sam_sid, &dom_sid))
567 return False;
569 *puid = pdb_user_rid_to_uid(rid);
572 * Ensure this uid really does exist.
574 if(!sys_getpwuid(*puid))
575 return False;
577 return True;
580 /****************************************************************************
581 Convert a gid to SID - locally.
582 ****************************************************************************/
583 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
585 extern DOM_SID global_sam_sid;
587 sid_copy(psid, &global_sam_sid);
588 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
590 return psid;
593 /****************************************************************************
594 Convert a SID to gid - locally.
595 ****************************************************************************/
596 BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
598 extern DOM_SID global_sam_sid;
599 DOM_SID dom_sid;
600 uint32 rid;
602 *name_type = SID_NAME_UNKNOWN;
604 sid_copy(&dom_sid, psid);
605 sid_split_rid(&dom_sid, &rid);
608 * We can only convert to a gid if this is our local
609 * Domain SID (ie. we are the controling authority).
612 if (!sid_equal(&global_sam_sid, &dom_sid))
613 return False;
615 *pgid = pdb_user_rid_to_gid(rid);
618 * Ensure this gid really does exist.
621 if(!getgrgid(*pgid))
622 return False;
624 return True;
627 static void select_name(fstring *string, char **name, const UNISTR2 *from)
629 if (from->buffer != 0)
631 unistr2_to_ascii(*string, from, sizeof(*string));
632 *name = *string;
636 /*************************************************************
637 copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
638 **************************************************************/
639 void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
641 static fstring smb_name;
642 static fstring full_name;
643 static fstring home_dir;
644 static fstring dir_drive;
645 static fstring logon_script;
646 static fstring profile_path;
647 static fstring acct_desc;
648 static fstring workstations;
649 static fstring unknown_str;
650 static fstring munged_dial;
652 if (from == NULL || to == NULL)
653 return;
655 to->logon_time = nt_time_to_unix(&from->logon_time);
656 to->logoff_time = nt_time_to_unix(&from->logoff_time);
657 to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
658 to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
659 to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
660 to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
662 select_name(&smb_name , &to->username , &from->uni_user_name );
663 select_name(&full_name , &to->full_name , &from->uni_full_name );
664 select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
665 select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
666 select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
667 select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
668 select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
669 select_name(&workstations, &to->workstations, &from->uni_workstations);
670 select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
671 select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
673 to->user_rid = from->user_rid;
674 to->group_rid = from->group_rid;
676 to->acct_ctrl = from->acb_info;
677 to->unknown_3 = from->unknown_3;
679 to->logon_divs = from->logon_divs;
680 to->hours_len = from->logon_hrs.len;
681 memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
683 to->unknown_5 = from->unknown_5;
684 to->unknown_6 = from->unknown_6;
687 /*************************************************************
688 copies a sam passwd.
689 **************************************************************/
690 void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
692 static fstring smb_name;
693 static fstring full_name;
694 static fstring home_dir;
695 static fstring dir_drive;
696 static fstring logon_script;
697 static fstring profile_path;
698 static fstring acct_desc;
699 static fstring workstations;
700 static fstring unknown_str;
701 static fstring munged_dial;
703 if (from == NULL || to == NULL)
704 return;
706 to->logon_time = nt_time_to_unix(&from->logon_time);
707 to->logoff_time = nt_time_to_unix(&from->logoff_time);
708 to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
709 to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
710 to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
711 to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
713 select_name(&smb_name , &to->username , &from->uni_user_name );
714 select_name(&full_name , &to->full_name , &from->uni_full_name );
715 select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
716 select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
717 select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
718 select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
719 select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
720 select_name(&workstations, &to->workstations, &from->uni_workstations);
721 select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
722 select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
724 to->user_rid = from->user_rid;
725 to->group_rid = from->group_rid;
727 /* FIXME!! Do we need to copy the passwords here as well?
728 I don't know. Need to figure this out --jerry */
730 to->acct_ctrl = from->acb_info;
731 to->unknown_3 = from->unknown_3;
733 to->logon_divs = from->logon_divs;
734 to->hours_len = from->logon_hrs.len;
735 memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
737 to->unknown_5 = from->unknown_5;
738 to->unknown_6 = from->unknown_6;
742 /*************************************************************
743 copies a sam passwd.
744 **************************************************************/
745 void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
747 static fstring smb_name="";
748 static fstring full_name="";
749 static fstring home_dir="";
750 static fstring dir_drive="";
751 static fstring logon_script="";
752 static fstring profile_path="";
753 static fstring acct_desc="";
754 static fstring workstations="";
755 static fstring unknown_str="";
756 static fstring munged_dial="";
757 static BYTE lm_pw[16], nt_pw[16];
759 if (from == NULL || to == NULL)
760 return;
762 /* we won't own this memory so set the flag.
763 This will also clear the strings from 'to' */
764 pdb_set_mem_ownership (to, False);
766 memcpy(to, from, sizeof(*from));
768 if (from->username != NULL)
770 fstrcpy(smb_name , from->username);
771 to->username = smb_name;
774 if (from->full_name != NULL)
776 fstrcpy(full_name, from->full_name);
777 to->full_name = full_name;
780 if (from->home_dir != NULL)
782 fstrcpy(home_dir, from->home_dir);
783 to->home_dir = home_dir;
786 if (from->dir_drive != NULL)
788 fstrcpy(dir_drive , from->dir_drive);
789 to->dir_drive = dir_drive;
792 if (from->logon_script != NULL)
794 fstrcpy(logon_script , from->logon_script);
795 to->logon_script = logon_script;
798 if (from->profile_path != NULL)
800 fstrcpy(profile_path , from->profile_path);
801 to->profile_path = profile_path;
804 if (from->acct_desc != NULL)
806 fstrcpy(acct_desc , from->acct_desc);
807 to->acct_desc = acct_desc;
810 if (from->workstations != NULL)
812 fstrcpy(workstations , from->workstations);
813 to->workstations = workstations;
816 if (from->unknown_str != NULL)
818 fstrcpy(unknown_str , from->unknown_str);
819 to->unknown_str = unknown_str;
822 if (from->munged_dial != NULL)
824 fstrcpy(munged_dial , from->munged_dial);
825 to->munged_dial = munged_dial;
828 if (from->nt_pw != NULL)
830 memcpy (nt_pw, from->nt_pw, 16);
831 to->nt_pw = nt_pw;
834 if (from->lm_pw != NULL)
836 memcpy (lm_pw, from->lm_pw, 16);
837 to->lm_pw = lm_pw;
840 return;
843 /*************************************************************
844 change a password entry in the local smbpasswd file
846 FIXME!! The function needs to be abstracted into the
847 passdb interface or something. It is currently being called
848 by _api_samr_create_user() in rpc_server/srv_samr.c
850 --jerry
851 *************************************************************/
853 BOOL local_password_change(char *user_name, int local_flags,
854 char *new_passwd,
855 char *err_str, size_t err_str_len,
856 char *msg_str, size_t msg_str_len)
858 struct passwd *pwd = NULL;
859 SAM_ACCOUNT *sam_pass;
860 SAM_ACCOUNT new_sam_acct;
861 uchar new_p16[16];
862 uchar new_nt_p16[16];
864 *err_str = '\0';
865 *msg_str = '\0';
867 if (local_flags & LOCAL_ADD_USER) {
870 * Check for a local account - if we're adding only.
873 if(!(pwd = sys_getpwnam(user_name))) {
874 slprintf(err_str, err_str_len - 1, "User %s does not \
875 exist in system password file (usually /etc/passwd). Cannot add \
876 account without a valid local system user.\n", user_name);
877 return False;
881 /* Calculate the MD4 hash (NT compatible) of the new password. */
882 nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
884 /* Get the smb passwd entry for this user */
885 sam_pass = pdb_getsampwnam(user_name);
886 if (sam_pass == NULL)
888 if(!(local_flags & LOCAL_ADD_USER))
890 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
891 return False;
894 /* create the SAM_ACCOUNT struct and call pdb_add_sam_account.
895 Because the new_sam_pwd only exists in the scope of this function
896 we will not allocate memory for members */
897 pdb_init_sam (&new_sam_acct);
898 pdb_set_mem_ownership (&new_sam_acct, False);
899 pdb_set_username (&new_sam_acct, user_name);
900 pdb_set_uid (&new_sam_acct, pwd->pw_uid);
901 pdb_set_pass_last_set_time(&new_sam_acct, time(NULL));
903 /* set account flags */
904 pdb_set_acct_ctrl(&new_sam_acct,((local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL) );
905 if (local_flags & LOCAL_DISABLE_USER)
907 pdb_set_acct_ctrl (&new_sam_acct, pdb_get_acct_ctrl(&new_sam_acct)|ACB_DISABLED);
909 if (local_flags & LOCAL_SET_NO_PASSWORD)
911 pdb_set_acct_ctrl (&new_sam_acct, pdb_get_acct_ctrl(&new_sam_acct)|ACB_PWNOTREQ);
913 else
915 /* set the passwords here. if we get to here it means
916 we have a valid, active account */
917 pdb_set_lanman_passwd (&new_sam_acct, new_p16);
918 pdb_set_nt_passwd (&new_sam_acct, new_nt_p16);
922 if (pdb_add_sam_account(&new_sam_acct))
924 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
925 pdb_clear_sam (&new_sam_acct);
926 return True;
928 else
930 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
931 return False;
934 else
936 /* the entry already existed */
937 local_flags &= ~LOCAL_ADD_USER;
941 * We are root - just write the new password
942 * and the valid last change time.
945 if(local_flags & LOCAL_DISABLE_USER)
947 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
949 else if (local_flags & LOCAL_ENABLE_USER)
951 if(pdb_get_lanman_passwd(sam_pass) == NULL)
953 pdb_set_lanman_passwd (sam_pass, new_p16);
954 pdb_set_nt_passwd (sam_pass, new_nt_p16);
956 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
957 } else if (local_flags & LOCAL_SET_NO_PASSWORD)
959 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
961 /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
962 pdb_set_lanman_passwd (sam_pass, NULL);
963 pdb_set_nt_passwd (sam_pass, NULL);
965 else
968 * If we're dealing with setting a completely empty user account
969 * ie. One with a password of 'XXXX', but not set disabled (like
970 * an account created from scratch) then if the old password was
971 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
972 * We remove that as we're giving this user their first password
973 * and the decision hasn't really been made to disable them (ie.
974 * don't create them disabled). JRA.
976 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED))
977 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
978 pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ));
979 pdb_set_lanman_passwd (sam_pass, new_p16);
980 pdb_set_nt_passwd (sam_pass, new_nt_p16);
983 if(local_flags & LOCAL_DELETE_USER)
985 if (!pdb_delete_sam_account(user_name))
987 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
988 return False;
990 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
992 else
994 if(!pdb_update_sam_account(sam_pass, True))
996 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
997 return False;
999 if(local_flags & LOCAL_DISABLE_USER)
1000 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1001 else if (local_flags & LOCAL_ENABLE_USER)
1002 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1003 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1004 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1007 return True;
1011 /*********************************************************************
1012 collection of get...() functions for SAM_ACCOUNT_INFO
1013 ********************************************************************/
1014 uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass)
1016 if (sampass)
1017 return (sampass->acct_ctrl);
1018 else
1019 return (ACB_DISABLED);
1022 time_t pdb_get_logon_time (SAM_ACCOUNT *sampass)
1024 if (sampass)
1025 return (sampass->logon_time);
1026 else
1027 return (-1);
1030 time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass)
1032 if (sampass)
1033 return (sampass->logoff_time);
1034 else
1035 return (-1);
1038 time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass)
1040 if (sampass)
1041 return (sampass->kickoff_time);
1042 else
1043 return (-1);
1046 time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass)
1048 if (sampass)
1049 return (sampass->pass_last_set_time);
1050 else
1051 return (-1);
1054 time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass)
1056 if (sampass)
1057 return (sampass->pass_can_change_time);
1058 else
1059 return (-1);
1062 time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass)
1064 if (sampass)
1065 return (sampass->pass_must_change_time);
1066 else
1067 return (-1);
1070 uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass)
1072 if (sampass)
1073 return (sampass->logon_divs);
1074 else
1075 return (-1);
1078 uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass)
1080 if (sampass)
1081 return (sampass->hours_len);
1082 else
1083 return (-1);
1086 uint8* pdb_get_hours (SAM_ACCOUNT *sampass)
1088 if (sampass)
1089 return (sampass->hours);
1090 else
1091 return (NULL);
1094 BYTE* pdb_get_nt_passwd (SAM_ACCOUNT *sampass)
1096 if (sampass)
1097 return (sampass->nt_pw);
1098 else
1099 return (NULL);
1102 BYTE* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass)
1104 if (sampass)
1105 return (sampass->lm_pw);
1106 else
1107 return (NULL);
1111 uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass)
1113 if (sampass)
1114 return (sampass->user_rid);
1115 else
1116 return (-1);
1119 uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass)
1121 if (sampass)
1122 return (sampass->group_rid);
1123 else
1124 return (-1);
1127 uid_t pdb_get_uid (SAM_ACCOUNT *sampass)
1129 if (sampass)
1130 return (sampass->uid);
1131 else
1132 return ((uid_t)-1);
1135 gid_t pdb_get_gid (SAM_ACCOUNT *sampass)
1137 if (sampass)
1138 return (sampass->gid);
1139 else
1140 return ((gid_t)-1);
1143 char* pdb_get_username (SAM_ACCOUNT *sampass)
1145 if (sampass)
1146 return (sampass->username);
1147 else
1148 return (NULL);
1151 char* pdb_get_domain (SAM_ACCOUNT *sampass)
1153 if (sampass)
1154 return (sampass->domain);
1155 else
1156 return (NULL);
1159 char* pdb_get_nt_username (SAM_ACCOUNT *sampass)
1161 if (sampass)
1162 return (sampass->nt_username);
1163 else
1164 return (NULL);
1167 char* pdb_get_fullname (SAM_ACCOUNT *sampass)
1169 if (sampass)
1170 return (sampass->full_name);
1171 else
1172 return (NULL);
1175 char* pdb_get_homedir (SAM_ACCOUNT *sampass)
1177 if (sampass)
1178 return (sampass->home_dir);
1179 else
1180 return (NULL);
1183 char* pdb_get_dirdrive (SAM_ACCOUNT *sampass)
1185 if (sampass)
1186 return (sampass->dir_drive);
1187 else
1188 return (NULL);
1191 char* pdb_get_logon_script (SAM_ACCOUNT *sampass)
1193 if (sampass)
1194 return (sampass->logon_script);
1195 else
1196 return (NULL);
1199 char* pdb_get_profile_path (SAM_ACCOUNT *sampass)
1201 if (sampass)
1202 return (sampass->profile_path);
1203 else
1204 return (NULL);
1207 char* pdb_get_acct_desc (SAM_ACCOUNT *sampass)
1209 if (sampass)
1210 return (sampass->acct_desc);
1211 else
1212 return (NULL);
1215 char* pdb_get_workstations (SAM_ACCOUNT *sampass)
1217 if (sampass)
1218 return (sampass->workstations);
1219 else
1220 return (NULL);
1223 char* pdb_get_munged_dial (SAM_ACCOUNT *sampass)
1225 if (sampass)
1226 return (sampass->munged_dial);
1227 else
1228 return (NULL);
1231 uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass)
1233 if (sampass)
1234 return (sampass->unknown_3);
1235 else
1236 return (-1);
1239 uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass)
1241 if (sampass)
1242 return (sampass->unknown_5);
1243 else
1244 return (-1);
1247 uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass)
1249 if (sampass)
1250 return (sampass->unknown_6);
1251 else
1252 return (-1);
1255 /*********************************************************************
1256 collection of set...() functions for SAM_ACCOUNT_INFO
1257 ********************************************************************/
1259 /********************************************************************
1260 The purpose of this flag is to determine whether or not we
1261 should free the memory when we are done. This allows us to
1262 use local static variables for string (reduce the number of
1263 malloc() calls) while still allowing for flexibility of
1264 dynamic objects.
1266 We always clear the structure even if setting the flag to the
1267 same value.
1268 *******************************************************************/
1269 void pdb_set_mem_ownership (SAM_ACCOUNT *sampass, BOOL flag)
1271 /* if we have no SAM_ACCOUNT struct or no change, then done */
1272 if (sampass == NULL)
1273 return;
1275 /* clear the struct and set the ownership flag */
1276 pdb_clear_sam (sampass);
1277 sampass->own_memory = flag;
1279 return;
1282 BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags)
1284 if (!sampass)
1285 return False;
1287 if (sampass)
1289 sampass->acct_ctrl = flags;
1290 return True;
1293 return False;
1296 BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime)
1298 if (!sampass)
1299 return False;
1301 sampass->logon_time = mytime;
1302 return True;
1305 BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime)
1307 if (!sampass)
1308 return False;
1310 sampass->logoff_time = mytime;
1311 return True;
1314 BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime)
1316 if (!sampass)
1317 return False;
1319 sampass->kickoff_time = mytime;
1320 return True;
1323 BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime)
1325 if (!sampass)
1326 return False;
1328 sampass->pass_can_change_time = mytime;
1329 return True;
1332 BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime)
1334 if (!sampass)
1335 return False;
1337 sampass->pass_must_change_time = mytime;
1338 return True;
1341 BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime)
1343 if (!sampass)
1344 return False;
1346 sampass->pass_last_set_time = mytime;
1347 return True;
1350 BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len)
1352 if (!sampass)
1353 return False;
1355 sampass->hours_len = len;
1356 return True;
1359 BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
1361 if (!sampass)
1362 return False;
1364 sampass->logon_divs = hours;
1365 return True;
1368 BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
1370 if (!sampass)
1371 return False;
1373 sampass->uid = uid;
1374 return True;
1377 BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
1379 if (!sampass)
1380 return False;
1382 sampass->gid = gid;
1383 return True;
1386 BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
1388 if (!sampass)
1389 return False;
1391 sampass->user_rid = rid;
1392 return True;
1395 BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
1397 if (!sampass)
1398 return False;
1400 sampass->group_rid = grid;
1401 return True;
1404 BOOL pdb_set_username (SAM_ACCOUNT *sampass, char *username)
1406 if (!sampass)
1407 return False;
1409 if (!sampass->own_memory)
1410 sampass->username = username;
1411 else
1413 if ( (sampass->username=strdup(username)) == NULL )
1415 DEBUG (0,("pdb_set_username: ERROR - Unable to malloc memory for [%s]\n", username));
1416 return False;
1420 return True;
1423 BOOL pdb_set_domain (SAM_ACCOUNT *sampass, char *domain)
1425 if (!sampass)
1426 return False;
1428 if (!sampass->own_memory)
1429 sampass->domain = domain;
1430 else
1432 if ( (sampass->domain=strdup(domain)) == NULL )
1434 DEBUG (0,("pdb_set_domain: ERROR - Unable to malloc memory for [%s]\n", domain));
1435 return False;
1439 return True;
1442 BOOL pdb_set_nt_username (SAM_ACCOUNT *sampass, char *nt_username)
1444 if (!sampass)
1445 return False;
1447 if (!sampass->own_memory)
1448 sampass->nt_username = nt_username;
1449 else
1451 if ( (sampass->nt_username=strdup(nt_username)) == NULL )
1453 DEBUG (0,("pdb_set_nt_username: ERROR - Unable to malloc memory for [%s]\n", nt_username));
1454 return False;
1458 return True;
1461 BOOL pdb_set_fullname (SAM_ACCOUNT *sampass, char *fullname)
1463 if (!sampass)
1464 return False;
1466 if (!sampass->own_memory)
1467 sampass->full_name = fullname;
1468 else
1470 if ( (sampass->full_name=strdup(fullname)) == NULL )
1472 DEBUG (0,("pdb_set_fullname: ERROR - Unable to malloc memory for [%s]\n", fullname));
1473 return False;
1477 return True;
1480 BOOL pdb_set_logon_script (SAM_ACCOUNT *sampass, char *logon_script)
1482 if (!sampass)
1483 return False;
1485 if (!sampass->own_memory)
1486 sampass->logon_script = logon_script;
1487 else
1489 if ( (sampass->logon_script=strdup(logon_script)) == NULL )
1491 DEBUG (0,("pdb_set_logon_script: ERROR - Unable to malloc memory for [%s]\n", logon_script));
1492 return False;
1496 return True;
1499 BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
1501 if (!sampass)
1502 return False;
1504 if (!sampass->own_memory)
1505 sampass->profile_path = profile_path;
1506 else
1508 if ( (sampass->profile_path=strdup(profile_path)) == NULL )
1510 DEBUG (0,("pdb_set_profile_path: ERROR - Unable to malloc memory for [%s]\n", profile_path));
1511 return False;
1515 return True;
1518 BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
1520 if (!sampass)
1521 return False;
1523 if (!sampass->own_memory)
1524 sampass->dir_drive = dir_drive;
1525 else
1527 if ( (sampass->dir_drive=strdup(dir_drive)) == NULL )
1529 DEBUG (0,("pdb_set_dir_drive: ERROR - Unable to malloc memory for [%s]\n", dir_drive));
1530 return False;
1534 return True;
1537 BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
1539 if (!sampass)
1540 return False;
1542 if (!sampass->own_memory)
1543 sampass->home_dir = homedir;
1544 else
1546 if ( (sampass->home_dir=strdup(homedir)) == NULL )
1548 DEBUG (0,("pdb_set_home_dir: ERROR - Unable to malloc memory for [%s]\n", homedir));
1549 return False;
1553 return True;
1556 BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
1558 if (!sampass)
1559 return False;
1561 if (!sampass->own_memory)
1562 sampass->acct_desc = acct_desc;
1563 else
1565 if ( (sampass->acct_desc=strdup(acct_desc)) == NULL )
1567 DEBUG (0,("pdb_set_acct_desc: ERROR - Unable to malloc memory for [%s]\n", acct_desc));
1568 return False;
1572 return True;
1574 BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
1576 if (!sampass)
1577 return False;
1579 if (!sampass->own_memory)
1580 sampass->workstations = workstations;
1581 else
1583 if ( (sampass->workstations=strdup(workstations)) == NULL )
1585 DEBUG (0,("pdb_set_workstations: ERROR - Unable to malloc memory for [%s]\n", workstations));
1586 return False;
1590 return True;
1593 BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
1595 if (!sampass)
1596 return False;
1598 if (!sampass->own_memory)
1599 sampass->munged_dial = munged_dial;
1600 else
1602 if ( (sampass->munged_dial=strdup(munged_dial)) == NULL )
1604 DEBUG (0,("pdb_set_munged_dial: ERROR - Unable to malloc memory for [%s]\n", munged_dial));
1605 return False;
1609 return True;
1612 BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, BYTE *pwd)
1614 if ( (!sampass) ||(pwd == NULL) )
1615 return False;
1617 if (!sampass->own_memory)
1618 sampass->nt_pw = pwd;
1619 else
1621 if ((sampass->nt_pw=(BYTE*)malloc(sizeof(BYTE)*16)) == NULL)
1623 DEBUG(0,("pdb_set_nt_passwd: ERROR - out of memory for nt_pw!\n"));
1624 return False;
1626 if (!memcpy(sampass->nt_pw, pwd, 16))
1627 return False;
1630 return True;
1633 BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, BYTE *pwd)
1635 if ( (!sampass) ||(pwd == NULL) )
1636 return False;
1638 if (!sampass->own_memory)
1639 sampass->lm_pw = pwd;
1640 else
1642 if ((sampass->lm_pw=(BYTE*)malloc(sizeof(BYTE)*16)) == NULL)
1644 DEBUG(0,("pdb_set_lanman_passwd: ERROR - out of memory for lm_pw!\n"));
1645 return False;
1647 if (!memcpy(sampass->lm_pw, pwd, 16))
1648 return False;
1651 return True;