2 Unix SMB/Netbios implementation.
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.
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
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();
53 /* load another module? */
54 if (reload
&& pdb_handle
)
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()));
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",
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
)
100 /*************************************************************
101 initialises a struct sam_passwd.
102 ************************************************************/
103 void pdb_init_sam(SAM_ACCOUNT
*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? */
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
);
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
;
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
;
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
;
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
] = ' '; }
210 acct_str
[i
++] = '\0';
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
++)
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. */ }
255 default: { finished
= True
; }
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
)
269 for (i
= 0; i
< 16; i
++)
270 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
272 if (acct_ctrl
& ACB_PWNOTREQ
)
273 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
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
)
286 unsigned char lonybble
, hinybble
;
287 char *hexchars
= "0123456789ABCDEF";
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
);
303 hinybble
= PTR_DIFF(p1
, hexchars
);
304 lonybble
= PTR_DIFF(p2
, hexchars
);
306 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
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
)
325 DEBUG(1,("Username %s is invalid on this system\n", user_name
));
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
;
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
);
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
)
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
)
410 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
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
));
428 if(rid
== DOMAIN_USER_RID_ADMIN
) {
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
) {
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");
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" ));
450 slprintf(name
, sizeof(fstring
)-1, "unix_user.%u", (unsigned int)uid
);
454 fstrcpy(name
, pass
->pw_name
);
456 DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name
,
457 (unsigned int)rid
));
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" ));
470 slprintf(name
, sizeof(fstring
)-1, "unix_group.%u", (unsigned int)gid
);
474 fstrcpy( name
, gr
->gr_name
);
476 DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name
,
477 (unsigned int)rid
));
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
;
493 sid_copy(&local_sid
, &global_sam_sid
);
495 if(!strequal(global_myname
, domain
) && !strequal(global_myworkgroup
, domain
))
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
;
509 (void)map_username(user
);
511 if(!(pass
= Get_Pwnam(user
, False
))) {
513 * Maybe it was a group ?
515 struct group
*grp
= getgrnam(user
);
520 sid_append_rid( &local_sid
, pdb_gid_to_group_rid(grp
->gr_gid
));
521 *psid_name_use
= SID_NAME_ALIAS
;
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
);
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
));
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
;
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
))
569 *puid
= pdb_user_rid_to_uid(rid
);
572 * Ensure this uid really does exist.
574 if(!sys_getpwuid(*puid
))
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
));
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
;
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
))
615 *pgid
= pdb_user_rid_to_gid(rid
);
618 * Ensure this gid really does exist.
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
));
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
)
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 /*************************************************************
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
)
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 /*************************************************************
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
)
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);
834 if (from
->lm_pw
!= NULL
)
836 memcpy (lm_pw
, from
->lm_pw
, 16);
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
851 *************************************************************/
853 BOOL
local_password_change(char *user_name
, int local_flags
,
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
;
862 uchar new_nt_p16
[16];
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
);
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
);
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
);
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
);
930 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
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
);
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
);
990 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
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
);
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
);
1011 /*********************************************************************
1012 collection of get...() functions for SAM_ACCOUNT_INFO
1013 ********************************************************************/
1014 uint16
pdb_get_acct_ctrl (SAM_ACCOUNT
*sampass
)
1017 return (sampass
->acct_ctrl
);
1019 return (ACB_DISABLED
);
1022 time_t pdb_get_logon_time (SAM_ACCOUNT
*sampass
)
1025 return (sampass
->logon_time
);
1030 time_t pdb_get_logoff_time (SAM_ACCOUNT
*sampass
)
1033 return (sampass
->logoff_time
);
1038 time_t pdb_get_kickoff_time (SAM_ACCOUNT
*sampass
)
1041 return (sampass
->kickoff_time
);
1046 time_t pdb_get_pass_last_set_time (SAM_ACCOUNT
*sampass
)
1049 return (sampass
->pass_last_set_time
);
1054 time_t pdb_get_pass_can_change_time (SAM_ACCOUNT
*sampass
)
1057 return (sampass
->pass_can_change_time
);
1062 time_t pdb_get_pass_must_change_time (SAM_ACCOUNT
*sampass
)
1065 return (sampass
->pass_must_change_time
);
1070 uint16
pdb_get_logon_divs (SAM_ACCOUNT
*sampass
)
1073 return (sampass
->logon_divs
);
1078 uint32
pdb_get_hours_len (SAM_ACCOUNT
*sampass
)
1081 return (sampass
->hours_len
);
1086 uint8
* pdb_get_hours (SAM_ACCOUNT
*sampass
)
1089 return (sampass
->hours
);
1094 BYTE
* pdb_get_nt_passwd (SAM_ACCOUNT
*sampass
)
1097 return (sampass
->nt_pw
);
1102 BYTE
* pdb_get_lanman_passwd (SAM_ACCOUNT
*sampass
)
1105 return (sampass
->lm_pw
);
1111 uint32
pdb_get_user_rid (SAM_ACCOUNT
*sampass
)
1114 return (sampass
->user_rid
);
1119 uint32
pdb_get_group_rid (SAM_ACCOUNT
*sampass
)
1122 return (sampass
->group_rid
);
1127 uid_t
pdb_get_uid (SAM_ACCOUNT
*sampass
)
1130 return (sampass
->uid
);
1135 gid_t
pdb_get_gid (SAM_ACCOUNT
*sampass
)
1138 return (sampass
->gid
);
1143 char* pdb_get_username (SAM_ACCOUNT
*sampass
)
1146 return (sampass
->username
);
1151 char* pdb_get_domain (SAM_ACCOUNT
*sampass
)
1154 return (sampass
->domain
);
1159 char* pdb_get_nt_username (SAM_ACCOUNT
*sampass
)
1162 return (sampass
->nt_username
);
1167 char* pdb_get_fullname (SAM_ACCOUNT
*sampass
)
1170 return (sampass
->full_name
);
1175 char* pdb_get_homedir (SAM_ACCOUNT
*sampass
)
1178 return (sampass
->home_dir
);
1183 char* pdb_get_dirdrive (SAM_ACCOUNT
*sampass
)
1186 return (sampass
->dir_drive
);
1191 char* pdb_get_logon_script (SAM_ACCOUNT
*sampass
)
1194 return (sampass
->logon_script
);
1199 char* pdb_get_profile_path (SAM_ACCOUNT
*sampass
)
1202 return (sampass
->profile_path
);
1207 char* pdb_get_acct_desc (SAM_ACCOUNT
*sampass
)
1210 return (sampass
->acct_desc
);
1215 char* pdb_get_workstations (SAM_ACCOUNT
*sampass
)
1218 return (sampass
->workstations
);
1223 char* pdb_get_munged_dial (SAM_ACCOUNT
*sampass
)
1226 return (sampass
->munged_dial
);
1231 uint32
pdb_get_unknown3 (SAM_ACCOUNT
*sampass
)
1234 return (sampass
->unknown_3
);
1239 uint32
pdb_get_unknown5 (SAM_ACCOUNT
*sampass
)
1242 return (sampass
->unknown_5
);
1247 uint32
pdb_get_unknown6 (SAM_ACCOUNT
*sampass
)
1250 return (sampass
->unknown_6
);
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
1266 We always clear the structure even if setting the flag to the
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
)
1275 /* clear the struct and set the ownership flag */
1276 pdb_clear_sam (sampass
);
1277 sampass
->own_memory
= flag
;
1282 BOOL
pdb_set_acct_ctrl (SAM_ACCOUNT
*sampass
, uint16 flags
)
1289 sampass
->acct_ctrl
= flags
;
1296 BOOL
pdb_set_logon_time (SAM_ACCOUNT
*sampass
, time_t mytime
)
1301 sampass
->logon_time
= mytime
;
1305 BOOL
pdb_set_logoff_time (SAM_ACCOUNT
*sampass
, time_t mytime
)
1310 sampass
->logoff_time
= mytime
;
1314 BOOL
pdb_set_kickoff_time (SAM_ACCOUNT
*sampass
, time_t mytime
)
1319 sampass
->kickoff_time
= mytime
;
1323 BOOL
pdb_set_pass_can_change_time (SAM_ACCOUNT
*sampass
, time_t mytime
)
1328 sampass
->pass_can_change_time
= mytime
;
1332 BOOL
pdb_set_pass_must_change_time (SAM_ACCOUNT
*sampass
, time_t mytime
)
1337 sampass
->pass_must_change_time
= mytime
;
1341 BOOL
pdb_set_pass_last_set_time (SAM_ACCOUNT
*sampass
, time_t mytime
)
1346 sampass
->pass_last_set_time
= mytime
;
1350 BOOL
pdb_set_hours_len (SAM_ACCOUNT
*sampass
, uint32 len
)
1355 sampass
->hours_len
= len
;
1359 BOOL
pdb_set_logons_divs (SAM_ACCOUNT
*sampass
, uint16 hours
)
1364 sampass
->logon_divs
= hours
;
1368 BOOL
pdb_set_uid (SAM_ACCOUNT
*sampass
, uid_t uid
)
1377 BOOL
pdb_set_gid (SAM_ACCOUNT
*sampass
, gid_t gid
)
1386 BOOL
pdb_set_user_rid (SAM_ACCOUNT
*sampass
, uint32 rid
)
1391 sampass
->user_rid
= rid
;
1395 BOOL
pdb_set_group_rid (SAM_ACCOUNT
*sampass
, uint32 grid
)
1400 sampass
->group_rid
= grid
;
1404 BOOL
pdb_set_username (SAM_ACCOUNT
*sampass
, char *username
)
1409 if (!sampass
->own_memory
)
1410 sampass
->username
= username
;
1413 if ( (sampass
->username
=strdup(username
)) == NULL
)
1415 DEBUG (0,("pdb_set_username: ERROR - Unable to malloc memory for [%s]\n", username
));
1423 BOOL
pdb_set_domain (SAM_ACCOUNT
*sampass
, char *domain
)
1428 if (!sampass
->own_memory
)
1429 sampass
->domain
= domain
;
1432 if ( (sampass
->domain
=strdup(domain
)) == NULL
)
1434 DEBUG (0,("pdb_set_domain: ERROR - Unable to malloc memory for [%s]\n", domain
));
1442 BOOL
pdb_set_nt_username (SAM_ACCOUNT
*sampass
, char *nt_username
)
1447 if (!sampass
->own_memory
)
1448 sampass
->nt_username
= nt_username
;
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
));
1461 BOOL
pdb_set_fullname (SAM_ACCOUNT
*sampass
, char *fullname
)
1466 if (!sampass
->own_memory
)
1467 sampass
->full_name
= fullname
;
1470 if ( (sampass
->full_name
=strdup(fullname
)) == NULL
)
1472 DEBUG (0,("pdb_set_fullname: ERROR - Unable to malloc memory for [%s]\n", fullname
));
1480 BOOL
pdb_set_logon_script (SAM_ACCOUNT
*sampass
, char *logon_script
)
1485 if (!sampass
->own_memory
)
1486 sampass
->logon_script
= logon_script
;
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
));
1499 BOOL
pdb_set_profile_path (SAM_ACCOUNT
*sampass
, char *profile_path
)
1504 if (!sampass
->own_memory
)
1505 sampass
->profile_path
= profile_path
;
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
));
1518 BOOL
pdb_set_dir_drive (SAM_ACCOUNT
*sampass
, char *dir_drive
)
1523 if (!sampass
->own_memory
)
1524 sampass
->dir_drive
= dir_drive
;
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
));
1537 BOOL
pdb_set_homedir (SAM_ACCOUNT
*sampass
, char *homedir
)
1542 if (!sampass
->own_memory
)
1543 sampass
->home_dir
= homedir
;
1546 if ( (sampass
->home_dir
=strdup(homedir
)) == NULL
)
1548 DEBUG (0,("pdb_set_home_dir: ERROR - Unable to malloc memory for [%s]\n", homedir
));
1556 BOOL
pdb_set_acct_desc (SAM_ACCOUNT
*sampass
, char *acct_desc
)
1561 if (!sampass
->own_memory
)
1562 sampass
->acct_desc
= acct_desc
;
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
));
1574 BOOL
pdb_set_workstations (SAM_ACCOUNT
*sampass
, char *workstations
)
1579 if (!sampass
->own_memory
)
1580 sampass
->workstations
= workstations
;
1583 if ( (sampass
->workstations
=strdup(workstations
)) == NULL
)
1585 DEBUG (0,("pdb_set_workstations: ERROR - Unable to malloc memory for [%s]\n", workstations
));
1593 BOOL
pdb_set_munged_dial (SAM_ACCOUNT
*sampass
, char *munged_dial
)
1598 if (!sampass
->own_memory
)
1599 sampass
->munged_dial
= munged_dial
;
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
));
1612 BOOL
pdb_set_nt_passwd (SAM_ACCOUNT
*sampass
, BYTE
*pwd
)
1614 if ( (!sampass
) ||(pwd
== NULL
) )
1617 if (!sampass
->own_memory
)
1618 sampass
->nt_pw
= pwd
;
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"));
1626 if (!memcpy(sampass
->nt_pw
, pwd
, 16))
1633 BOOL
pdb_set_lanman_passwd (SAM_ACCOUNT
*sampass
, BYTE
*pwd
)
1635 if ( (!sampass
) ||(pwd
== NULL
) )
1638 if (!sampass
->own_memory
)
1639 sampass
->lm_pw
= pwd
;
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"));
1647 if (!memcpy(sampass
->lm_pw
, pwd
, 16))