ntlm_auth: Fix another typo in the test.
[Samba.git] / source / passdb / passdb.c
blob4228f6c32fbd37efbc59872b12870686453fb258
1 /*
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/>.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
30 /******************************************************************
31 get the default domain/netbios name to be used when
32 testing authentication. For example, if you connect
33 to a Windows member server using a bogus domain name, the
34 Windows box will map the BOGUS\user to DOMAIN\user. A
35 standalone box will map to WKS\user.
36 ******************************************************************/
38 const char *my_sam_name(void)
40 /* standalone servers can only use the local netbios name */
41 if ( lp_server_role() == ROLE_STANDALONE )
42 return global_myname();
44 /* Windows domain members default to the DOMAIN
45 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) );
60 return 0;
63 /**********************************************************************
64 generate a new struct samuser
65 ***********************************************************************/
67 struct samu *samu_new( TALLOC_CTX *ctx )
69 struct samu *user;
71 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
72 DEBUG(0,("samuser_new: Talloc failed!\n"));
73 return NULL;
76 talloc_set_destructor( user, samu_destroy );
78 /* no initial methods */
80 user->methods = NULL;
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. */
102 user->username = "";
103 user->domain = "";
104 user->nt_username = "";
105 user->full_name = "";
106 user->home_dir = "";
107 user->logon_script = "";
108 user->profile_path = "";
109 user->acct_desc = "";
110 user->workstations = "";
111 user->comment = "";
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;
123 return user;
126 /*********************************************************************
127 Initialize a struct samu from a struct passwd including the user
128 and group SIDs. The *user structure is filled out with the Unix
129 attributes and a user SID.
130 *********************************************************************/
132 static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, bool create)
134 const char *guest_account = lp_guestaccount();
135 const char *domain = global_myname();
136 uint32 urid;
138 if ( !pwd ) {
139 return NT_STATUS_NO_SUCH_USER;
142 /* Basic properties based upon the Unix account information */
144 pdb_set_username(user, pwd->pw_name, PDB_SET);
145 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
146 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
147 #if 0
148 /* This can lead to a primary group of S-1-22-2-XX which
149 will be rejected by other parts of the Samba code.
150 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
151 --jerry */
153 gid_to_sid(&group_sid, pwd->pw_gid);
154 pdb_set_group_sid(user, &group_sid, PDB_SET);
155 #endif
157 /* save the password structure for later use */
159 user->unix_pw = tcopy_passwd( user, pwd );
161 /* Special case for the guest account which must have a RID of 501 */
163 if ( strequal( pwd->pw_name, guest_account ) ) {
164 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
165 return NT_STATUS_NO_SUCH_USER;
167 return NT_STATUS_OK;
170 /* Non-guest accounts...Check for a workstation or user account */
172 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
173 /* workstation */
175 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
176 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
177 pwd->pw_name));
178 return NT_STATUS_INVALID_COMPUTER_NAME;
181 else {
182 /* user */
184 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
185 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
186 pwd->pw_name));
187 return NT_STATUS_INVALID_ACCOUNT_NAME;
190 /* set some basic attributes */
192 pdb_set_profile_path(user, talloc_sub_specified(user,
193 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
194 PDB_DEFAULT);
195 pdb_set_homedir(user, talloc_sub_specified(user,
196 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
197 PDB_DEFAULT);
198 pdb_set_dir_drive(user, talloc_sub_specified(user,
199 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
200 PDB_DEFAULT);
201 pdb_set_logon_script(user, talloc_sub_specified(user,
202 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
203 PDB_DEFAULT);
206 /* Now deal with the user SID. If we have a backend that can generate
207 RIDs, then do so. But sometimes the caller just wanted a structure
208 initialized and will fill in these fields later (such as from a
209 NET_USER_INFO_3 structure) */
211 if ( create && !pdb_rid_algorithm() ) {
212 uint32 user_rid;
213 DOM_SID user_sid;
215 if ( !pdb_new_rid( &user_rid ) ) {
216 DEBUG(3, ("Could not allocate a new RID\n"));
217 return NT_STATUS_ACCESS_DENIED;
220 sid_copy( &user_sid, get_global_sam_sid() );
221 sid_append_rid( &user_sid, user_rid );
223 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
224 DEBUG(3, ("pdb_set_user_sid failed\n"));
225 return NT_STATUS_INTERNAL_ERROR;
228 return NT_STATUS_OK;
231 /* generate a SID for the user with the RID algorithm */
233 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
235 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
236 return NT_STATUS_INTERNAL_ERROR;
239 return NT_STATUS_OK;
242 /********************************************************************
243 Set the Unix user attributes
244 ********************************************************************/
246 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
248 return samu_set_unix_internal( user, pwd, False );
251 NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
253 return samu_set_unix_internal( user, pwd, True );
256 /**********************************************************
257 Encode the account control bits into a string.
258 length = length of string to encode into (including terminating
259 null). length *MUST BE MORE THAN 2* !
260 **********************************************************/
262 char *pdb_encode_acct_ctrl(uint32 acct_ctrl, size_t length)
264 fstring acct_str;
265 char *result;
267 size_t i = 0;
269 SMB_ASSERT(length <= sizeof(acct_str));
271 acct_str[i++] = '[';
273 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
274 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
275 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
276 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
277 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
278 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
279 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
280 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
281 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
282 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
283 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
285 for ( ; i < length - 2 ; i++ )
286 acct_str[i] = ' ';
288 i = length - 2;
289 acct_str[i++] = ']';
290 acct_str[i++] = '\0';
292 result = talloc_strdup(talloc_tos(), acct_str);
293 SMB_ASSERT(result != NULL);
294 return result;
297 /**********************************************************
298 Decode the account control bits from a string.
299 **********************************************************/
301 uint32 pdb_decode_acct_ctrl(const char *p)
303 uint32 acct_ctrl = 0;
304 bool finished = False;
307 * Check if the account type bits have been encoded after the
308 * NT password (in the form [NDHTUWSLXI]).
311 if (*p != '[')
312 return 0;
314 for (p++; *p && !finished; p++) {
315 switch (*p) {
316 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
317 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
318 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
319 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
320 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
321 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
322 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
323 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
324 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
325 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
326 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
327 case ' ': { break; }
328 case ':':
329 case '\n':
330 case '\0':
331 case ']':
332 default: { finished = True; }
336 return acct_ctrl;
339 /*************************************************************
340 Routine to set 32 hex password characters from a 16 byte array.
341 **************************************************************/
343 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32 acct_ctrl)
345 if (pwd != NULL) {
346 int i;
347 for (i = 0; i < 16; i++)
348 slprintf(&p[i*2], 3, "%02X", pwd[i]);
349 } else {
350 if (acct_ctrl & ACB_PWNOTREQ)
351 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
352 else
353 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
357 /*************************************************************
358 Routine to get the 32 hex characters and turn them
359 into a 16 byte array.
360 **************************************************************/
362 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
364 int i;
365 unsigned char lonybble, hinybble;
366 const char *hexchars = "0123456789ABCDEF";
367 char *p1, *p2;
369 if (!p)
370 return (False);
372 for (i = 0; i < 32; i += 2) {
373 hinybble = toupper_ascii(p[i]);
374 lonybble = toupper_ascii(p[i + 1]);
376 p1 = strchr(hexchars, hinybble);
377 p2 = strchr(hexchars, lonybble);
379 if (!p1 || !p2)
380 return (False);
382 hinybble = PTR_DIFF(p1, hexchars);
383 lonybble = PTR_DIFF(p2, hexchars);
385 pwd[i / 2] = (hinybble << 4) | lonybble;
387 return (True);
390 /*************************************************************
391 Routine to set 42 hex hours characters from a 21 byte array.
392 **************************************************************/
394 void pdb_sethexhours(char *p, const unsigned char *hours)
396 if (hours != NULL) {
397 int i;
398 for (i = 0; i < 21; i++) {
399 slprintf(&p[i*2], 3, "%02X", hours[i]);
401 } else {
402 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
406 /*************************************************************
407 Routine to get the 42 hex characters and turn them
408 into a 21 byte array.
409 **************************************************************/
411 bool pdb_gethexhours(const char *p, unsigned char *hours)
413 int i;
414 unsigned char lonybble, hinybble;
415 const char *hexchars = "0123456789ABCDEF";
416 char *p1, *p2;
418 if (!p) {
419 return (False);
422 for (i = 0; i < 42; i += 2) {
423 hinybble = toupper_ascii(p[i]);
424 lonybble = toupper_ascii(p[i + 1]);
426 p1 = strchr(hexchars, hinybble);
427 p2 = strchr(hexchars, lonybble);
429 if (!p1 || !p2) {
430 return (False);
433 hinybble = PTR_DIFF(p1, hexchars);
434 lonybble = PTR_DIFF(p2, hexchars);
436 hours[i / 2] = (hinybble << 4) | lonybble;
438 return (True);
441 /********************************************************************
442 ********************************************************************/
444 int algorithmic_rid_base(void)
446 static int rid_offset = 0;
448 if (rid_offset != 0)
449 return rid_offset;
451 rid_offset = lp_algorithmic_rid_base();
453 if (rid_offset < BASE_RID) {
454 /* Try to prevent admin foot-shooting, we can't put algorithmic
455 rids below 1000, that's the 'well known RIDs' on NT */
456 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
457 rid_offset = BASE_RID;
459 if (rid_offset & 1) {
460 DEBUG(0, ("algorithmic rid base must be even\n"));
461 rid_offset += 1;
463 return rid_offset;
466 /*******************************************************************
467 Converts NT user RID to a UNIX uid.
468 ********************************************************************/
470 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
472 int rid_offset = algorithmic_rid_base();
473 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
476 uid_t max_algorithmic_uid(void)
478 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
481 /*******************************************************************
482 converts UNIX uid to an NT User RID.
483 ********************************************************************/
485 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
487 int rid_offset = algorithmic_rid_base();
488 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
491 /*******************************************************************
492 Converts NT group RID to a UNIX gid.
493 ********************************************************************/
495 gid_t pdb_group_rid_to_gid(uint32 group_rid)
497 int rid_offset = algorithmic_rid_base();
498 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
501 gid_t max_algorithmic_gid(void)
503 return pdb_group_rid_to_gid(0xffffffff);
506 /*******************************************************************
507 converts NT Group RID to a UNIX uid.
509 warning: you must not call that function only
510 you must do a call to the group mapping first.
511 there is not anymore a direct link between the gid and the rid.
512 ********************************************************************/
514 uint32 algorithmic_pdb_gid_to_group_rid(gid_t gid)
516 int rid_offset = algorithmic_rid_base();
517 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
520 /*******************************************************************
521 Decides if a RID is a well known RID.
522 ********************************************************************/
524 static bool rid_is_well_known(uint32 rid)
526 /* Not using rid_offset here, because this is the actual
527 NT fixed value (1000) */
529 return (rid < BASE_RID);
532 /*******************************************************************
533 Decides if a RID is a user or group RID.
534 ********************************************************************/
536 bool algorithmic_pdb_rid_is_user(uint32 rid)
538 if ( rid_is_well_known(rid) ) {
540 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
541 * and DOMAIN_USER_RID_GUEST.
543 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
544 return True;
545 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
546 return True;
548 return False;
551 /*******************************************************************
552 Convert a name into a SID. Used in the lookup name rpc.
553 ********************************************************************/
555 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
556 enum lsa_SidType *type)
558 GROUP_MAP map;
559 bool ret;
561 /* Windows treats "MACHINE\None" as a special name for
562 rid 513 on non-DCs. You cannot create a user or group
563 name "None" on Windows. You will get an error that
564 the group already exists. */
566 if ( strequal( name, "None" ) ) {
567 *rid = DOMAIN_GROUP_RID_USERS;
568 *type = SID_NAME_DOM_GRP;
570 return True;
573 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
574 * correctly in the case where foo also exists as a user. If the flag
575 * is set, don't look for users at all. */
577 if ((flags & LOOKUP_NAME_GROUP) == 0) {
578 struct samu *sam_account = NULL;
579 DOM_SID user_sid;
581 if ( !(sam_account = samu_new( NULL )) ) {
582 return False;
585 become_root();
586 ret = pdb_getsampwnam(sam_account, name);
587 unbecome_root();
589 if (ret) {
590 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
593 TALLOC_FREE(sam_account);
595 if (ret) {
596 if (!sid_check_is_in_our_domain(&user_sid)) {
597 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
598 name, sid_string_dbg(&user_sid)));
599 return False;
602 sid_peek_rid(&user_sid, rid);
603 *type = SID_NAME_USER;
604 return True;
609 * Maybe it is a group ?
612 become_root();
613 ret = pdb_getgrnam(&map, name);
614 unbecome_root();
616 if (!ret) {
617 return False;
620 /* BUILTIN groups are looked up elsewhere */
621 if (!sid_check_is_in_our_domain(&map.sid)) {
622 DEBUG(10, ("Found group %s (%s) not in our domain -- "
623 "ignoring.", name, sid_string_dbg(&map.sid)));
624 return False;
627 /* yes it's a mapped group */
628 sid_peek_rid(&map.sid, rid);
629 *type = map.sid_name_use;
630 return True;
633 /*************************************************************
634 Change a password entry in the local smbpasswd file.
635 *************************************************************/
637 NTSTATUS local_password_change(const char *user_name,
638 int local_flags,
639 const char *new_passwd,
640 char **pp_err_str,
641 char **pp_msg_str)
643 struct samu *sam_pass=NULL;
644 uint32 other_acb;
645 NTSTATUS result;
647 *pp_err_str = NULL;
648 *pp_msg_str = NULL;
650 /* Get the smb passwd entry for this user */
652 if ( !(sam_pass = samu_new( NULL )) ) {
653 return NT_STATUS_NO_MEMORY;
656 become_root();
657 if(!pdb_getsampwnam(sam_pass, user_name)) {
658 unbecome_root();
659 TALLOC_FREE(sam_pass);
661 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
662 int tmp_debug = DEBUGLEVEL;
663 struct passwd *pwd;
665 /* Might not exist in /etc/passwd. */
667 if (tmp_debug < 1) {
668 DEBUGLEVEL = 1;
671 if ( !(pwd = getpwnam_alloc( NULL, user_name)) ) {
672 return NT_STATUS_NO_SUCH_USER;
675 /* create the struct samu and initialize the basic Unix properties */
677 if ( !(sam_pass = samu_new( NULL )) ) {
678 return NT_STATUS_NO_MEMORY;
681 result = samu_set_unix( sam_pass, pwd );
683 DEBUGLEVEL = tmp_debug;
685 TALLOC_FREE( pwd );
687 if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) {
688 return result;
691 if (!NT_STATUS_IS_OK(result)) {
692 asprintf(pp_err_str, "Failed to " "initialize account for user %s: %s\n",
693 user_name, nt_errstr(result));
694 return result;
696 } else {
697 asprintf(pp_err_str, "Failed to find entry for user %s.\n", user_name);
698 return NT_STATUS_NO_SUCH_USER;
700 } else {
701 unbecome_root();
702 /* the entry already existed */
703 local_flags &= ~LOCAL_ADD_USER;
706 /* the 'other' acb bits not being changed here */
707 other_acb = (pdb_get_acct_ctrl(sam_pass) & (~(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
708 if (local_flags & LOCAL_TRUST_ACCOUNT) {
709 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
710 asprintf(pp_err_str, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
711 TALLOC_FREE(sam_pass);
712 return NT_STATUS_UNSUCCESSFUL;
714 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
715 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
716 asprintf(pp_err_str, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
717 TALLOC_FREE(sam_pass);
718 return NT_STATUS_UNSUCCESSFUL;
720 } else {
721 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
722 asprintf(pp_err_str, "Failed to set 'normal account' flags for user %s.\n", user_name);
723 TALLOC_FREE(sam_pass);
724 return NT_STATUS_UNSUCCESSFUL;
729 * We are root - just write the new password
730 * and the valid last change time.
733 if (local_flags & LOCAL_DISABLE_USER) {
734 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
735 asprintf(pp_err_str, "Failed to set 'disabled' flag for user %s.\n", user_name);
736 TALLOC_FREE(sam_pass);
737 return NT_STATUS_UNSUCCESSFUL;
739 } else if (local_flags & LOCAL_ENABLE_USER) {
740 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
741 asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name);
742 TALLOC_FREE(sam_pass);
743 return NT_STATUS_UNSUCCESSFUL;
747 if (local_flags & LOCAL_SET_NO_PASSWORD) {
748 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
749 asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name);
750 TALLOC_FREE(sam_pass);
751 return NT_STATUS_UNSUCCESSFUL;
753 } else if (local_flags & LOCAL_SET_PASSWORD) {
755 * If we're dealing with setting a completely empty user account
756 * ie. One with a password of 'XXXX', but not set disabled (like
757 * an account created from scratch) then if the old password was
758 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
759 * We remove that as we're giving this user their first password
760 * and the decision hasn't really been made to disable them (ie.
761 * don't create them disabled). JRA.
763 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
764 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
765 asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name);
766 TALLOC_FREE(sam_pass);
767 return NT_STATUS_UNSUCCESSFUL;
770 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
771 asprintf(pp_err_str, "Failed to unset 'no password required' flag for user %s.\n", user_name);
772 TALLOC_FREE(sam_pass);
773 return NT_STATUS_UNSUCCESSFUL;
776 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
777 asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name);
778 TALLOC_FREE(sam_pass);
779 return NT_STATUS_UNSUCCESSFUL;
783 if (local_flags & LOCAL_ADD_USER) {
784 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
785 asprintf(pp_msg_str, "Added user %s.\n", user_name);
786 TALLOC_FREE(sam_pass);
787 return NT_STATUS_OK;
788 } else {
789 asprintf(pp_err_str, "Failed to add entry for user %s.\n", user_name);
790 TALLOC_FREE(sam_pass);
791 return NT_STATUS_UNSUCCESSFUL;
793 } else if (local_flags & LOCAL_DELETE_USER) {
794 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
795 asprintf(pp_err_str, "Failed to delete entry for user %s.\n", user_name);
796 TALLOC_FREE(sam_pass);
797 return NT_STATUS_UNSUCCESSFUL;
799 asprintf(pp_msg_str, "Deleted user %s.\n", user_name);
800 } else {
801 result = pdb_update_sam_account(sam_pass);
802 if(!NT_STATUS_IS_OK(result)) {
803 asprintf(pp_err_str, "Failed to modify entry for user %s.\n", user_name);
804 TALLOC_FREE(sam_pass);
805 return result;
807 if(local_flags & LOCAL_DISABLE_USER)
808 asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
809 else if (local_flags & LOCAL_ENABLE_USER)
810 asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
811 else if (local_flags & LOCAL_SET_NO_PASSWORD)
812 asprintf(pp_msg_str, "User %s password set to none.\n", user_name);
815 TALLOC_FREE(sam_pass);
816 return NT_STATUS_OK;
819 /**********************************************************************
820 Marshall/unmarshall struct samu structs.
821 *********************************************************************/
823 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
825 /*********************************************************************
826 *********************************************************************/
828 bool init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
831 /* times are stored as 32bit integer
832 take care on system with 64bit wide time_t
833 --SSS */
834 uint32 logon_time,
835 logoff_time,
836 kickoff_time,
837 bad_password_time,
838 pass_last_set_time,
839 pass_can_change_time,
840 pass_must_change_time;
841 char *username = NULL;
842 char *domain = NULL;
843 char *nt_username = NULL;
844 char *dir_drive = NULL;
845 char *unknown_str = NULL;
846 char *munged_dial = NULL;
847 char *fullname = NULL;
848 char *homedir = NULL;
849 char *logon_script = NULL;
850 char *profile_path = NULL;
851 char *acct_desc = NULL;
852 char *workstations = NULL;
853 uint32 username_len, domain_len, nt_username_len,
854 dir_drive_len, unknown_str_len, munged_dial_len,
855 fullname_len, homedir_len, logon_script_len,
856 profile_path_len, acct_desc_len, workstations_len;
858 uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
859 uint16 logon_divs;
860 uint16 bad_password_count, logon_count;
861 uint8 *hours = NULL;
862 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
863 uint32 len = 0;
864 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
865 uint32 pwHistLen = 0;
866 bool ret = True;
867 fstring tmp_string;
868 bool expand_explicit = lp_passdb_expand_explicit();
870 if(sampass == NULL || buf == NULL) {
871 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
872 return False;
875 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
877 /* unpack the buffer into variables */
878 len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING_V3,
879 &logon_time, /* d */
880 &logoff_time, /* d */
881 &kickoff_time, /* d */
882 &bad_password_time, /* d */
883 &pass_last_set_time, /* d */
884 &pass_can_change_time, /* d */
885 &pass_must_change_time, /* d */
886 &username_len, &username, /* B */
887 &domain_len, &domain, /* B */
888 &nt_username_len, &nt_username, /* B */
889 &fullname_len, &fullname, /* B */
890 &homedir_len, &homedir, /* B */
891 &dir_drive_len, &dir_drive, /* B */
892 &logon_script_len, &logon_script, /* B */
893 &profile_path_len, &profile_path, /* B */
894 &acct_desc_len, &acct_desc, /* B */
895 &workstations_len, &workstations, /* B */
896 &unknown_str_len, &unknown_str, /* B */
897 &munged_dial_len, &munged_dial, /* B */
898 &user_rid, /* d */
899 &group_rid, /* d */
900 &lm_pw_len, &lm_pw_ptr, /* B */
901 &nt_pw_len, &nt_pw_ptr, /* B */
902 /* Change from V1 is addition of password history field. */
903 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
904 /* Change from V2 is the uint32 acb_mask */
905 &acct_ctrl, /* d */
906 /* Also "remove_me" field was removed. */
907 &logon_divs, /* w */
908 &hours_len, /* d */
909 &hourslen, &hours, /* B */
910 &bad_password_count, /* w */
911 &logon_count, /* w */
912 &unknown_6); /* d */
914 if (len == (uint32) -1) {
915 ret = False;
916 goto done;
919 pdb_set_logon_time(sampass, convert_uint32_to_time_t(logon_time), PDB_SET);
920 pdb_set_logoff_time(sampass, convert_uint32_to_time_t(logoff_time), PDB_SET);
921 pdb_set_kickoff_time(sampass, convert_uint32_to_time_t(kickoff_time), PDB_SET);
922 pdb_set_bad_password_time(sampass, convert_uint32_to_time_t(bad_password_time), PDB_SET);
923 pdb_set_pass_can_change_time(sampass, convert_uint32_to_time_t(pass_can_change_time), PDB_SET);
924 pdb_set_pass_must_change_time(sampass, convert_uint32_to_time_t(pass_must_change_time), PDB_SET);
925 pdb_set_pass_last_set_time(sampass, convert_uint32_to_time_t(pass_last_set_time), PDB_SET);
927 pdb_set_username(sampass, username, PDB_SET);
928 pdb_set_domain(sampass, domain, PDB_SET);
929 pdb_set_nt_username(sampass, nt_username, PDB_SET);
930 pdb_set_fullname(sampass, fullname, PDB_SET);
932 if (homedir) {
933 fstrcpy( tmp_string, homedir );
934 if (expand_explicit) {
935 standard_sub_basic( username, domain, tmp_string,
936 sizeof(tmp_string) );
938 pdb_set_homedir(sampass, tmp_string, PDB_SET);
940 else {
941 pdb_set_homedir(sampass,
942 talloc_sub_basic(sampass, username, domain,
943 lp_logon_home()),
944 PDB_DEFAULT);
947 if (dir_drive)
948 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
949 else
950 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
952 if (logon_script) {
953 fstrcpy( tmp_string, logon_script );
954 if (expand_explicit) {
955 standard_sub_basic( username, domain, tmp_string,
956 sizeof(tmp_string) );
958 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
960 else {
961 pdb_set_logon_script(sampass,
962 talloc_sub_basic(sampass, username, domain,
963 lp_logon_script()),
964 PDB_DEFAULT);
967 if (profile_path) {
968 fstrcpy( tmp_string, profile_path );
969 if (expand_explicit) {
970 standard_sub_basic( username, domain, tmp_string,
971 sizeof(tmp_string) );
973 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
975 else {
976 pdb_set_profile_path(sampass,
977 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
978 PDB_DEFAULT);
981 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
982 pdb_set_workstations(sampass, workstations, PDB_SET);
983 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
985 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
986 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
987 ret = False;
988 goto done;
992 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
993 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
994 ret = False;
995 goto done;
999 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1000 if (pwHistLen) {
1001 uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1002 if (!pw_hist) {
1003 ret = False;
1004 goto done;
1006 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1007 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1008 int i;
1009 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1010 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1011 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1012 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1013 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1014 PW_HISTORY_ENTRY_LEN);
1017 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1018 SAFE_FREE(pw_hist);
1019 ret = False;
1020 goto done;
1022 SAFE_FREE(pw_hist);
1023 } else {
1024 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1027 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1028 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1029 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1030 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1031 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1032 /* Change from V2 is the uint32 acct_ctrl */
1033 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1034 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1035 pdb_set_hours(sampass, hours, PDB_SET);
1037 done:
1039 SAFE_FREE(username);
1040 SAFE_FREE(domain);
1041 SAFE_FREE(nt_username);
1042 SAFE_FREE(fullname);
1043 SAFE_FREE(homedir);
1044 SAFE_FREE(dir_drive);
1045 SAFE_FREE(logon_script);
1046 SAFE_FREE(profile_path);
1047 SAFE_FREE(acct_desc);
1048 SAFE_FREE(workstations);
1049 SAFE_FREE(munged_dial);
1050 SAFE_FREE(unknown_str);
1051 SAFE_FREE(lm_pw_ptr);
1052 SAFE_FREE(nt_pw_ptr);
1053 SAFE_FREE(nt_pw_hist_ptr);
1054 SAFE_FREE(hours);
1056 return ret;
1059 /*********************************************************************
1060 *********************************************************************/
1062 uint32 init_buffer_from_sam_v3 (uint8 **buf, struct samu *sampass, bool size_only)
1064 size_t len, buflen;
1066 /* times are stored as 32bit integer
1067 take care on system with 64bit wide time_t
1068 --SSS */
1069 uint32 logon_time,
1070 logoff_time,
1071 kickoff_time,
1072 bad_password_time,
1073 pass_last_set_time,
1074 pass_can_change_time,
1075 pass_must_change_time;
1077 uint32 user_rid, group_rid;
1079 const char *username;
1080 const char *domain;
1081 const char *nt_username;
1082 const char *dir_drive;
1083 const char *unknown_str;
1084 const char *munged_dial;
1085 const char *fullname;
1086 const char *homedir;
1087 const char *logon_script;
1088 const char *profile_path;
1089 const char *acct_desc;
1090 const char *workstations;
1091 uint32 username_len, domain_len, nt_username_len,
1092 dir_drive_len, unknown_str_len, munged_dial_len,
1093 fullname_len, homedir_len, logon_script_len,
1094 profile_path_len, acct_desc_len, workstations_len;
1096 const uint8 *lm_pw;
1097 const uint8 *nt_pw;
1098 const uint8 *nt_pw_hist;
1099 uint32 lm_pw_len = 16;
1100 uint32 nt_pw_len = 16;
1101 uint32 nt_pw_hist_len;
1102 uint32 pwHistLen = 0;
1104 *buf = NULL;
1105 buflen = 0;
1107 logon_time = convert_time_t_to_uint32(pdb_get_logon_time(sampass));
1108 logoff_time = convert_time_t_to_uint32(pdb_get_logoff_time(sampass));
1109 kickoff_time = convert_time_t_to_uint32(pdb_get_kickoff_time(sampass));
1110 bad_password_time = convert_time_t_to_uint32(pdb_get_bad_password_time(sampass));
1111 pass_can_change_time = convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass));
1112 pass_must_change_time = convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass));
1113 pass_last_set_time = convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass));
1115 user_rid = pdb_get_user_rid(sampass);
1116 group_rid = pdb_get_group_rid(sampass);
1118 username = pdb_get_username(sampass);
1119 if (username) {
1120 username_len = strlen(username) +1;
1121 } else {
1122 username_len = 0;
1125 domain = pdb_get_domain(sampass);
1126 if (domain) {
1127 domain_len = strlen(domain) +1;
1128 } else {
1129 domain_len = 0;
1132 nt_username = pdb_get_nt_username(sampass);
1133 if (nt_username) {
1134 nt_username_len = strlen(nt_username) +1;
1135 } else {
1136 nt_username_len = 0;
1139 fullname = pdb_get_fullname(sampass);
1140 if (fullname) {
1141 fullname_len = strlen(fullname) +1;
1142 } else {
1143 fullname_len = 0;
1147 * Only updates fields which have been set (not defaults from smb.conf)
1150 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1151 dir_drive = pdb_get_dir_drive(sampass);
1152 } else {
1153 dir_drive = NULL;
1155 if (dir_drive) {
1156 dir_drive_len = strlen(dir_drive) +1;
1157 } else {
1158 dir_drive_len = 0;
1161 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1162 homedir = pdb_get_homedir(sampass);
1163 } else {
1164 homedir = NULL;
1166 if (homedir) {
1167 homedir_len = strlen(homedir) +1;
1168 } else {
1169 homedir_len = 0;
1172 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1173 logon_script = pdb_get_logon_script(sampass);
1174 } else {
1175 logon_script = NULL;
1177 if (logon_script) {
1178 logon_script_len = strlen(logon_script) +1;
1179 } else {
1180 logon_script_len = 0;
1183 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1184 profile_path = pdb_get_profile_path(sampass);
1185 } else {
1186 profile_path = NULL;
1188 if (profile_path) {
1189 profile_path_len = strlen(profile_path) +1;
1190 } else {
1191 profile_path_len = 0;
1194 lm_pw = pdb_get_lanman_passwd(sampass);
1195 if (!lm_pw) {
1196 lm_pw_len = 0;
1199 nt_pw = pdb_get_nt_passwd(sampass);
1200 if (!nt_pw) {
1201 nt_pw_len = 0;
1204 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1205 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1206 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1207 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1208 } else {
1209 nt_pw_hist_len = 0;
1212 acct_desc = pdb_get_acct_desc(sampass);
1213 if (acct_desc) {
1214 acct_desc_len = strlen(acct_desc) +1;
1215 } else {
1216 acct_desc_len = 0;
1219 workstations = pdb_get_workstations(sampass);
1220 if (workstations) {
1221 workstations_len = strlen(workstations) +1;
1222 } else {
1223 workstations_len = 0;
1226 unknown_str = NULL;
1227 unknown_str_len = 0;
1229 munged_dial = pdb_get_munged_dial(sampass);
1230 if (munged_dial) {
1231 munged_dial_len = strlen(munged_dial) +1;
1232 } else {
1233 munged_dial_len = 0;
1236 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1238 /* one time to get the size needed */
1239 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V3,
1240 logon_time, /* d */
1241 logoff_time, /* d */
1242 kickoff_time, /* d */
1243 bad_password_time, /* d */
1244 pass_last_set_time, /* d */
1245 pass_can_change_time, /* d */
1246 pass_must_change_time, /* d */
1247 username_len, username, /* B */
1248 domain_len, domain, /* B */
1249 nt_username_len, nt_username, /* B */
1250 fullname_len, fullname, /* B */
1251 homedir_len, homedir, /* B */
1252 dir_drive_len, dir_drive, /* B */
1253 logon_script_len, logon_script, /* B */
1254 profile_path_len, profile_path, /* B */
1255 acct_desc_len, acct_desc, /* B */
1256 workstations_len, workstations, /* B */
1257 unknown_str_len, unknown_str, /* B */
1258 munged_dial_len, munged_dial, /* B */
1259 user_rid, /* d */
1260 group_rid, /* d */
1261 lm_pw_len, lm_pw, /* B */
1262 nt_pw_len, nt_pw, /* B */
1263 nt_pw_hist_len, nt_pw_hist, /* B */
1264 pdb_get_acct_ctrl(sampass), /* d */
1265 pdb_get_logon_divs(sampass), /* w */
1266 pdb_get_hours_len(sampass), /* d */
1267 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1268 pdb_get_bad_password_count(sampass), /* w */
1269 pdb_get_logon_count(sampass), /* w */
1270 pdb_get_unknown_6(sampass)); /* d */
1272 if (size_only) {
1273 return buflen;
1276 /* malloc the space needed */
1277 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
1278 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1279 return (-1);
1282 /* now for the real call to tdb_pack() */
1283 buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING_V3,
1284 logon_time, /* d */
1285 logoff_time, /* d */
1286 kickoff_time, /* d */
1287 bad_password_time, /* d */
1288 pass_last_set_time, /* d */
1289 pass_can_change_time, /* d */
1290 pass_must_change_time, /* d */
1291 username_len, username, /* B */
1292 domain_len, domain, /* B */
1293 nt_username_len, nt_username, /* B */
1294 fullname_len, fullname, /* B */
1295 homedir_len, homedir, /* B */
1296 dir_drive_len, dir_drive, /* B */
1297 logon_script_len, logon_script, /* B */
1298 profile_path_len, profile_path, /* B */
1299 acct_desc_len, acct_desc, /* B */
1300 workstations_len, workstations, /* B */
1301 unknown_str_len, unknown_str, /* B */
1302 munged_dial_len, munged_dial, /* B */
1303 user_rid, /* d */
1304 group_rid, /* d */
1305 lm_pw_len, lm_pw, /* B */
1306 nt_pw_len, nt_pw, /* B */
1307 nt_pw_hist_len, nt_pw_hist, /* B */
1308 pdb_get_acct_ctrl(sampass), /* d */
1309 pdb_get_logon_divs(sampass), /* w */
1310 pdb_get_hours_len(sampass), /* d */
1311 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1312 pdb_get_bad_password_count(sampass), /* w */
1313 pdb_get_logon_count(sampass), /* w */
1314 pdb_get_unknown_6(sampass)); /* d */
1316 /* check to make sure we got it correct */
1317 if (buflen != len) {
1318 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1319 (unsigned long)buflen, (unsigned long)len));
1320 /* error */
1321 SAFE_FREE (*buf);
1322 return (-1);
1325 return (buflen);
1329 /*********************************************************************
1330 *********************************************************************/
1332 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
1334 uint8 *buf = NULL;
1335 int len;
1337 len = init_buffer_from_sam_v3(&buf, src, False);
1338 if (len == -1 || !buf) {
1339 SAFE_FREE(buf);
1340 return False;
1343 if (!init_sam_from_buffer_v3( dst, buf, len )) {
1344 free(buf);
1345 return False;
1348 dst->methods = src->methods;
1350 if ( src->unix_pw ) {
1351 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
1352 if (!dst->unix_pw) {
1353 free(buf);
1354 return False;
1358 free(buf);
1359 return True;
1362 /*********************************************************************
1363 Update the bad password count checking the AP_RESET_COUNT_TIME
1364 *********************************************************************/
1366 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
1368 time_t LastBadPassword;
1369 uint16 BadPasswordCount;
1370 uint32 resettime;
1371 bool res;
1373 BadPasswordCount = pdb_get_bad_password_count(sampass);
1374 if (!BadPasswordCount) {
1375 DEBUG(9, ("No bad password attempts.\n"));
1376 return True;
1379 become_root();
1380 res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime);
1381 unbecome_root();
1383 if (!res) {
1384 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1385 return False;
1388 /* First, check if there is a reset time to compare */
1389 if ((resettime == (uint32) -1) || (resettime == 0)) {
1390 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1391 return True;
1394 LastBadPassword = pdb_get_bad_password_time(sampass);
1395 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1396 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
1397 if (time(NULL) > (LastBadPassword + convert_uint32_to_time_t(resettime)*60)){
1398 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1399 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1400 if (updated) {
1401 *updated = True;
1405 return True;
1408 /*********************************************************************
1409 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1410 *********************************************************************/
1412 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
1414 uint32 duration;
1415 time_t LastBadPassword;
1416 bool res;
1418 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
1419 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1420 pdb_get_username(sampass)));
1421 return True;
1424 become_root();
1425 res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration);
1426 unbecome_root();
1428 if (!res) {
1429 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1430 return False;
1433 /* First, check if there is a duration to compare */
1434 if ((duration == (uint32) -1) || (duration == 0)) {
1435 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1436 return True;
1439 LastBadPassword = pdb_get_bad_password_time(sampass);
1440 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1441 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
1443 if (LastBadPassword == (time_t)0) {
1444 DEBUG(1,("pdb_update_autolock_flag: Account %s "
1445 "administratively locked out with no bad password "
1446 "time. Leaving locked out.\n",
1447 pdb_get_username(sampass) ));
1448 return True;
1451 if ((time(NULL) > (LastBadPassword + convert_uint32_to_time_t(duration) * 60))) {
1452 pdb_set_acct_ctrl(sampass,
1453 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
1454 PDB_CHANGED);
1455 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1456 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1457 if (updated) {
1458 *updated = True;
1462 return True;
1465 /*********************************************************************
1466 Increment the bad_password_count
1467 *********************************************************************/
1469 bool pdb_increment_bad_password_count(struct samu *sampass)
1471 uint32 account_policy_lockout;
1472 bool autolock_updated = False, badpw_updated = False;
1473 bool ret;
1475 /* Retrieve the account lockout policy */
1476 become_root();
1477 ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
1478 unbecome_root();
1479 if ( !ret ) {
1480 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1481 return False;
1484 /* If there is no policy, we don't need to continue checking */
1485 if (!account_policy_lockout) {
1486 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1487 return True;
1490 /* Check if the autolock needs to be cleared */
1491 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
1492 return False;
1494 /* Check if the badpw count needs to be reset */
1495 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
1496 return False;
1499 Ok, now we can assume that any resetting that needs to be
1500 done has been done, and just get on with incrementing
1501 and autolocking if necessary
1504 pdb_set_bad_password_count(sampass,
1505 pdb_get_bad_password_count(sampass)+1,
1506 PDB_CHANGED);
1507 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
1510 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
1511 return True;
1513 if (!pdb_set_acct_ctrl(sampass,
1514 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
1515 PDB_CHANGED)) {
1516 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
1517 return False;
1520 return True;
1523 bool is_trusted_domain_situation(const char *domain_name)
1525 return IS_DC &&
1526 lp_allow_trusted_domains() &&
1527 !strequal(domain_name, lp_workgroup());
1530 /*******************************************************************
1531 Wrapper around retrieving the clear text trust account password.
1532 appropriate account name is stored in account_name.
1533 Caller must free password, but not account_name.
1534 *******************************************************************/
1536 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
1537 const char **account_name, uint32 *channel)
1539 char *pwd;
1540 time_t last_set_time;
1542 /* if we are a DC and this is not our domain, then lookup an account
1543 * for the domain trust */
1545 if (is_trusted_domain_situation(domain)) {
1546 if (!pdb_get_trusteddom_pw(domain, ret_pwd, NULL,
1547 &last_set_time))
1549 DEBUG(0, ("get_trust_pw: could not fetch trust "
1550 "account password for trusted domain %s\n",
1551 domain));
1552 return false;
1555 if (channel != NULL) {
1556 *channel = SEC_CHAN_DOMAIN;
1559 if (account_name != NULL) {
1560 *account_name = lp_workgroup();
1563 return true;
1566 /* Just get the account for the requested domain. In the future this
1567 * might also cover to be member of more than one domain. */
1569 pwd = secrets_fetch_machine_password(domain, &last_set_time, channel);
1571 if (pwd != NULL) {
1572 *ret_pwd = pwd;
1573 if (account_name != NULL) {
1574 *account_name = global_myname();
1577 return true;
1580 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
1581 "account password for domain %s\n", domain));
1582 return false;
1585 /*******************************************************************
1586 Wrapper around retrieving the trust account password.
1587 appropriate account name is stored in account_name.
1588 *******************************************************************/
1590 bool get_trust_pw_hash(const char *domain, uint8 ret_pwd[16],
1591 const char **account_name, uint32 *channel)
1593 char *pwd = NULL;
1594 time_t last_set_time;
1596 if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
1597 E_md4hash(pwd, ret_pwd);
1598 SAFE_FREE(pwd);
1599 return true;
1600 } else if (is_trusted_domain_situation(domain)) {
1601 return false;
1604 /* as a fallback, try to get the hashed pwd directly from the tdb... */
1606 if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
1607 &last_set_time,
1608 channel))
1610 if (account_name != NULL) {
1611 *account_name = global_myname();
1614 return true;
1617 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
1618 "password for domain %s\n", domain));
1619 return False;