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
;
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();
77 /* load another module? */
78 if (reload
&& pdb_handle
)
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()));
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",
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
)
124 /*************************************************************
125 initialises a struct sam_passwd.
126 ************************************************************/
127 void pdb_init_sam(SAM_ACCOUNT
*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
)
158 /* clear all pointer members */
160 free(user
->username
);
162 free(user
->full_name
);
164 free(user
->home_dir
);
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
);
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
);
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
;
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
;
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
;
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
] = ' '; }
240 acct_str
[i
++] = '\0';
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
++)
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. */ }
285 default: { finished
= True
; }
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
)
299 for (i
= 0; i
< 16; i
++)
300 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
302 if (acct_ctrl
& ACB_PWNOTREQ
)
303 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
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
)
316 unsigned char lonybble
, hinybble
;
317 char *hexchars
= "0123456789ABCDEF";
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
);
333 hinybble
= PTR_DIFF(p1
, hexchars
);
334 lonybble
= PTR_DIFF(p2
, hexchars
);
336 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
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
)
355 DEBUG(1,("Username %s is invalid on this system\n", user_name
));
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
;
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
);
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
)
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
)
440 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
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
));
458 if(rid
== DOMAIN_USER_RID_ADMIN
) {
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
) {
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");
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" ));
480 slprintf(name
, sizeof(fstring
)-1, "unix_user.%u", (unsigned int)uid
);
484 fstrcpy(name
, pass
->pw_name
);
486 DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name
,
487 (unsigned int)rid
));
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" ));
500 slprintf(name
, sizeof(fstring
)-1, "unix_group.%u", (unsigned int)gid
);
504 fstrcpy( name
, gr
->gr_name
);
506 DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name
,
507 (unsigned int)rid
));
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
;
523 sid_copy(&local_sid
, &global_sam_sid
);
525 if(!strequal(global_myname
, domain
) && !strequal(global_myworkgroup
, domain
))
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
;
539 (void)map_username(user
);
541 if(!(pass
= Get_Pwnam(user
, False
))) {
543 * Maybe it was a group ?
545 struct group
*grp
= getgrnam(user
);
550 sid_append_rid( &local_sid
, pdb_gid_to_group_rid(grp
->gr_gid
));
551 *psid_name_use
= SID_NAME_ALIAS
;
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
);
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
));
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
;
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
))
599 *puid
= pdb_user_rid_to_uid(rid
);
602 * Ensure this uid really does exist.
604 if(!sys_getpwuid(*puid
))
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
));
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
;
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
))
645 *pgid
= pdb_user_rid_to_gid(rid
);
648 * Ensure this gid really does exist.
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
));
666 /*************************************************************
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
);
704 to
->user_rid
= from
->user_rid
;
705 to
->group_rid
= from
->group_rid
;
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 /*************************************************************
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
);
759 to
->user_rid
= from
->user_rid
;
760 to
->group_rid
= from
->group_rid
;
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 /*************************************************************
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
861 *************************************************************/
863 BOOL
local_password_change(char *user_name
, int local_flags
,
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
;
872 uchar new_nt_p16
[16];
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
);
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
);
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
);
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
);
937 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
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
);
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
);
997 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
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
);
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
);
1018 /*********************************************************************
1019 collection of get...() functions for SAM_ACCOUNT_INFO
1020 ********************************************************************/
1021 uint16
pdb_get_acct_ctrl (SAM_ACCOUNT
*sampass
)
1024 return (sampass
->acct_ctrl
);
1026 return (ACB_DISABLED
);
1029 time_t pdb_get_logon_time (SAM_ACCOUNT
*sampass
)
1032 return (sampass
->logon_time
);
1037 time_t pdb_get_logoff_time (SAM_ACCOUNT
*sampass
)
1040 return (sampass
->logoff_time
);
1045 time_t pdb_get_kickoff_time (SAM_ACCOUNT
*sampass
)
1048 return (sampass
->kickoff_time
);
1053 time_t pdb_get_pass_last_set_time (SAM_ACCOUNT
*sampass
)
1056 return (sampass
->pass_last_set_time
);
1061 time_t pdb_get_pass_can_change_time (SAM_ACCOUNT
*sampass
)
1064 return (sampass
->pass_can_change_time
);
1069 time_t pdb_get_pass_must_change_time (SAM_ACCOUNT
*sampass
)
1072 return (sampass
->pass_must_change_time
);
1077 uint16
pdb_get_logon_divs (SAM_ACCOUNT
*sampass
)
1080 return (sampass
->logon_divs
);
1085 uint32
pdb_get_hours_len (SAM_ACCOUNT
*sampass
)
1088 return (sampass
->hours_len
);
1093 uint8
* pdb_get_hours (SAM_ACCOUNT
*sampass
)
1096 return (sampass
->hours
);
1101 BYTE
* pdb_get_nt_passwd (SAM_ACCOUNT
*sampass
)
1104 return (sampass
->nt_pw
);
1109 BYTE
* pdb_get_lanman_passwd (SAM_ACCOUNT
*sampass
)
1112 return (sampass
->lm_pw
);
1118 uint32
pdb_get_user_rid (SAM_ACCOUNT
*sampass
)
1121 return (sampass
->user_rid
);
1126 uint32
pdb_get_group_rid (SAM_ACCOUNT
*sampass
)
1129 return (sampass
->group_rid
);
1134 uid_t
pdb_get_uid (SAM_ACCOUNT
*sampass
)
1137 return (sampass
->uid
);
1142 gid_t
pdb_get_gid (SAM_ACCOUNT
*sampass
)
1145 return (sampass
->gid
);
1150 char* pdb_get_username (SAM_ACCOUNT
*sampass
)
1153 return (sampass
->username
);
1158 char* pdb_get_domain (SAM_ACCOUNT
*sampass
)
1161 return (sampass
->domain
);
1166 char* pdb_get_nt_username (SAM_ACCOUNT
*sampass
)
1169 return (sampass
->nt_username
);
1174 char* pdb_get_fullname (SAM_ACCOUNT
*sampass
)
1177 return (sampass
->full_name
);
1182 char* pdb_get_homedir (SAM_ACCOUNT
*sampass
)
1185 return (sampass
->home_dir
);
1190 char* pdb_get_dirdrive (SAM_ACCOUNT
*sampass
)
1193 return (sampass
->dir_drive
);
1198 char* pdb_get_logon_script (SAM_ACCOUNT
*sampass
)
1201 return (sampass
->logon_script
);
1206 char* pdb_get_profile_path (SAM_ACCOUNT
*sampass
)
1209 return (sampass
->profile_path
);
1214 char* pdb_get_acct_desc (SAM_ACCOUNT
*sampass
)
1217 return (sampass
->acct_desc
);
1222 char* pdb_get_workstations (SAM_ACCOUNT
*sampass
)
1225 return (sampass
->workstations
);
1230 char* pdb_get_munged_dial (SAM_ACCOUNT
*sampass
)
1233 return (sampass
->munged_dial
);
1238 uint32
pdb_get_unknown3 (SAM_ACCOUNT
*sampass
)
1241 return (sampass
->unknown_3
);
1246 uint32
pdb_get_unknown5 (SAM_ACCOUNT
*sampass
)
1249 return (sampass
->unknown_5
);
1254 uint32
pdb_get_unknown6 (SAM_ACCOUNT
*sampass
)
1257 return (sampass
->unknown_6
);
1262 /*********************************************************************
1263 collection of set...() functions for SAM_ACCOUNT_INFO
1264 ********************************************************************/
1265 BOOL
pdb_set_acct_ctrl (SAM_ACCOUNT
*sampass
, uint16 flags
)
1269 sampass
->acct_ctrl
= flags
;
1276 BOOL
pdb_set_logon_time (SAM_ACCOUNT
*sampass
, time_t time
)
1280 sampass
->logon_time
= time
;
1287 BOOL
pdb_set_logoff_time (SAM_ACCOUNT
*sampass
, time_t time
)
1291 sampass
->logoff_time
= time
;
1298 BOOL
pdb_set_kickoff_time (SAM_ACCOUNT
*sampass
, time_t time
)
1302 sampass
->kickoff_time
= time
;
1309 BOOL
pdb_set_pass_can_change_time (SAM_ACCOUNT
*sampass
, time_t time
)
1313 sampass
->pass_can_change_time
= time
;
1320 BOOL
pdb_set_pass_must_change_time (SAM_ACCOUNT
*sampass
, time_t time
)
1324 sampass
->pass_must_change_time
= time
;
1331 BOOL
pdb_set_pass_last_set_time (SAM_ACCOUNT
*sampass
, time_t time
)
1335 sampass
->pass_last_set_time
= time
;
1342 BOOL
pdb_set_hours_len (SAM_ACCOUNT
*sampass
, uint32 len
)
1346 sampass
->hours_len
= len
;
1353 BOOL
pdb_set_logons_divs (SAM_ACCOUNT
*sampass
, uint16 hours
)
1357 sampass
->logon_divs
= hours
;
1364 BOOL
pdb_set_uid (SAM_ACCOUNT
*sampass
, uid_t uid
)
1375 BOOL
pdb_set_gid (SAM_ACCOUNT
*sampass
, gid_t gid
)
1386 BOOL
pdb_set_user_rid (SAM_ACCOUNT
*sampass
, uint32 rid
)
1390 sampass
->user_rid
= rid
;
1397 BOOL
pdb_set_group_rid (SAM_ACCOUNT
*sampass
, uint32 grid
)
1401 sampass
->group_rid
= grid
;
1408 BOOL
pdb_set_username (SAM_ACCOUNT
*sampass
, char *username
)
1412 sampass
->username
= strdup(username
);
1419 BOOL
pdb_set_domain (SAM_ACCOUNT
*sampass
, char *domain
)
1423 sampass
->username
= strdup(domain
);
1430 BOOL
pdb_set_nt_username (SAM_ACCOUNT
*sampass
, char *nt_username
)
1434 sampass
->username
= strdup(nt_username
);
1441 BOOL
pdb_set_fullname (SAM_ACCOUNT
*sampass
, char *fullname
)
1445 sampass
->full_name
= strdup(fullname
);
1452 BOOL
pdb_set_logon_script (SAM_ACCOUNT
*sampass
, char *logon_script
)
1456 sampass
->logon_script
= strdup(logon_script
);
1463 BOOL
pdb_set_profile_path (SAM_ACCOUNT
*sampass
, char *profile_path
)
1467 sampass
->profile_path
= strdup(profile_path
);
1474 BOOL
pdb_set_dir_drive (SAM_ACCOUNT
*sampass
, char *dir_drive
)
1478 sampass
->dir_drive
= strdup(dir_drive
);
1485 BOOL
pdb_set_homedir (SAM_ACCOUNT
*sampass
, char *homedir
)
1489 sampass
->home_dir
= strdup(homedir
);
1497 BOOL
pdb_set_nt_passwd (SAM_ACCOUNT
*sampass
, BYTE
*pwd
)
1503 /* allocate space for the password and make a copy of it */
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"));
1511 if (memcpy(sampass
->nt_pw
, pwd
, 16))
1518 BOOL
pdb_set_lanman_passwd (SAM_ACCOUNT
*sampass
, BYTE
*pwd
)
1523 /* allocate space for the password and make a copy of it */
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"));
1531 if (memcpy(sampass
->lm_pw
, pwd
, 16))