2 Unix SMB/CIFS implementation.
3 Password and authentication handling
4 Copyright (C) Jeremy Allison 1996-2001
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000-2006
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Simo Sorce 2003
9 Copyright (C) Volker Lendecke 2006
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "../libcli/auth/libcli_auth.h"
29 #define DBGC_CLASS DBGC_PASSDB
31 /******************************************************************
32 Get the default domain/netbios name to be used when
33 testing authentication.
35 LEGACY: this function provides the legacy domain mapping used with
36 the lp_map_untrusted_to_domain() parameter
37 ******************************************************************/
39 const char *my_sam_name(void)
41 /* Standalone servers can only use the local netbios name */
42 if ( lp_server_role() == ROLE_STANDALONE
)
43 return global_myname();
45 /* Default to the DOMAIN name when not specified */
46 return lp_workgroup();
49 /**********************************************************************
50 ***********************************************************************/
52 static int samu_destroy(struct samu
*user
)
54 data_blob_clear_free( &user
->lm_pw
);
55 data_blob_clear_free( &user
->nt_pw
);
57 if ( user
->plaintext_pw
)
58 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
63 /**********************************************************************
64 generate a new struct samuser
65 ***********************************************************************/
67 struct samu
*samu_new( TALLOC_CTX
*ctx
)
71 if ( !(user
= TALLOC_ZERO_P( ctx
, struct samu
)) ) {
72 DEBUG(0,("samuser_new: Talloc failed!\n"));
76 talloc_set_destructor( user
, samu_destroy
);
78 /* no initial methods */
82 /* Don't change these timestamp settings without a good reason.
83 They are important for NT member server compatibility. */
85 user
->logon_time
= (time_t)0;
86 user
->pass_last_set_time
= (time_t)0;
87 user
->pass_can_change_time
= (time_t)0;
88 user
->logoff_time
= get_time_t_max();
89 user
->kickoff_time
= get_time_t_max();
90 user
->pass_must_change_time
= get_time_t_max();
91 user
->fields_present
= 0x00ffffff;
92 user
->logon_divs
= 168; /* hours per week */
93 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
94 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
95 user
->bad_password_count
= 0;
96 user
->logon_count
= 0;
97 user
->unknown_6
= 0x000004ec; /* don't know */
99 /* Some parts of samba strlen their pdb_get...() returns,
100 so this keeps the interface unchanged for now. */
104 user
->nt_username
= "";
105 user
->full_name
= "";
107 user
->logon_script
= "";
108 user
->profile_path
= "";
109 user
->acct_desc
= "";
110 user
->workstations
= "";
112 user
->munged_dial
= "";
114 user
->plaintext_pw
= NULL
;
116 /* Unless we know otherwise have a Account Control Bit
117 value of 'normal user'. This helps User Manager, which
118 asks for a filtered list of users. */
120 user
->acct_ctrl
= ACB_NORMAL
;
125 static int count_commas(const char *str
)
128 const char *comma
= str
;
130 while ((comma
= strchr(comma
, ',')) != NULL
) {
137 /*********************************************************************
138 Initialize a struct samu from a struct passwd including the user
139 and group SIDs. The *user structure is filled out with the Unix
140 attributes and a user SID.
141 *********************************************************************/
143 static NTSTATUS
samu_set_unix_internal(struct samu
*user
, const struct passwd
*pwd
, bool create
)
145 const char *guest_account
= lp_guestaccount();
146 const char *domain
= global_myname();
151 return NT_STATUS_NO_SUCH_USER
;
154 /* Basic properties based upon the Unix account information */
156 pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
160 if (count_commas(pwd
->pw_gecos
) == 3) {
162 * Heuristic: This seems to be a gecos field that has been
163 * edited by chfn(1). Only use the part before the first
164 * comma. Fixes bug 5198.
166 fullname
= talloc_strndup(
167 talloc_tos(), pwd
->pw_gecos
,
168 strchr(pwd
->pw_gecos
, ',') - pwd
->pw_gecos
);
171 if (fullname
!= NULL
) {
172 pdb_set_fullname(user
, fullname
, PDB_SET
);
174 pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
176 TALLOC_FREE(fullname
);
178 pdb_set_domain (user
, get_global_sam_name(), PDB_DEFAULT
);
180 /* This can lead to a primary group of S-1-22-2-XX which
181 will be rejected by other parts of the Samba code.
182 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
185 gid_to_sid(&group_sid
, pwd
->pw_gid
);
186 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
189 /* save the password structure for later use */
191 user
->unix_pw
= tcopy_passwd( user
, pwd
);
193 /* Special case for the guest account which must have a RID of 501 */
195 if ( strequal( pwd
->pw_name
, guest_account
) ) {
196 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_USER_RID_GUEST
, PDB_DEFAULT
)) {
197 return NT_STATUS_NO_SUCH_USER
;
202 /* Non-guest accounts...Check for a workstation or user account */
204 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
207 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
208 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
210 return NT_STATUS_INVALID_COMPUTER_NAME
;
216 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
217 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
219 return NT_STATUS_INVALID_ACCOUNT_NAME
;
222 /* set some basic attributes */
224 pdb_set_profile_path(user
, talloc_sub_specified(user
,
225 lp_logon_path(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
227 pdb_set_homedir(user
, talloc_sub_specified(user
,
228 lp_logon_home(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
230 pdb_set_dir_drive(user
, talloc_sub_specified(user
,
231 lp_logon_drive(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
233 pdb_set_logon_script(user
, talloc_sub_specified(user
,
234 lp_logon_script(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
238 /* Now deal with the user SID. If we have a backend that can generate
239 RIDs, then do so. But sometimes the caller just wanted a structure
240 initialized and will fill in these fields later (such as from a
241 netr_SamInfo3 structure) */
243 if ( create
&& (pdb_capabilities() & PDB_CAP_STORE_RIDS
)) {
247 if ( !pdb_new_rid( &user_rid
) ) {
248 DEBUG(3, ("Could not allocate a new RID\n"));
249 return NT_STATUS_ACCESS_DENIED
;
252 sid_compose(&user_sid
, get_global_sam_sid(), user_rid
);
254 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
255 DEBUG(3, ("pdb_set_user_sid failed\n"));
256 return NT_STATUS_INTERNAL_ERROR
;
262 /* generate a SID for the user with the RID algorithm */
264 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
266 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
267 return NT_STATUS_INTERNAL_ERROR
;
273 /********************************************************************
274 Set the Unix user attributes
275 ********************************************************************/
277 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
279 return samu_set_unix_internal( user
, pwd
, False
);
282 NTSTATUS
samu_alloc_rid_unix(struct samu
*user
, const struct passwd
*pwd
)
284 return samu_set_unix_internal( user
, pwd
, True
);
287 /**********************************************************
288 Encode the account control bits into a string.
289 length = length of string to encode into (including terminating
290 null). length *MUST BE MORE THAN 2* !
291 **********************************************************/
293 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl
, size_t length
)
300 SMB_ASSERT(length
<= sizeof(acct_str
));
304 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
305 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
306 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
307 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
308 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
309 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
310 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
311 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
312 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
313 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
314 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
316 for ( ; i
< length
- 2 ; i
++ )
321 acct_str
[i
++] = '\0';
323 result
= talloc_strdup(talloc_tos(), acct_str
);
324 SMB_ASSERT(result
!= NULL
);
328 /**********************************************************
329 Decode the account control bits from a string.
330 **********************************************************/
332 uint32_t pdb_decode_acct_ctrl(const char *p
)
334 uint32_t acct_ctrl
= 0;
335 bool finished
= false;
338 * Check if the account type bits have been encoded after the
339 * NT password (in the form [NDHTUWSLXI]).
345 for (p
++; *p
&& !finished
; p
++) {
347 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
348 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
349 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
350 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
351 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
352 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
353 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
354 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
355 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
356 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
357 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
363 default: { finished
= true; }
370 /*************************************************************
371 Routine to set 32 hex password characters from a 16 byte array.
372 **************************************************************/
374 void pdb_sethexpwd(char p
[33], const unsigned char *pwd
, uint32 acct_ctrl
)
378 for (i
= 0; i
< 16; i
++)
379 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
381 if (acct_ctrl
& ACB_PWNOTREQ
)
382 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
384 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
388 /*************************************************************
389 Routine to get the 32 hex characters and turn them
390 into a 16 byte array.
391 **************************************************************/
393 bool pdb_gethexpwd(const char *p
, unsigned char *pwd
)
396 unsigned char lonybble
, hinybble
;
397 const char *hexchars
= "0123456789ABCDEF";
403 for (i
= 0; i
< 32; i
+= 2) {
404 hinybble
= toupper_ascii(p
[i
]);
405 lonybble
= toupper_ascii(p
[i
+ 1]);
407 p1
= strchr(hexchars
, hinybble
);
408 p2
= strchr(hexchars
, lonybble
);
413 hinybble
= PTR_DIFF(p1
, hexchars
);
414 lonybble
= PTR_DIFF(p2
, hexchars
);
416 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
421 /*************************************************************
422 Routine to set 42 hex hours characters from a 21 byte array.
423 **************************************************************/
425 void pdb_sethexhours(char *p
, const unsigned char *hours
)
429 for (i
= 0; i
< 21; i
++) {
430 slprintf(&p
[i
*2], 3, "%02X", hours
[i
]);
433 safe_strcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
437 /*************************************************************
438 Routine to get the 42 hex characters and turn them
439 into a 21 byte array.
440 **************************************************************/
442 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
445 unsigned char lonybble
, hinybble
;
446 const char *hexchars
= "0123456789ABCDEF";
453 for (i
= 0; i
< 42; i
+= 2) {
454 hinybble
= toupper_ascii(p
[i
]);
455 lonybble
= toupper_ascii(p
[i
+ 1]);
457 p1
= strchr(hexchars
, hinybble
);
458 p2
= strchr(hexchars
, lonybble
);
464 hinybble
= PTR_DIFF(p1
, hexchars
);
465 lonybble
= PTR_DIFF(p2
, hexchars
);
467 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
472 /********************************************************************
473 ********************************************************************/
475 int algorithmic_rid_base(void)
479 rid_offset
= lp_algorithmic_rid_base();
481 if (rid_offset
< BASE_RID
) {
482 /* Try to prevent admin foot-shooting, we can't put algorithmic
483 rids below 1000, that's the 'well known RIDs' on NT */
484 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
485 rid_offset
= BASE_RID
;
487 if (rid_offset
& 1) {
488 DEBUG(0, ("algorithmic rid base must be even\n"));
494 /*******************************************************************
495 Converts NT user RID to a UNIX uid.
496 ********************************************************************/
498 uid_t
algorithmic_pdb_user_rid_to_uid(uint32 user_rid
)
500 int rid_offset
= algorithmic_rid_base();
501 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
504 uid_t
max_algorithmic_uid(void)
506 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
509 /*******************************************************************
510 converts UNIX uid to an NT User RID.
511 ********************************************************************/
513 uint32
algorithmic_pdb_uid_to_user_rid(uid_t uid
)
515 int rid_offset
= algorithmic_rid_base();
516 return (((((uint32
)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
519 /*******************************************************************
520 Converts NT group RID to a UNIX gid.
521 ********************************************************************/
523 gid_t
pdb_group_rid_to_gid(uint32 group_rid
)
525 int rid_offset
= algorithmic_rid_base();
526 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
529 gid_t
max_algorithmic_gid(void)
531 return pdb_group_rid_to_gid(0xffffffff);
534 /*******************************************************************
535 converts NT Group RID to a UNIX uid.
537 warning: you must not call that function only
538 you must do a call to the group mapping first.
539 there is not anymore a direct link between the gid and the rid.
540 ********************************************************************/
542 uint32
algorithmic_pdb_gid_to_group_rid(gid_t gid
)
544 int rid_offset
= algorithmic_rid_base();
545 return (((((uint32
)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
548 /*******************************************************************
549 Decides if a RID is a well known RID.
550 ********************************************************************/
552 static bool rid_is_well_known(uint32 rid
)
554 /* Not using rid_offset here, because this is the actual
555 NT fixed value (1000) */
557 return (rid
< BASE_RID
);
560 /*******************************************************************
561 Decides if a RID is a user or group RID.
562 ********************************************************************/
564 bool algorithmic_pdb_rid_is_user(uint32 rid
)
566 if ( rid_is_well_known(rid
) ) {
568 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
569 * and DOMAIN_USER_RID_GUEST.
571 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
573 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
579 /*******************************************************************
580 Convert a name into a SID. Used in the lookup name rpc.
581 ********************************************************************/
583 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
584 enum lsa_SidType
*type
)
589 /* Windows treats "MACHINE\None" as a special name for
590 rid 513 on non-DCs. You cannot create a user or group
591 name "None" on Windows. You will get an error that
592 the group already exists. */
594 if ( strequal( name
, "None" ) ) {
595 *rid
= DOMAIN_GROUP_RID_USERS
;
596 *type
= SID_NAME_DOM_GRP
;
601 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
602 * correctly in the case where foo also exists as a user. If the flag
603 * is set, don't look for users at all. */
605 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
606 struct samu
*sam_account
= NULL
;
609 if ( !(sam_account
= samu_new( NULL
)) ) {
614 ret
= pdb_getsampwnam(sam_account
, name
);
618 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
621 TALLOC_FREE(sam_account
);
624 if (!sid_check_is_in_our_domain(&user_sid
)) {
625 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
626 name
, sid_string_dbg(&user_sid
)));
630 sid_peek_rid(&user_sid
, rid
);
631 *type
= SID_NAME_USER
;
637 * Maybe it is a group ?
641 ret
= pdb_getgrnam(&map
, name
);
648 /* BUILTIN groups are looked up elsewhere */
649 if (!sid_check_is_in_our_domain(&map
.sid
)) {
650 DEBUG(10, ("Found group %s (%s) not in our domain -- "
651 "ignoring.", name
, sid_string_dbg(&map
.sid
)));
655 /* yes it's a mapped group */
656 sid_peek_rid(&map
.sid
, rid
);
657 *type
= map
.sid_name_use
;
661 /*************************************************************
662 Change a password entry in the local passdb backend.
665 - always called as root
666 - ignores the account type except when adding a new account
667 - will create/delete the unix account if the relative
668 add/delete user script is configured
670 *************************************************************/
672 NTSTATUS
local_password_change(const char *user_name
,
674 const char *new_passwd
,
679 struct samu
*sam_pass
;
689 tosctx
= talloc_tos();
691 sam_pass
= samu_new(tosctx
);
693 result
= NT_STATUS_NO_MEMORY
;
697 /* Get the smb passwd entry for this user */
698 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
700 /* Check delete first, we don't need to do anything else if we
701 * are going to delete the acocunt */
702 if (user_exists
&& (local_flags
& LOCAL_DELETE_USER
)) {
704 result
= pdb_delete_user(tosctx
, sam_pass
);
705 if (!NT_STATUS_IS_OK(result
)) {
706 ret
= asprintf(pp_err_str
,
707 "Failed to delete entry for user %s.\n",
712 result
= NT_STATUS_UNSUCCESSFUL
;
714 ret
= asprintf(pp_msg_str
,
715 "Deleted user %s.\n",
724 if (user_exists
&& (local_flags
& LOCAL_ADD_USER
)) {
725 /* the entry already existed */
726 local_flags
&= ~LOCAL_ADD_USER
;
729 if (!user_exists
&& !(local_flags
& LOCAL_ADD_USER
)) {
730 ret
= asprintf(pp_err_str
,
731 "Failed to find entry for user %s.\n",
736 result
= NT_STATUS_NO_SUCH_USER
;
740 /* First thing add the new user if we are required to do so */
741 if (local_flags
& LOCAL_ADD_USER
) {
743 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
745 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
751 result
= pdb_create_user(tosctx
, user_name
, acb
, &rid
);
752 if (!NT_STATUS_IS_OK(result
)) {
753 ret
= asprintf(pp_err_str
,
754 "Failed to add entry for user %s.\n",
759 result
= NT_STATUS_UNSUCCESSFUL
;
763 sam_pass
= samu_new(tosctx
);
765 result
= NT_STATUS_NO_MEMORY
;
769 /* Now get back the smb passwd entry for this new user */
770 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
772 ret
= asprintf(pp_err_str
,
773 "Failed to add entry for user %s.\n",
778 result
= NT_STATUS_UNSUCCESSFUL
;
783 acb
= pdb_get_acct_ctrl(sam_pass
);
786 * We are root - just write the new password
787 * and the valid last change time.
789 if ((local_flags
& LOCAL_SET_NO_PASSWORD
) && !(acb
& ACB_PWNOTREQ
)) {
791 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
792 ret
= asprintf(pp_err_str
,
793 "Failed to set 'no password required' "
794 "flag for user %s.\n", user_name
);
798 result
= NT_STATUS_UNSUCCESSFUL
;
803 if (local_flags
& LOCAL_SET_PASSWORD
) {
805 * If we're dealing with setting a completely empty user account
806 * ie. One with a password of 'XXXX', but not set disabled (like
807 * an account created from scratch) then if the old password was
808 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
809 * We remove that as we're giving this user their first password
810 * and the decision hasn't really been made to disable them (ie.
811 * don't create them disabled). JRA.
813 if ((pdb_get_lanman_passwd(sam_pass
) == NULL
) &&
814 (acb
& ACB_DISABLED
)) {
815 acb
&= (~ACB_DISABLED
);
816 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
817 ret
= asprintf(pp_err_str
,
818 "Failed to unset 'disabled' "
819 "flag for user %s.\n",
824 result
= NT_STATUS_UNSUCCESSFUL
;
829 acb
&= (~ACB_PWNOTREQ
);
830 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
831 ret
= asprintf(pp_err_str
,
832 "Failed to unset 'no password required'"
833 " flag for user %s.\n", user_name
);
837 result
= NT_STATUS_UNSUCCESSFUL
;
841 if (!pdb_set_plaintext_passwd(sam_pass
, new_passwd
)) {
842 ret
= asprintf(pp_err_str
,
843 "Failed to set password for "
844 "user %s.\n", user_name
);
848 result
= NT_STATUS_UNSUCCESSFUL
;
853 if ((local_flags
& LOCAL_DISABLE_USER
) && !(acb
& ACB_DISABLED
)) {
855 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
856 ret
= asprintf(pp_err_str
,
857 "Failed to set 'disabled' flag for "
858 "user %s.\n", user_name
);
862 result
= NT_STATUS_UNSUCCESSFUL
;
867 if ((local_flags
& LOCAL_ENABLE_USER
) && (acb
& ACB_DISABLED
)) {
868 acb
&= (~ACB_DISABLED
);
869 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
870 ret
= asprintf(pp_err_str
,
871 "Failed to unset 'disabled' flag for "
872 "user %s.\n", user_name
);
876 result
= NT_STATUS_UNSUCCESSFUL
;
881 /* now commit changes if any */
882 result
= pdb_update_sam_account(sam_pass
);
883 if (!NT_STATUS_IS_OK(result
)) {
884 ret
= asprintf(pp_err_str
,
885 "Failed to modify entry for user %s.\n",
893 if (local_flags
& LOCAL_ADD_USER
) {
894 ret
= asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
895 } else if (local_flags
& LOCAL_DISABLE_USER
) {
896 ret
= asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
897 } else if (local_flags
& LOCAL_ENABLE_USER
) {
898 ret
= asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
899 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
900 ret
= asprintf(pp_msg_str
,
901 "User %s password set to none.\n", user_name
);
908 result
= NT_STATUS_OK
;
911 TALLOC_FREE(sam_pass
);
915 /**********************************************************************
916 Marshall/unmarshall struct samu structs.
917 *********************************************************************/
919 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
920 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
921 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
922 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
923 /* nothing changed between V3 and V4 */
925 /*********************************************************************
926 *********************************************************************/
928 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
931 /* times are stored as 32bit integer
932 take care on system with 64bit wide time_t
938 pass_can_change_time
,
939 pass_must_change_time
;
940 char *username
= NULL
;
942 char *nt_username
= NULL
;
943 char *dir_drive
= NULL
;
944 char *unknown_str
= NULL
;
945 char *munged_dial
= NULL
;
946 char *fullname
= NULL
;
947 char *homedir
= NULL
;
948 char *logon_script
= NULL
;
949 char *profile_path
= NULL
;
950 char *acct_desc
= NULL
;
951 char *workstations
= NULL
;
952 uint32 username_len
, domain_len
, nt_username_len
,
953 dir_drive_len
, unknown_str_len
, munged_dial_len
,
954 fullname_len
, homedir_len
, logon_script_len
,
955 profile_path_len
, acct_desc_len
, workstations_len
;
957 uint32 user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
958 uint16 acct_ctrl
, logon_divs
;
959 uint16 bad_password_count
, logon_count
;
961 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
963 uint32 lm_pw_len
, nt_pw_len
, hourslen
;
966 if(sampass
== NULL
|| buf
== NULL
) {
967 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
971 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
973 /* unpack the buffer into variables */
974 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
976 &logoff_time
, /* d */
977 &kickoff_time
, /* d */
978 &pass_last_set_time
, /* d */
979 &pass_can_change_time
, /* d */
980 &pass_must_change_time
, /* d */
981 &username_len
, &username
, /* B */
982 &domain_len
, &domain
, /* B */
983 &nt_username_len
, &nt_username
, /* B */
984 &fullname_len
, &fullname
, /* B */
985 &homedir_len
, &homedir
, /* B */
986 &dir_drive_len
, &dir_drive
, /* B */
987 &logon_script_len
, &logon_script
, /* B */
988 &profile_path_len
, &profile_path
, /* B */
989 &acct_desc_len
, &acct_desc
, /* B */
990 &workstations_len
, &workstations
, /* B */
991 &unknown_str_len
, &unknown_str
, /* B */
992 &munged_dial_len
, &munged_dial
, /* B */
995 &lm_pw_len
, &lm_pw_ptr
, /* B */
996 &nt_pw_len
, &nt_pw_ptr
, /* B */
998 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
1001 &hourslen
, &hours
, /* B */
1002 &bad_password_count
, /* w */
1003 &logon_count
, /* w */
1004 &unknown_6
); /* d */
1006 if (len
== (uint32
) -1) {
1011 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1012 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1013 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1014 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1015 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1016 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1018 pdb_set_username(sampass
, username
, PDB_SET
);
1019 pdb_set_domain(sampass
, domain
, PDB_SET
);
1020 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1021 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1024 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1027 pdb_set_homedir(sampass
,
1028 talloc_sub_basic(sampass
, username
, domain
,
1034 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1036 pdb_set_dir_drive(sampass
,
1037 talloc_sub_basic(sampass
, username
, domain
,
1043 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1045 pdb_set_logon_script(sampass
,
1046 talloc_sub_basic(sampass
, username
, domain
,
1052 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1054 pdb_set_profile_path(sampass
,
1055 talloc_sub_basic(sampass
, username
, domain
,
1060 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1061 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1062 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1064 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1065 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1071 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1072 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1078 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1079 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1080 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1081 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1082 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1083 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1084 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1085 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1086 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1087 pdb_set_hours(sampass
, hours
, PDB_SET
);
1091 SAFE_FREE(username
);
1093 SAFE_FREE(nt_username
);
1094 SAFE_FREE(fullname
);
1096 SAFE_FREE(dir_drive
);
1097 SAFE_FREE(logon_script
);
1098 SAFE_FREE(profile_path
);
1099 SAFE_FREE(acct_desc
);
1100 SAFE_FREE(workstations
);
1101 SAFE_FREE(munged_dial
);
1102 SAFE_FREE(unknown_str
);
1103 SAFE_FREE(lm_pw_ptr
);
1104 SAFE_FREE(nt_pw_ptr
);
1110 /*********************************************************************
1111 *********************************************************************/
1113 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1116 /* times are stored as 32bit integer
1117 take care on system with 64bit wide time_t
1124 pass_can_change_time
,
1125 pass_must_change_time
;
1126 char *username
= NULL
;
1127 char *domain
= NULL
;
1128 char *nt_username
= NULL
;
1129 char *dir_drive
= NULL
;
1130 char *unknown_str
= NULL
;
1131 char *munged_dial
= NULL
;
1132 char *fullname
= NULL
;
1133 char *homedir
= NULL
;
1134 char *logon_script
= NULL
;
1135 char *profile_path
= NULL
;
1136 char *acct_desc
= NULL
;
1137 char *workstations
= NULL
;
1138 uint32 username_len
, domain_len
, nt_username_len
,
1139 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1140 fullname_len
, homedir_len
, logon_script_len
,
1141 profile_path_len
, acct_desc_len
, workstations_len
;
1143 uint32 user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1144 uint16 acct_ctrl
, logon_divs
;
1145 uint16 bad_password_count
, logon_count
;
1146 uint8
*hours
= NULL
;
1147 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1149 uint32 lm_pw_len
, nt_pw_len
, hourslen
;
1152 if(sampass
== NULL
|| buf
== NULL
) {
1153 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1157 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1159 /* unpack the buffer into variables */
1160 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1161 &logon_time
, /* d */
1162 &logoff_time
, /* d */
1163 &kickoff_time
, /* d */
1164 /* Change from V0 is addition of bad_password_time field. */
1165 &bad_password_time
, /* d */
1166 &pass_last_set_time
, /* d */
1167 &pass_can_change_time
, /* d */
1168 &pass_must_change_time
, /* d */
1169 &username_len
, &username
, /* B */
1170 &domain_len
, &domain
, /* B */
1171 &nt_username_len
, &nt_username
, /* B */
1172 &fullname_len
, &fullname
, /* B */
1173 &homedir_len
, &homedir
, /* B */
1174 &dir_drive_len
, &dir_drive
, /* B */
1175 &logon_script_len
, &logon_script
, /* B */
1176 &profile_path_len
, &profile_path
, /* B */
1177 &acct_desc_len
, &acct_desc
, /* B */
1178 &workstations_len
, &workstations
, /* B */
1179 &unknown_str_len
, &unknown_str
, /* B */
1180 &munged_dial_len
, &munged_dial
, /* B */
1183 &lm_pw_len
, &lm_pw_ptr
, /* B */
1184 &nt_pw_len
, &nt_pw_ptr
, /* B */
1187 &logon_divs
, /* w */
1189 &hourslen
, &hours
, /* B */
1190 &bad_password_count
, /* w */
1191 &logon_count
, /* w */
1192 &unknown_6
); /* d */
1194 if (len
== (uint32
) -1) {
1199 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1200 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1201 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1203 /* Change from V0 is addition of bad_password_time field. */
1204 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1205 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1206 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1207 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1209 pdb_set_username(sampass
, username
, PDB_SET
);
1210 pdb_set_domain(sampass
, domain
, PDB_SET
);
1211 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1212 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1215 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1218 pdb_set_homedir(sampass
,
1219 talloc_sub_basic(sampass
, username
, domain
,
1225 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1227 pdb_set_dir_drive(sampass
,
1228 talloc_sub_basic(sampass
, username
, domain
,
1234 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1236 pdb_set_logon_script(sampass
,
1237 talloc_sub_basic(sampass
, username
, domain
,
1243 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1245 pdb_set_profile_path(sampass
,
1246 talloc_sub_basic(sampass
, username
, domain
,
1251 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1252 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1253 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1255 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1256 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1262 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1263 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1269 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1271 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1272 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1273 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1274 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1275 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1276 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1277 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1278 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1279 pdb_set_hours(sampass
, hours
, PDB_SET
);
1283 SAFE_FREE(username
);
1285 SAFE_FREE(nt_username
);
1286 SAFE_FREE(fullname
);
1288 SAFE_FREE(dir_drive
);
1289 SAFE_FREE(logon_script
);
1290 SAFE_FREE(profile_path
);
1291 SAFE_FREE(acct_desc
);
1292 SAFE_FREE(workstations
);
1293 SAFE_FREE(munged_dial
);
1294 SAFE_FREE(unknown_str
);
1295 SAFE_FREE(lm_pw_ptr
);
1296 SAFE_FREE(nt_pw_ptr
);
1302 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1305 /* times are stored as 32bit integer
1306 take care on system with 64bit wide time_t
1313 pass_can_change_time
,
1314 pass_must_change_time
;
1315 char *username
= NULL
;
1316 char *domain
= NULL
;
1317 char *nt_username
= NULL
;
1318 char *dir_drive
= NULL
;
1319 char *unknown_str
= NULL
;
1320 char *munged_dial
= NULL
;
1321 char *fullname
= NULL
;
1322 char *homedir
= NULL
;
1323 char *logon_script
= NULL
;
1324 char *profile_path
= NULL
;
1325 char *acct_desc
= NULL
;
1326 char *workstations
= NULL
;
1327 uint32 username_len
, domain_len
, nt_username_len
,
1328 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1329 fullname_len
, homedir_len
, logon_script_len
,
1330 profile_path_len
, acct_desc_len
, workstations_len
;
1332 uint32 user_rid
, group_rid
, hours_len
, unknown_6
;
1333 uint16 acct_ctrl
, logon_divs
;
1334 uint16 bad_password_count
, logon_count
;
1335 uint8
*hours
= NULL
;
1336 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1338 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1339 uint32 pwHistLen
= 0;
1342 bool expand_explicit
= lp_passdb_expand_explicit();
1344 if(sampass
== NULL
|| buf
== NULL
) {
1345 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1349 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1351 /* unpack the buffer into variables */
1352 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1353 &logon_time
, /* d */
1354 &logoff_time
, /* d */
1355 &kickoff_time
, /* d */
1356 &bad_password_time
, /* d */
1357 &pass_last_set_time
, /* d */
1358 &pass_can_change_time
, /* d */
1359 &pass_must_change_time
, /* d */
1360 &username_len
, &username
, /* B */
1361 &domain_len
, &domain
, /* B */
1362 &nt_username_len
, &nt_username
, /* B */
1363 &fullname_len
, &fullname
, /* B */
1364 &homedir_len
, &homedir
, /* B */
1365 &dir_drive_len
, &dir_drive
, /* B */
1366 &logon_script_len
, &logon_script
, /* B */
1367 &profile_path_len
, &profile_path
, /* B */
1368 &acct_desc_len
, &acct_desc
, /* B */
1369 &workstations_len
, &workstations
, /* B */
1370 &unknown_str_len
, &unknown_str
, /* B */
1371 &munged_dial_len
, &munged_dial
, /* B */
1374 &lm_pw_len
, &lm_pw_ptr
, /* B */
1375 &nt_pw_len
, &nt_pw_ptr
, /* B */
1376 /* Change from V1 is addition of password history field. */
1377 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1379 /* Also "remove_me" field was removed. */
1380 &logon_divs
, /* w */
1382 &hourslen
, &hours
, /* B */
1383 &bad_password_count
, /* w */
1384 &logon_count
, /* w */
1385 &unknown_6
); /* d */
1387 if (len
== (uint32
) -1) {
1392 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1393 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1394 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1395 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1396 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1397 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1398 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1400 pdb_set_username(sampass
, username
, PDB_SET
);
1401 pdb_set_domain(sampass
, domain
, PDB_SET
);
1402 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1403 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1406 fstrcpy( tmp_string
, homedir
);
1407 if (expand_explicit
) {
1408 standard_sub_basic( username
, domain
, tmp_string
,
1409 sizeof(tmp_string
) );
1411 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1414 pdb_set_homedir(sampass
,
1415 talloc_sub_basic(sampass
, username
, domain
,
1421 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1423 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1426 fstrcpy( tmp_string
, logon_script
);
1427 if (expand_explicit
) {
1428 standard_sub_basic( username
, domain
, tmp_string
,
1429 sizeof(tmp_string
) );
1431 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1434 pdb_set_logon_script(sampass
,
1435 talloc_sub_basic(sampass
, username
, domain
,
1441 fstrcpy( tmp_string
, profile_path
);
1442 if (expand_explicit
) {
1443 standard_sub_basic( username
, domain
, tmp_string
,
1444 sizeof(tmp_string
) );
1446 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1449 pdb_set_profile_path(sampass
,
1450 talloc_sub_basic(sampass
, username
, domain
,
1455 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1456 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1457 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1459 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1460 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1466 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1467 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1473 /* Change from V1 is addition of password history field. */
1474 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1476 uint8
*pw_hist
= SMB_MALLOC_ARRAY(uint8
, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1481 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1482 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1484 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1485 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1486 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1487 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1488 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1489 PW_HISTORY_ENTRY_LEN
);
1492 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1499 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1502 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1503 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1504 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1505 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1506 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1507 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1508 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1509 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1510 pdb_set_hours(sampass
, hours
, PDB_SET
);
1514 SAFE_FREE(username
);
1516 SAFE_FREE(nt_username
);
1517 SAFE_FREE(fullname
);
1519 SAFE_FREE(dir_drive
);
1520 SAFE_FREE(logon_script
);
1521 SAFE_FREE(profile_path
);
1522 SAFE_FREE(acct_desc
);
1523 SAFE_FREE(workstations
);
1524 SAFE_FREE(munged_dial
);
1525 SAFE_FREE(unknown_str
);
1526 SAFE_FREE(lm_pw_ptr
);
1527 SAFE_FREE(nt_pw_ptr
);
1528 SAFE_FREE(nt_pw_hist_ptr
);
1534 /*********************************************************************
1535 *********************************************************************/
1537 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1540 /* times are stored as 32bit integer
1541 take care on system with 64bit wide time_t
1548 pass_can_change_time
,
1549 pass_must_change_time
;
1550 char *username
= NULL
;
1551 char *domain
= NULL
;
1552 char *nt_username
= NULL
;
1553 char *dir_drive
= NULL
;
1554 char *comment
= NULL
;
1555 char *munged_dial
= NULL
;
1556 char *fullname
= NULL
;
1557 char *homedir
= NULL
;
1558 char *logon_script
= NULL
;
1559 char *profile_path
= NULL
;
1560 char *acct_desc
= NULL
;
1561 char *workstations
= NULL
;
1562 uint32 username_len
, domain_len
, nt_username_len
,
1563 dir_drive_len
, comment_len
, munged_dial_len
,
1564 fullname_len
, homedir_len
, logon_script_len
,
1565 profile_path_len
, acct_desc_len
, workstations_len
;
1567 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1569 uint16 bad_password_count
, logon_count
;
1570 uint8
*hours
= NULL
;
1571 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1573 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1574 uint32 pwHistLen
= 0;
1577 bool expand_explicit
= lp_passdb_expand_explicit();
1579 if(sampass
== NULL
|| buf
== NULL
) {
1580 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1584 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1586 /* unpack the buffer into variables */
1587 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1588 &logon_time
, /* d */
1589 &logoff_time
, /* d */
1590 &kickoff_time
, /* d */
1591 &bad_password_time
, /* d */
1592 &pass_last_set_time
, /* d */
1593 &pass_can_change_time
, /* d */
1594 &pass_must_change_time
, /* d */
1595 &username_len
, &username
, /* B */
1596 &domain_len
, &domain
, /* B */
1597 &nt_username_len
, &nt_username
, /* B */
1598 &fullname_len
, &fullname
, /* B */
1599 &homedir_len
, &homedir
, /* B */
1600 &dir_drive_len
, &dir_drive
, /* B */
1601 &logon_script_len
, &logon_script
, /* B */
1602 &profile_path_len
, &profile_path
, /* B */
1603 &acct_desc_len
, &acct_desc
, /* B */
1604 &workstations_len
, &workstations
, /* B */
1605 &comment_len
, &comment
, /* B */
1606 &munged_dial_len
, &munged_dial
, /* B */
1609 &lm_pw_len
, &lm_pw_ptr
, /* B */
1610 &nt_pw_len
, &nt_pw_ptr
, /* B */
1611 /* Change from V1 is addition of password history field. */
1612 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1613 /* Change from V2 is the uint32 acb_mask */
1615 /* Also "remove_me" field was removed. */
1616 &logon_divs
, /* w */
1618 &hourslen
, &hours
, /* B */
1619 &bad_password_count
, /* w */
1620 &logon_count
, /* w */
1621 &unknown_6
); /* d */
1623 if (len
== (uint32
) -1) {
1628 pdb_set_logon_time(sampass
, convert_uint32_to_time_t(logon_time
), PDB_SET
);
1629 pdb_set_logoff_time(sampass
, convert_uint32_to_time_t(logoff_time
), PDB_SET
);
1630 pdb_set_kickoff_time(sampass
, convert_uint32_to_time_t(kickoff_time
), PDB_SET
);
1631 pdb_set_bad_password_time(sampass
, convert_uint32_to_time_t(bad_password_time
), PDB_SET
);
1632 pdb_set_pass_can_change_time(sampass
, convert_uint32_to_time_t(pass_can_change_time
), PDB_SET
);
1633 pdb_set_pass_must_change_time(sampass
, convert_uint32_to_time_t(pass_must_change_time
), PDB_SET
);
1634 pdb_set_pass_last_set_time(sampass
, convert_uint32_to_time_t(pass_last_set_time
), PDB_SET
);
1636 pdb_set_username(sampass
, username
, PDB_SET
);
1637 pdb_set_domain(sampass
, domain
, PDB_SET
);
1638 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1639 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1642 fstrcpy( tmp_string
, homedir
);
1643 if (expand_explicit
) {
1644 standard_sub_basic( username
, domain
, tmp_string
,
1645 sizeof(tmp_string
) );
1647 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1650 pdb_set_homedir(sampass
,
1651 talloc_sub_basic(sampass
, username
, domain
,
1657 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1659 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1662 fstrcpy( tmp_string
, logon_script
);
1663 if (expand_explicit
) {
1664 standard_sub_basic( username
, domain
, tmp_string
,
1665 sizeof(tmp_string
) );
1667 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1670 pdb_set_logon_script(sampass
,
1671 talloc_sub_basic(sampass
, username
, domain
,
1677 fstrcpy( tmp_string
, profile_path
);
1678 if (expand_explicit
) {
1679 standard_sub_basic( username
, domain
, tmp_string
,
1680 sizeof(tmp_string
) );
1682 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1685 pdb_set_profile_path(sampass
,
1686 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1690 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1691 pdb_set_comment(sampass
, comment
, PDB_SET
);
1692 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1693 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1695 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1696 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1702 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1703 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1709 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1711 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1716 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1717 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1719 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1720 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1721 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1722 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1723 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1724 PW_HISTORY_ENTRY_LEN
);
1727 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1734 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1737 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1738 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1739 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1740 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1741 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1742 /* Change from V2 is the uint32 acct_ctrl */
1743 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1744 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1745 pdb_set_hours(sampass
, hours
, PDB_SET
);
1749 SAFE_FREE(username
);
1751 SAFE_FREE(nt_username
);
1752 SAFE_FREE(fullname
);
1754 SAFE_FREE(dir_drive
);
1755 SAFE_FREE(logon_script
);
1756 SAFE_FREE(profile_path
);
1757 SAFE_FREE(acct_desc
);
1758 SAFE_FREE(workstations
);
1759 SAFE_FREE(munged_dial
);
1761 SAFE_FREE(lm_pw_ptr
);
1762 SAFE_FREE(nt_pw_ptr
);
1763 SAFE_FREE(nt_pw_hist_ptr
);
1769 /*********************************************************************
1770 *********************************************************************/
1772 static uint32
init_buffer_from_samu_v3 (uint8
**buf
, struct samu
*sampass
, bool size_only
)
1776 /* times are stored as 32bit integer
1777 take care on system with 64bit wide time_t
1784 pass_can_change_time
,
1785 pass_must_change_time
;
1787 uint32 user_rid
, group_rid
;
1789 const char *username
;
1791 const char *nt_username
;
1792 const char *dir_drive
;
1793 const char *comment
;
1794 const char *munged_dial
;
1795 const char *fullname
;
1796 const char *homedir
;
1797 const char *logon_script
;
1798 const char *profile_path
;
1799 const char *acct_desc
;
1800 const char *workstations
;
1801 uint32 username_len
, domain_len
, nt_username_len
,
1802 dir_drive_len
, comment_len
, munged_dial_len
,
1803 fullname_len
, homedir_len
, logon_script_len
,
1804 profile_path_len
, acct_desc_len
, workstations_len
;
1808 const uint8
*nt_pw_hist
;
1809 uint32 lm_pw_len
= 16;
1810 uint32 nt_pw_len
= 16;
1811 uint32 nt_pw_hist_len
;
1812 uint32 pwHistLen
= 0;
1817 logon_time
= convert_time_t_to_uint32(pdb_get_logon_time(sampass
));
1818 logoff_time
= convert_time_t_to_uint32(pdb_get_logoff_time(sampass
));
1819 kickoff_time
= convert_time_t_to_uint32(pdb_get_kickoff_time(sampass
));
1820 bad_password_time
= convert_time_t_to_uint32(pdb_get_bad_password_time(sampass
));
1821 pass_can_change_time
= convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass
));
1822 pass_must_change_time
= convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass
));
1823 pass_last_set_time
= convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass
));
1825 user_rid
= pdb_get_user_rid(sampass
);
1826 group_rid
= pdb_get_group_rid(sampass
);
1828 username
= pdb_get_username(sampass
);
1830 username_len
= strlen(username
) +1;
1835 domain
= pdb_get_domain(sampass
);
1837 domain_len
= strlen(domain
) +1;
1842 nt_username
= pdb_get_nt_username(sampass
);
1844 nt_username_len
= strlen(nt_username
) +1;
1846 nt_username_len
= 0;
1849 fullname
= pdb_get_fullname(sampass
);
1851 fullname_len
= strlen(fullname
) +1;
1857 * Only updates fields which have been set (not defaults from smb.conf)
1860 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1861 dir_drive
= pdb_get_dir_drive(sampass
);
1866 dir_drive_len
= strlen(dir_drive
) +1;
1871 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1872 homedir
= pdb_get_homedir(sampass
);
1877 homedir_len
= strlen(homedir
) +1;
1882 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1883 logon_script
= pdb_get_logon_script(sampass
);
1885 logon_script
= NULL
;
1888 logon_script_len
= strlen(logon_script
) +1;
1890 logon_script_len
= 0;
1893 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1894 profile_path
= pdb_get_profile_path(sampass
);
1896 profile_path
= NULL
;
1899 profile_path_len
= strlen(profile_path
) +1;
1901 profile_path_len
= 0;
1904 lm_pw
= pdb_get_lanman_passwd(sampass
);
1909 nt_pw
= pdb_get_nt_passwd(sampass
);
1914 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1915 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1916 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1917 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1922 acct_desc
= pdb_get_acct_desc(sampass
);
1924 acct_desc_len
= strlen(acct_desc
) +1;
1929 workstations
= pdb_get_workstations(sampass
);
1931 workstations_len
= strlen(workstations
) +1;
1933 workstations_len
= 0;
1936 comment
= pdb_get_comment(sampass
);
1938 comment_len
= strlen(comment
) +1;
1943 munged_dial
= pdb_get_munged_dial(sampass
);
1945 munged_dial_len
= strlen(munged_dial
) +1;
1947 munged_dial_len
= 0;
1950 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1952 /* one time to get the size needed */
1953 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
1955 logoff_time
, /* d */
1956 kickoff_time
, /* d */
1957 bad_password_time
, /* d */
1958 pass_last_set_time
, /* d */
1959 pass_can_change_time
, /* d */
1960 pass_must_change_time
, /* d */
1961 username_len
, username
, /* B */
1962 domain_len
, domain
, /* B */
1963 nt_username_len
, nt_username
, /* B */
1964 fullname_len
, fullname
, /* B */
1965 homedir_len
, homedir
, /* B */
1966 dir_drive_len
, dir_drive
, /* B */
1967 logon_script_len
, logon_script
, /* B */
1968 profile_path_len
, profile_path
, /* B */
1969 acct_desc_len
, acct_desc
, /* B */
1970 workstations_len
, workstations
, /* B */
1971 comment_len
, comment
, /* B */
1972 munged_dial_len
, munged_dial
, /* B */
1975 lm_pw_len
, lm_pw
, /* B */
1976 nt_pw_len
, nt_pw
, /* B */
1977 nt_pw_hist_len
, nt_pw_hist
, /* B */
1978 pdb_get_acct_ctrl(sampass
), /* d */
1979 pdb_get_logon_divs(sampass
), /* w */
1980 pdb_get_hours_len(sampass
), /* d */
1981 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1982 pdb_get_bad_password_count(sampass
), /* w */
1983 pdb_get_logon_count(sampass
), /* w */
1984 pdb_get_unknown_6(sampass
)); /* d */
1990 /* malloc the space needed */
1991 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1992 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1996 /* now for the real call to tdb_pack() */
1997 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
1999 logoff_time
, /* d */
2000 kickoff_time
, /* d */
2001 bad_password_time
, /* d */
2002 pass_last_set_time
, /* d */
2003 pass_can_change_time
, /* d */
2004 pass_must_change_time
, /* d */
2005 username_len
, username
, /* B */
2006 domain_len
, domain
, /* B */
2007 nt_username_len
, nt_username
, /* B */
2008 fullname_len
, fullname
, /* B */
2009 homedir_len
, homedir
, /* B */
2010 dir_drive_len
, dir_drive
, /* B */
2011 logon_script_len
, logon_script
, /* B */
2012 profile_path_len
, profile_path
, /* B */
2013 acct_desc_len
, acct_desc
, /* B */
2014 workstations_len
, workstations
, /* B */
2015 comment_len
, comment
, /* B */
2016 munged_dial_len
, munged_dial
, /* B */
2019 lm_pw_len
, lm_pw
, /* B */
2020 nt_pw_len
, nt_pw
, /* B */
2021 nt_pw_hist_len
, nt_pw_hist
, /* B */
2022 pdb_get_acct_ctrl(sampass
), /* d */
2023 pdb_get_logon_divs(sampass
), /* w */
2024 pdb_get_hours_len(sampass
), /* d */
2025 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2026 pdb_get_bad_password_count(sampass
), /* w */
2027 pdb_get_logon_count(sampass
), /* w */
2028 pdb_get_unknown_6(sampass
)); /* d */
2030 /* check to make sure we got it correct */
2031 if (buflen
!= len
) {
2032 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2033 (unsigned long)buflen
, (unsigned long)len
));
2042 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
2044 /* nothing changed between V3 and V4 */
2045 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2048 static uint32
init_buffer_from_samu_v4(uint8
**buf
, struct samu
*sampass
, bool size_only
)
2050 /* nothing changed between V3 and V4 */
2051 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
2054 /**********************************************************************
2055 Intialize a struct samu struct from a BYTE buffer of size len
2056 *********************************************************************/
2058 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
2059 uint8
*buf
, uint32 buflen
)
2062 case SAMU_BUFFER_V0
:
2063 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
2064 case SAMU_BUFFER_V1
:
2065 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2066 case SAMU_BUFFER_V2
:
2067 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2068 case SAMU_BUFFER_V3
:
2069 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2070 case SAMU_BUFFER_V4
:
2071 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2077 /**********************************************************************
2078 Intialize a BYTE buffer from a struct samu struct
2079 *********************************************************************/
2081 uint32
init_buffer_from_samu (uint8
**buf
, struct samu
*sampass
, bool size_only
)
2083 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2086 /*********************************************************************
2087 *********************************************************************/
2089 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2094 len
= init_buffer_from_samu(&buf
, src
, False
);
2095 if (len
== -1 || !buf
) {
2100 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2105 dst
->methods
= src
->methods
;
2107 if ( src
->unix_pw
) {
2108 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2109 if (!dst
->unix_pw
) {
2115 if (src
->group_sid
) {
2116 pdb_set_group_sid(dst
, src
->group_sid
, PDB_SET
);
2123 /*********************************************************************
2124 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2125 *********************************************************************/
2127 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2129 time_t LastBadPassword
;
2130 uint16 BadPasswordCount
;
2134 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2135 if (!BadPasswordCount
) {
2136 DEBUG(9, ("No bad password attempts.\n"));
2141 res
= pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &resettime
);
2145 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2149 /* First, check if there is a reset time to compare */
2150 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
2151 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2155 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2156 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2157 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
2158 if (time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(resettime
)*60)){
2159 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2160 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2169 /*********************************************************************
2170 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2171 *********************************************************************/
2173 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2176 time_t LastBadPassword
;
2179 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2180 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2181 pdb_get_username(sampass
)));
2186 res
= pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &duration
);
2190 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2194 /* First, check if there is a duration to compare */
2195 if ((duration
== (uint32
) -1) || (duration
== 0)) {
2196 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2200 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2201 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2202 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
2204 if (LastBadPassword
== (time_t)0) {
2205 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2206 "administratively locked out with no bad password "
2207 "time. Leaving locked out.\n",
2208 pdb_get_username(sampass
) ));
2212 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(duration
) * 60))) {
2213 pdb_set_acct_ctrl(sampass
,
2214 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2216 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2217 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2226 /*********************************************************************
2227 Increment the bad_password_count
2228 *********************************************************************/
2230 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2232 uint32 account_policy_lockout
;
2233 bool autolock_updated
= False
, badpw_updated
= False
;
2236 /* Retrieve the account lockout policy */
2238 ret
= pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2241 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2245 /* If there is no policy, we don't need to continue checking */
2246 if (!account_policy_lockout
) {
2247 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2251 /* Check if the autolock needs to be cleared */
2252 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2255 /* Check if the badpw count needs to be reset */
2256 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2260 Ok, now we can assume that any resetting that needs to be
2261 done has been done, and just get on with incrementing
2262 and autolocking if necessary
2265 pdb_set_bad_password_count(sampass
,
2266 pdb_get_bad_password_count(sampass
)+1,
2268 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2271 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2274 if (!pdb_set_acct_ctrl(sampass
,
2275 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2277 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2284 bool is_dc_trusted_domain_situation(const char *domain_name
)
2286 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2289 /*******************************************************************
2290 Wrapper around retrieving the clear text trust account password.
2291 appropriate account name is stored in account_name.
2292 Caller must free password, but not account_name.
2293 *******************************************************************/
2295 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2296 const char **account_name
,
2297 enum netr_SchannelType
*channel
)
2300 time_t last_set_time
;
2302 /* if we are a DC and this is not our domain, then lookup an account
2303 * for the domain trust */
2305 if (is_dc_trusted_domain_situation(domain
)) {
2306 if (!lp_allow_trusted_domains()) {
2310 if (!pdb_get_trusteddom_pw(domain
, ret_pwd
, NULL
,
2313 DEBUG(0, ("get_trust_pw: could not fetch trust "
2314 "account password for trusted domain %s\n",
2319 if (channel
!= NULL
) {
2320 *channel
= SEC_CHAN_DOMAIN
;
2323 if (account_name
!= NULL
) {
2324 *account_name
= lp_workgroup();
2331 * Since we can only be member of one single domain, we are now
2332 * in a member situation:
2334 * - Either we are a DC (selfjoined) and the domain is our
2336 * - Or we are on a member and the domain is our own or some
2337 * other (potentially trusted) domain.
2339 * In both cases, we can only get the machine account password
2340 * for our own domain to connect to our own dc. (For a member,
2341 * request to trusted domains are performed through our dc.)
2343 * So we simply use our own domain name to retrieve the
2344 * machine account passowrd and ignore the request domain here.
2347 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2351 if (account_name
!= NULL
) {
2352 *account_name
= global_myname();
2358 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2359 "account password for domain %s\n", domain
));
2363 /*******************************************************************
2364 Wrapper around retrieving the trust account password.
2365 appropriate account name is stored in account_name.
2366 *******************************************************************/
2368 bool get_trust_pw_hash(const char *domain
, uint8 ret_pwd
[16],
2369 const char **account_name
,
2370 enum netr_SchannelType
*channel
)
2373 time_t last_set_time
;
2375 if (get_trust_pw_clear(domain
, &pwd
, account_name
, channel
)) {
2376 E_md4hash(pwd
, ret_pwd
);
2379 } else if (is_dc_trusted_domain_situation(domain
)) {
2383 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2385 if (secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
2389 if (account_name
!= NULL
) {
2390 *account_name
= global_myname();
2396 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2397 "password for domain %s\n", domain
));
2401 struct samr_LogonHours
get_logon_hours_from_pdb(TALLOC_CTX
*mem_ctx
,
2404 struct samr_LogonHours hours
;
2405 const int units_per_week
= 168;
2408 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
2413 hours
.units_per_week
= units_per_week
;
2414 memset(hours
.bits
, 0xFF, units_per_week
);
2416 if (pdb_get_hours(pw
)) {
2417 memcpy(hours
.bits
, pdb_get_hours(pw
),
2418 MIN(pdb_get_hours_len(pw
), units_per_week
));