s4-dsdb_schema: Copy info needed for Schema refresh in dsdb_schema_copy_shallow
[Samba.git] / source3 / passdb / passdb.c
blobdafe55eef756fa3cbb77b8d59888e9e57e594cfd
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"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "secrets.h"
28 #include "../libcli/security/security.h"
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_PASSDB
33 /******************************************************************
34 Get the default domain/netbios name to be used when
35 testing authentication.
37 LEGACY: this function provides the legacy domain mapping used with
38 the lp_map_untrusted_to_domain() parameter
39 ******************************************************************/
41 const char *my_sam_name(void)
43 /* Standalone servers can only use the local netbios name */
44 if ( lp_server_role() == ROLE_STANDALONE )
45 return global_myname();
47 /* Default to the DOMAIN name when not specified */
48 return lp_workgroup();
51 /**********************************************************************
52 ***********************************************************************/
54 static int samu_destroy(struct samu *user)
56 data_blob_clear_free( &user->lm_pw );
57 data_blob_clear_free( &user->nt_pw );
59 if ( user->plaintext_pw )
60 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
62 return 0;
65 /**********************************************************************
66 generate a new struct samuser
67 ***********************************************************************/
69 struct samu *samu_new( TALLOC_CTX *ctx )
71 struct samu *user;
73 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
74 DEBUG(0,("samuser_new: Talloc failed!\n"));
75 return NULL;
78 talloc_set_destructor( user, samu_destroy );
80 /* no initial methods */
82 user->methods = NULL;
84 /* Don't change these timestamp settings without a good reason.
85 They are important for NT member server compatibility. */
87 user->logon_time = (time_t)0;
88 user->pass_last_set_time = (time_t)0;
89 user->pass_can_change_time = (time_t)0;
90 user->logoff_time = get_time_t_max();
91 user->kickoff_time = get_time_t_max();
92 user->pass_must_change_time = get_time_t_max();
93 user->fields_present = 0x00ffffff;
94 user->logon_divs = 168; /* hours per week */
95 user->hours_len = 21; /* 21 times 8 bits = 168 */
96 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
97 user->bad_password_count = 0;
98 user->logon_count = 0;
99 user->unknown_6 = 0x000004ec; /* don't know */
101 /* Some parts of samba strlen their pdb_get...() returns,
102 so this keeps the interface unchanged for now. */
104 user->username = "";
105 user->domain = "";
106 user->nt_username = "";
107 user->full_name = "";
108 user->home_dir = "";
109 user->logon_script = "";
110 user->profile_path = "";
111 user->acct_desc = "";
112 user->workstations = "";
113 user->comment = "";
114 user->munged_dial = "";
116 user->plaintext_pw = NULL;
118 /* Unless we know otherwise have a Account Control Bit
119 value of 'normal user'. This helps User Manager, which
120 asks for a filtered list of users. */
122 user->acct_ctrl = ACB_NORMAL;
124 return user;
127 static int count_commas(const char *str)
129 int num_commas = 0;
130 const char *comma = str;
132 while ((comma = strchr(comma, ',')) != NULL) {
133 comma += 1;
134 num_commas += 1;
136 return num_commas;
139 /*********************************************************************
140 Initialize a struct samu from a struct passwd including the user
141 and group SIDs. The *user structure is filled out with the Unix
142 attributes and a user SID.
143 *********************************************************************/
145 static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, bool create)
147 const char *guest_account = lp_guestaccount();
148 const char *domain = global_myname();
149 char *fullname;
150 uint32_t urid;
152 if ( !pwd ) {
153 return NT_STATUS_NO_SUCH_USER;
156 /* Basic properties based upon the Unix account information */
158 pdb_set_username(user, pwd->pw_name, PDB_SET);
160 fullname = NULL;
162 if (count_commas(pwd->pw_gecos) == 3) {
164 * Heuristic: This seems to be a gecos field that has been
165 * edited by chfn(1). Only use the part before the first
166 * comma. Fixes bug 5198.
168 fullname = talloc_strndup(
169 talloc_tos(), pwd->pw_gecos,
170 strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
173 if (fullname != NULL) {
174 pdb_set_fullname(user, fullname, PDB_SET);
175 } else {
176 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
178 TALLOC_FREE(fullname);
180 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
181 #if 0
182 /* This can lead to a primary group of S-1-22-2-XX which
183 will be rejected by other parts of the Samba code.
184 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
185 --jerry */
187 gid_to_sid(&group_sid, pwd->pw_gid);
188 pdb_set_group_sid(user, &group_sid, PDB_SET);
189 #endif
191 /* save the password structure for later use */
193 user->unix_pw = tcopy_passwd( user, pwd );
195 /* Special case for the guest account which must have a RID of 501 */
197 if ( strequal( pwd->pw_name, guest_account ) ) {
198 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
199 return NT_STATUS_NO_SUCH_USER;
201 return NT_STATUS_OK;
204 /* Non-guest accounts...Check for a workstation or user account */
206 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
207 /* workstation */
209 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
210 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
211 pwd->pw_name));
212 return NT_STATUS_INVALID_COMPUTER_NAME;
215 else {
216 /* user */
218 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
219 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
220 pwd->pw_name));
221 return NT_STATUS_INVALID_ACCOUNT_NAME;
224 /* set some basic attributes */
226 pdb_set_profile_path(user, talloc_sub_specified(user,
227 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
228 PDB_DEFAULT);
229 pdb_set_homedir(user, talloc_sub_specified(user,
230 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
231 PDB_DEFAULT);
232 pdb_set_dir_drive(user, talloc_sub_specified(user,
233 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
234 PDB_DEFAULT);
235 pdb_set_logon_script(user, talloc_sub_specified(user,
236 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
237 PDB_DEFAULT);
240 /* Now deal with the user SID. If we have a backend that can generate
241 RIDs, then do so. But sometimes the caller just wanted a structure
242 initialized and will fill in these fields later (such as from a
243 netr_SamInfo3 structure) */
245 if ( create && (pdb_capabilities() & PDB_CAP_STORE_RIDS)) {
246 uint32_t user_rid;
247 struct dom_sid user_sid;
249 if ( !pdb_new_rid( &user_rid ) ) {
250 DEBUG(3, ("Could not allocate a new RID\n"));
251 return NT_STATUS_ACCESS_DENIED;
254 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
256 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
257 DEBUG(3, ("pdb_set_user_sid failed\n"));
258 return NT_STATUS_INTERNAL_ERROR;
261 return NT_STATUS_OK;
264 /* generate a SID for the user with the RID algorithm */
266 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
268 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
269 return NT_STATUS_INTERNAL_ERROR;
272 return NT_STATUS_OK;
275 /********************************************************************
276 Set the Unix user attributes
277 ********************************************************************/
279 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
281 return samu_set_unix_internal( user, pwd, False );
284 NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
286 return samu_set_unix_internal( user, pwd, True );
289 /**********************************************************
290 Encode the account control bits into a string.
291 length = length of string to encode into (including terminating
292 null). length *MUST BE MORE THAN 2* !
293 **********************************************************/
295 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
297 fstring acct_str;
298 char *result;
300 size_t i = 0;
302 SMB_ASSERT(length <= sizeof(acct_str));
304 acct_str[i++] = '[';
306 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
307 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
308 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
309 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
310 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
311 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
312 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
313 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
314 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
315 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
316 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
318 for ( ; i < length - 2 ; i++ )
319 acct_str[i] = ' ';
321 i = length - 2;
322 acct_str[i++] = ']';
323 acct_str[i++] = '\0';
325 result = talloc_strdup(talloc_tos(), acct_str);
326 SMB_ASSERT(result != NULL);
327 return result;
330 /**********************************************************
331 Decode the account control bits from a string.
332 **********************************************************/
334 uint32_t pdb_decode_acct_ctrl(const char *p)
336 uint32_t acct_ctrl = 0;
337 bool finished = false;
340 * Check if the account type bits have been encoded after the
341 * NT password (in the form [NDHTUWSLXI]).
344 if (*p != '[')
345 return 0;
347 for (p++; *p && !finished; p++) {
348 switch (*p) {
349 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
350 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
351 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
352 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
353 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
354 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
355 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
356 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
357 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
358 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
359 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
360 case ' ': { break; }
361 case ':':
362 case '\n':
363 case '\0':
364 case ']':
365 default: { finished = true; }
369 return acct_ctrl;
372 /*************************************************************
373 Routine to set 32 hex password characters from a 16 byte array.
374 **************************************************************/
376 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
378 if (pwd != NULL) {
379 int i;
380 for (i = 0; i < 16; i++)
381 slprintf(&p[i*2], 3, "%02X", pwd[i]);
382 } else {
383 if (acct_ctrl & ACB_PWNOTREQ)
384 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
385 else
386 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
390 /*************************************************************
391 Routine to get the 32 hex characters and turn them
392 into a 16 byte array.
393 **************************************************************/
395 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
397 int i;
398 unsigned char lonybble, hinybble;
399 const char *hexchars = "0123456789ABCDEF";
400 char *p1, *p2;
402 if (!p)
403 return false;
405 for (i = 0; i < 32; i += 2) {
406 hinybble = toupper_ascii(p[i]);
407 lonybble = toupper_ascii(p[i + 1]);
409 p1 = strchr(hexchars, hinybble);
410 p2 = strchr(hexchars, lonybble);
412 if (!p1 || !p2)
413 return false;
415 hinybble = PTR_DIFF(p1, hexchars);
416 lonybble = PTR_DIFF(p2, hexchars);
418 pwd[i / 2] = (hinybble << 4) | lonybble;
420 return true;
423 /*************************************************************
424 Routine to set 42 hex hours characters from a 21 byte array.
425 **************************************************************/
427 void pdb_sethexhours(char *p, const unsigned char *hours)
429 if (hours != NULL) {
430 int i;
431 for (i = 0; i < 21; i++) {
432 slprintf(&p[i*2], 3, "%02X", hours[i]);
434 } else {
435 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
439 /*************************************************************
440 Routine to get the 42 hex characters and turn them
441 into a 21 byte array.
442 **************************************************************/
444 bool pdb_gethexhours(const char *p, unsigned char *hours)
446 int i;
447 unsigned char lonybble, hinybble;
448 const char *hexchars = "0123456789ABCDEF";
449 char *p1, *p2;
451 if (!p) {
452 return (False);
455 for (i = 0; i < 42; i += 2) {
456 hinybble = toupper_ascii(p[i]);
457 lonybble = toupper_ascii(p[i + 1]);
459 p1 = strchr(hexchars, hinybble);
460 p2 = strchr(hexchars, lonybble);
462 if (!p1 || !p2) {
463 return (False);
466 hinybble = PTR_DIFF(p1, hexchars);
467 lonybble = PTR_DIFF(p2, hexchars);
469 hours[i / 2] = (hinybble << 4) | lonybble;
471 return (True);
474 /********************************************************************
475 ********************************************************************/
477 int algorithmic_rid_base(void)
479 int rid_offset;
481 rid_offset = lp_algorithmic_rid_base();
483 if (rid_offset < BASE_RID) {
484 /* Try to prevent admin foot-shooting, we can't put algorithmic
485 rids below 1000, that's the 'well known RIDs' on NT */
486 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
487 rid_offset = BASE_RID;
489 if (rid_offset & 1) {
490 DEBUG(0, ("algorithmic rid base must be even\n"));
491 rid_offset += 1;
493 return rid_offset;
496 /*******************************************************************
497 Converts NT user RID to a UNIX uid.
498 ********************************************************************/
500 uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
502 int rid_offset = algorithmic_rid_base();
503 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
506 uid_t max_algorithmic_uid(void)
508 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
511 /*******************************************************************
512 converts UNIX uid to an NT User RID.
513 ********************************************************************/
515 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
517 int rid_offset = algorithmic_rid_base();
518 return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
521 /*******************************************************************
522 Converts NT group RID to a UNIX gid.
523 ********************************************************************/
525 gid_t pdb_group_rid_to_gid(uint32_t group_rid)
527 int rid_offset = algorithmic_rid_base();
528 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
531 gid_t max_algorithmic_gid(void)
533 return pdb_group_rid_to_gid(0xffffffff);
536 /*******************************************************************
537 converts NT Group RID to a UNIX uid.
539 warning: you must not call that function only
540 you must do a call to the group mapping first.
541 there is not anymore a direct link between the gid and the rid.
542 ********************************************************************/
544 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
546 int rid_offset = algorithmic_rid_base();
547 return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
550 /*******************************************************************
551 Decides if a RID is a well known RID.
552 ********************************************************************/
554 static bool rid_is_well_known(uint32_t rid)
556 /* Not using rid_offset here, because this is the actual
557 NT fixed value (1000) */
559 return (rid < BASE_RID);
562 /*******************************************************************
563 Decides if a RID is a user or group RID.
564 ********************************************************************/
566 bool algorithmic_pdb_rid_is_user(uint32_t rid)
568 if ( rid_is_well_known(rid) ) {
570 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
571 * and DOMAIN_RID_GUEST.
573 if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
574 return True;
575 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
576 return True;
578 return False;
581 /*******************************************************************
582 Convert a name into a SID. Used in the lookup name rpc.
583 ********************************************************************/
585 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
586 enum lsa_SidType *type)
588 GROUP_MAP map;
589 bool ret;
591 /* Windows treats "MACHINE\None" as a special name for
592 rid 513 on non-DCs. You cannot create a user or group
593 name "None" on Windows. You will get an error that
594 the group already exists. */
596 if ( strequal( name, "None" ) ) {
597 *rid = DOMAIN_RID_USERS;
598 *type = SID_NAME_DOM_GRP;
600 return True;
603 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
604 * correctly in the case where foo also exists as a user. If the flag
605 * is set, don't look for users at all. */
607 if ((flags & LOOKUP_NAME_GROUP) == 0) {
608 struct samu *sam_account = NULL;
609 struct dom_sid user_sid;
611 if ( !(sam_account = samu_new( NULL )) ) {
612 return False;
615 become_root();
616 ret = pdb_getsampwnam(sam_account, name);
617 unbecome_root();
619 if (ret) {
620 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
623 TALLOC_FREE(sam_account);
625 if (ret) {
626 if (!sid_check_is_in_our_domain(&user_sid)) {
627 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
628 name, sid_string_dbg(&user_sid)));
629 return False;
632 sid_peek_rid(&user_sid, rid);
633 *type = SID_NAME_USER;
634 return True;
639 * Maybe it is a group ?
642 become_root();
643 ret = pdb_getgrnam(&map, name);
644 unbecome_root();
646 if (!ret) {
647 return False;
650 /* BUILTIN groups are looked up elsewhere */
651 if (!sid_check_is_in_our_domain(&map.sid)) {
652 DEBUG(10, ("Found group %s (%s) not in our domain -- "
653 "ignoring.", name, sid_string_dbg(&map.sid)));
654 return False;
657 /* yes it's a mapped group */
658 sid_peek_rid(&map.sid, rid);
659 *type = map.sid_name_use;
660 return True;
663 /*************************************************************
664 Change a password entry in the local passdb backend.
666 Assumptions:
667 - always called as root
668 - ignores the account type except when adding a new account
669 - will create/delete the unix account if the relative
670 add/delete user script is configured
672 *************************************************************/
674 NTSTATUS local_password_change(const char *user_name,
675 int local_flags,
676 const char *new_passwd,
677 char **pp_err_str,
678 char **pp_msg_str)
680 TALLOC_CTX *tosctx;
681 struct samu *sam_pass;
682 uint32_t acb;
683 uint32_t rid;
684 NTSTATUS result;
685 bool user_exists;
686 int ret = -1;
688 *pp_err_str = NULL;
689 *pp_msg_str = NULL;
691 tosctx = talloc_tos();
693 sam_pass = samu_new(tosctx);
694 if (!sam_pass) {
695 result = NT_STATUS_NO_MEMORY;
696 goto done;
699 /* Get the smb passwd entry for this user */
700 user_exists = pdb_getsampwnam(sam_pass, user_name);
702 /* Check delete first, we don't need to do anything else if we
703 * are going to delete the acocunt */
704 if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
706 result = pdb_delete_user(tosctx, sam_pass);
707 if (!NT_STATUS_IS_OK(result)) {
708 ret = asprintf(pp_err_str,
709 "Failed to delete entry for user %s.\n",
710 user_name);
711 if (ret < 0) {
712 *pp_err_str = NULL;
714 result = NT_STATUS_UNSUCCESSFUL;
715 } else {
716 ret = asprintf(pp_msg_str,
717 "Deleted user %s.\n",
718 user_name);
719 if (ret < 0) {
720 *pp_msg_str = NULL;
723 goto done;
726 if (user_exists && (local_flags & LOCAL_ADD_USER)) {
727 /* the entry already existed */
728 local_flags &= ~LOCAL_ADD_USER;
731 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
732 ret = asprintf(pp_err_str,
733 "Failed to find entry for user %s.\n",
734 user_name);
735 if (ret < 0) {
736 *pp_err_str = NULL;
738 result = NT_STATUS_NO_SUCH_USER;
739 goto done;
742 /* First thing add the new user if we are required to do so */
743 if (local_flags & LOCAL_ADD_USER) {
745 if (local_flags & LOCAL_TRUST_ACCOUNT) {
746 acb = ACB_WSTRUST;
747 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
748 acb = ACB_DOMTRUST;
749 } else {
750 acb = ACB_NORMAL;
753 result = pdb_create_user(tosctx, user_name, acb, &rid);
754 if (!NT_STATUS_IS_OK(result)) {
755 ret = asprintf(pp_err_str,
756 "Failed to add entry for user %s.\n",
757 user_name);
758 if (ret < 0) {
759 *pp_err_str = NULL;
761 result = NT_STATUS_UNSUCCESSFUL;
762 goto done;
765 sam_pass = samu_new(tosctx);
766 if (!sam_pass) {
767 result = NT_STATUS_NO_MEMORY;
768 goto done;
771 /* Now get back the smb passwd entry for this new user */
772 user_exists = pdb_getsampwnam(sam_pass, user_name);
773 if (!user_exists) {
774 ret = asprintf(pp_err_str,
775 "Failed to add entry for user %s.\n",
776 user_name);
777 if (ret < 0) {
778 *pp_err_str = NULL;
780 result = NT_STATUS_UNSUCCESSFUL;
781 goto done;
785 acb = pdb_get_acct_ctrl(sam_pass);
788 * We are root - just write the new password
789 * and the valid last change time.
791 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
792 acb |= ACB_PWNOTREQ;
793 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
794 ret = asprintf(pp_err_str,
795 "Failed to set 'no password required' "
796 "flag for user %s.\n", user_name);
797 if (ret < 0) {
798 *pp_err_str = NULL;
800 result = NT_STATUS_UNSUCCESSFUL;
801 goto done;
805 if (local_flags & LOCAL_SET_PASSWORD) {
807 * If we're dealing with setting a completely empty user account
808 * ie. One with a password of 'XXXX', but not set disabled (like
809 * an account created from scratch) then if the old password was
810 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
811 * We remove that as we're giving this user their first password
812 * and the decision hasn't really been made to disable them (ie.
813 * don't create them disabled). JRA.
815 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
816 (acb & ACB_DISABLED)) {
817 acb &= (~ACB_DISABLED);
818 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
819 ret = asprintf(pp_err_str,
820 "Failed to unset 'disabled' "
821 "flag for user %s.\n",
822 user_name);
823 if (ret < 0) {
824 *pp_err_str = NULL;
826 result = NT_STATUS_UNSUCCESSFUL;
827 goto done;
831 acb &= (~ACB_PWNOTREQ);
832 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
833 ret = asprintf(pp_err_str,
834 "Failed to unset 'no password required'"
835 " flag for user %s.\n", user_name);
836 if (ret < 0) {
837 *pp_err_str = NULL;
839 result = NT_STATUS_UNSUCCESSFUL;
840 goto done;
843 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
844 ret = asprintf(pp_err_str,
845 "Failed to set password for "
846 "user %s.\n", user_name);
847 if (ret < 0) {
848 *pp_err_str = NULL;
850 result = NT_STATUS_UNSUCCESSFUL;
851 goto done;
855 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
856 acb |= ACB_DISABLED;
857 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
858 ret = asprintf(pp_err_str,
859 "Failed to set 'disabled' flag for "
860 "user %s.\n", user_name);
861 if (ret < 0) {
862 *pp_err_str = NULL;
864 result = NT_STATUS_UNSUCCESSFUL;
865 goto done;
869 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
870 acb &= (~ACB_DISABLED);
871 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
872 ret = asprintf(pp_err_str,
873 "Failed to unset 'disabled' flag for "
874 "user %s.\n", user_name);
875 if (ret < 0) {
876 *pp_err_str = NULL;
878 result = NT_STATUS_UNSUCCESSFUL;
879 goto done;
883 /* now commit changes if any */
884 result = pdb_update_sam_account(sam_pass);
885 if (!NT_STATUS_IS_OK(result)) {
886 ret = asprintf(pp_err_str,
887 "Failed to modify entry for user %s.\n",
888 user_name);
889 if (ret < 0) {
890 *pp_err_str = NULL;
892 goto done;
895 if (local_flags & LOCAL_ADD_USER) {
896 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
897 } else if (local_flags & LOCAL_DISABLE_USER) {
898 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
899 } else if (local_flags & LOCAL_ENABLE_USER) {
900 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
901 } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
902 ret = asprintf(pp_msg_str,
903 "User %s password set to none.\n", user_name);
906 if (ret < 0) {
907 *pp_msg_str = NULL;
910 result = NT_STATUS_OK;
912 done:
913 TALLOC_FREE(sam_pass);
914 return result;
917 /**********************************************************************
918 Marshall/unmarshall struct samu structs.
919 *********************************************************************/
921 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
922 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
923 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
924 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
925 /* nothing changed between V3 and V4 */
927 /*********************************************************************
928 *********************************************************************/
930 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
933 /* times are stored as 32bit integer
934 take care on system with 64bit wide time_t
935 --SSS */
936 uint32_t logon_time,
937 logoff_time,
938 kickoff_time,
939 pass_last_set_time,
940 pass_can_change_time,
941 pass_must_change_time;
942 char *username = NULL;
943 char *domain = NULL;
944 char *nt_username = NULL;
945 char *dir_drive = NULL;
946 char *unknown_str = NULL;
947 char *munged_dial = NULL;
948 char *fullname = NULL;
949 char *homedir = NULL;
950 char *logon_script = NULL;
951 char *profile_path = NULL;
952 char *acct_desc = NULL;
953 char *workstations = NULL;
954 uint32_t username_len, domain_len, nt_username_len,
955 dir_drive_len, unknown_str_len, munged_dial_len,
956 fullname_len, homedir_len, logon_script_len,
957 profile_path_len, acct_desc_len, workstations_len;
959 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
960 uint16_t acct_ctrl, logon_divs;
961 uint16_t bad_password_count, logon_count;
962 uint8_t *hours = NULL;
963 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
964 uint32_t len = 0;
965 uint32_t lm_pw_len, nt_pw_len, hourslen;
966 bool ret = True;
968 if(sampass == NULL || buf == NULL) {
969 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
970 return False;
973 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
975 /* unpack the buffer into variables */
976 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
977 &logon_time, /* d */
978 &logoff_time, /* d */
979 &kickoff_time, /* d */
980 &pass_last_set_time, /* d */
981 &pass_can_change_time, /* d */
982 &pass_must_change_time, /* d */
983 &username_len, &username, /* B */
984 &domain_len, &domain, /* B */
985 &nt_username_len, &nt_username, /* B */
986 &fullname_len, &fullname, /* B */
987 &homedir_len, &homedir, /* B */
988 &dir_drive_len, &dir_drive, /* B */
989 &logon_script_len, &logon_script, /* B */
990 &profile_path_len, &profile_path, /* B */
991 &acct_desc_len, &acct_desc, /* B */
992 &workstations_len, &workstations, /* B */
993 &unknown_str_len, &unknown_str, /* B */
994 &munged_dial_len, &munged_dial, /* B */
995 &user_rid, /* d */
996 &group_rid, /* d */
997 &lm_pw_len, &lm_pw_ptr, /* B */
998 &nt_pw_len, &nt_pw_ptr, /* B */
999 &acct_ctrl, /* w */
1000 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1001 &logon_divs, /* w */
1002 &hours_len, /* d */
1003 &hourslen, &hours, /* B */
1004 &bad_password_count, /* w */
1005 &logon_count, /* w */
1006 &unknown_6); /* d */
1008 if (len == (uint32_t) -1) {
1009 ret = False;
1010 goto done;
1013 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1014 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1015 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1016 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1017 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1018 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1020 pdb_set_username(sampass, username, PDB_SET);
1021 pdb_set_domain(sampass, domain, PDB_SET);
1022 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1023 pdb_set_fullname(sampass, fullname, PDB_SET);
1025 if (homedir) {
1026 pdb_set_homedir(sampass, homedir, PDB_SET);
1028 else {
1029 pdb_set_homedir(sampass,
1030 talloc_sub_basic(sampass, username, domain,
1031 lp_logon_home()),
1032 PDB_DEFAULT);
1035 if (dir_drive)
1036 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1037 else {
1038 pdb_set_dir_drive(sampass,
1039 talloc_sub_basic(sampass, username, domain,
1040 lp_logon_drive()),
1041 PDB_DEFAULT);
1044 if (logon_script)
1045 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1046 else {
1047 pdb_set_logon_script(sampass,
1048 talloc_sub_basic(sampass, username, domain,
1049 lp_logon_script()),
1050 PDB_DEFAULT);
1053 if (profile_path) {
1054 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1055 } else {
1056 pdb_set_profile_path(sampass,
1057 talloc_sub_basic(sampass, username, domain,
1058 lp_logon_path()),
1059 PDB_DEFAULT);
1062 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1063 pdb_set_workstations(sampass, workstations, PDB_SET);
1064 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1066 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1067 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1068 ret = False;
1069 goto done;
1073 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1074 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1075 ret = False;
1076 goto done;
1080 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1081 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1082 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1083 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1084 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1085 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1086 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1087 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1088 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1089 pdb_set_hours(sampass, hours, PDB_SET);
1091 done:
1093 SAFE_FREE(username);
1094 SAFE_FREE(domain);
1095 SAFE_FREE(nt_username);
1096 SAFE_FREE(fullname);
1097 SAFE_FREE(homedir);
1098 SAFE_FREE(dir_drive);
1099 SAFE_FREE(logon_script);
1100 SAFE_FREE(profile_path);
1101 SAFE_FREE(acct_desc);
1102 SAFE_FREE(workstations);
1103 SAFE_FREE(munged_dial);
1104 SAFE_FREE(unknown_str);
1105 SAFE_FREE(lm_pw_ptr);
1106 SAFE_FREE(nt_pw_ptr);
1107 SAFE_FREE(hours);
1109 return ret;
1112 /*********************************************************************
1113 *********************************************************************/
1115 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1118 /* times are stored as 32bit integer
1119 take care on system with 64bit wide time_t
1120 --SSS */
1121 uint32_t logon_time,
1122 logoff_time,
1123 kickoff_time,
1124 bad_password_time,
1125 pass_last_set_time,
1126 pass_can_change_time,
1127 pass_must_change_time;
1128 char *username = NULL;
1129 char *domain = NULL;
1130 char *nt_username = NULL;
1131 char *dir_drive = NULL;
1132 char *unknown_str = NULL;
1133 char *munged_dial = NULL;
1134 char *fullname = NULL;
1135 char *homedir = NULL;
1136 char *logon_script = NULL;
1137 char *profile_path = NULL;
1138 char *acct_desc = NULL;
1139 char *workstations = NULL;
1140 uint32_t username_len, domain_len, nt_username_len,
1141 dir_drive_len, unknown_str_len, munged_dial_len,
1142 fullname_len, homedir_len, logon_script_len,
1143 profile_path_len, acct_desc_len, workstations_len;
1145 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
1146 uint16_t acct_ctrl, logon_divs;
1147 uint16_t bad_password_count, logon_count;
1148 uint8_t *hours = NULL;
1149 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1150 uint32_t len = 0;
1151 uint32_t lm_pw_len, nt_pw_len, hourslen;
1152 bool ret = True;
1154 if(sampass == NULL || buf == NULL) {
1155 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1156 return False;
1159 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1161 /* unpack the buffer into variables */
1162 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1163 &logon_time, /* d */
1164 &logoff_time, /* d */
1165 &kickoff_time, /* d */
1166 /* Change from V0 is addition of bad_password_time field. */
1167 &bad_password_time, /* d */
1168 &pass_last_set_time, /* d */
1169 &pass_can_change_time, /* d */
1170 &pass_must_change_time, /* d */
1171 &username_len, &username, /* B */
1172 &domain_len, &domain, /* B */
1173 &nt_username_len, &nt_username, /* B */
1174 &fullname_len, &fullname, /* B */
1175 &homedir_len, &homedir, /* B */
1176 &dir_drive_len, &dir_drive, /* B */
1177 &logon_script_len, &logon_script, /* B */
1178 &profile_path_len, &profile_path, /* B */
1179 &acct_desc_len, &acct_desc, /* B */
1180 &workstations_len, &workstations, /* B */
1181 &unknown_str_len, &unknown_str, /* B */
1182 &munged_dial_len, &munged_dial, /* B */
1183 &user_rid, /* d */
1184 &group_rid, /* d */
1185 &lm_pw_len, &lm_pw_ptr, /* B */
1186 &nt_pw_len, &nt_pw_ptr, /* B */
1187 &acct_ctrl, /* w */
1188 &remove_me, /* d */
1189 &logon_divs, /* w */
1190 &hours_len, /* d */
1191 &hourslen, &hours, /* B */
1192 &bad_password_count, /* w */
1193 &logon_count, /* w */
1194 &unknown_6); /* d */
1196 if (len == (uint32_t) -1) {
1197 ret = False;
1198 goto done;
1201 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1202 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1203 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1205 /* Change from V0 is addition of bad_password_time field. */
1206 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1207 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1208 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1209 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1211 pdb_set_username(sampass, username, PDB_SET);
1212 pdb_set_domain(sampass, domain, PDB_SET);
1213 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1214 pdb_set_fullname(sampass, fullname, PDB_SET);
1216 if (homedir) {
1217 pdb_set_homedir(sampass, homedir, PDB_SET);
1219 else {
1220 pdb_set_homedir(sampass,
1221 talloc_sub_basic(sampass, username, domain,
1222 lp_logon_home()),
1223 PDB_DEFAULT);
1226 if (dir_drive)
1227 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1228 else {
1229 pdb_set_dir_drive(sampass,
1230 talloc_sub_basic(sampass, username, domain,
1231 lp_logon_drive()),
1232 PDB_DEFAULT);
1235 if (logon_script)
1236 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1237 else {
1238 pdb_set_logon_script(sampass,
1239 talloc_sub_basic(sampass, username, domain,
1240 lp_logon_script()),
1241 PDB_DEFAULT);
1244 if (profile_path) {
1245 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1246 } else {
1247 pdb_set_profile_path(sampass,
1248 talloc_sub_basic(sampass, username, domain,
1249 lp_logon_path()),
1250 PDB_DEFAULT);
1253 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1254 pdb_set_workstations(sampass, workstations, PDB_SET);
1255 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1257 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1258 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1259 ret = False;
1260 goto done;
1264 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1265 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1266 ret = False;
1267 goto done;
1271 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1273 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1274 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1275 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1276 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1277 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1278 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1279 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1280 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1281 pdb_set_hours(sampass, hours, PDB_SET);
1283 done:
1285 SAFE_FREE(username);
1286 SAFE_FREE(domain);
1287 SAFE_FREE(nt_username);
1288 SAFE_FREE(fullname);
1289 SAFE_FREE(homedir);
1290 SAFE_FREE(dir_drive);
1291 SAFE_FREE(logon_script);
1292 SAFE_FREE(profile_path);
1293 SAFE_FREE(acct_desc);
1294 SAFE_FREE(workstations);
1295 SAFE_FREE(munged_dial);
1296 SAFE_FREE(unknown_str);
1297 SAFE_FREE(lm_pw_ptr);
1298 SAFE_FREE(nt_pw_ptr);
1299 SAFE_FREE(hours);
1301 return ret;
1304 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1307 /* times are stored as 32bit integer
1308 take care on system with 64bit wide time_t
1309 --SSS */
1310 uint32_t logon_time,
1311 logoff_time,
1312 kickoff_time,
1313 bad_password_time,
1314 pass_last_set_time,
1315 pass_can_change_time,
1316 pass_must_change_time;
1317 char *username = NULL;
1318 char *domain = NULL;
1319 char *nt_username = NULL;
1320 char *dir_drive = NULL;
1321 char *unknown_str = NULL;
1322 char *munged_dial = NULL;
1323 char *fullname = NULL;
1324 char *homedir = NULL;
1325 char *logon_script = NULL;
1326 char *profile_path = NULL;
1327 char *acct_desc = NULL;
1328 char *workstations = NULL;
1329 uint32_t username_len, domain_len, nt_username_len,
1330 dir_drive_len, unknown_str_len, munged_dial_len,
1331 fullname_len, homedir_len, logon_script_len,
1332 profile_path_len, acct_desc_len, workstations_len;
1334 uint32_t user_rid, group_rid, hours_len, unknown_6;
1335 uint16_t acct_ctrl, logon_divs;
1336 uint16_t bad_password_count, logon_count;
1337 uint8_t *hours = NULL;
1338 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1339 uint32_t len = 0;
1340 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1341 uint32_t pwHistLen = 0;
1342 bool ret = True;
1343 fstring tmp_string;
1344 bool expand_explicit = lp_passdb_expand_explicit();
1346 if(sampass == NULL || buf == NULL) {
1347 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1348 return False;
1351 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1353 /* unpack the buffer into variables */
1354 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1355 &logon_time, /* d */
1356 &logoff_time, /* d */
1357 &kickoff_time, /* d */
1358 &bad_password_time, /* d */
1359 &pass_last_set_time, /* d */
1360 &pass_can_change_time, /* d */
1361 &pass_must_change_time, /* d */
1362 &username_len, &username, /* B */
1363 &domain_len, &domain, /* B */
1364 &nt_username_len, &nt_username, /* B */
1365 &fullname_len, &fullname, /* B */
1366 &homedir_len, &homedir, /* B */
1367 &dir_drive_len, &dir_drive, /* B */
1368 &logon_script_len, &logon_script, /* B */
1369 &profile_path_len, &profile_path, /* B */
1370 &acct_desc_len, &acct_desc, /* B */
1371 &workstations_len, &workstations, /* B */
1372 &unknown_str_len, &unknown_str, /* B */
1373 &munged_dial_len, &munged_dial, /* B */
1374 &user_rid, /* d */
1375 &group_rid, /* d */
1376 &lm_pw_len, &lm_pw_ptr, /* B */
1377 &nt_pw_len, &nt_pw_ptr, /* B */
1378 /* Change from V1 is addition of password history field. */
1379 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1380 &acct_ctrl, /* w */
1381 /* Also "remove_me" field was removed. */
1382 &logon_divs, /* w */
1383 &hours_len, /* d */
1384 &hourslen, &hours, /* B */
1385 &bad_password_count, /* w */
1386 &logon_count, /* w */
1387 &unknown_6); /* d */
1389 if (len == (uint32_t) -1) {
1390 ret = False;
1391 goto done;
1394 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1395 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1396 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1397 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1398 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1399 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1400 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1402 pdb_set_username(sampass, username, PDB_SET);
1403 pdb_set_domain(sampass, domain, PDB_SET);
1404 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1405 pdb_set_fullname(sampass, fullname, PDB_SET);
1407 if (homedir) {
1408 fstrcpy( tmp_string, homedir );
1409 if (expand_explicit) {
1410 standard_sub_basic( username, domain, tmp_string,
1411 sizeof(tmp_string) );
1413 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1415 else {
1416 pdb_set_homedir(sampass,
1417 talloc_sub_basic(sampass, username, domain,
1418 lp_logon_home()),
1419 PDB_DEFAULT);
1422 if (dir_drive)
1423 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1424 else
1425 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1427 if (logon_script) {
1428 fstrcpy( tmp_string, logon_script );
1429 if (expand_explicit) {
1430 standard_sub_basic( username, domain, tmp_string,
1431 sizeof(tmp_string) );
1433 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1435 else {
1436 pdb_set_logon_script(sampass,
1437 talloc_sub_basic(sampass, username, domain,
1438 lp_logon_script()),
1439 PDB_DEFAULT);
1442 if (profile_path) {
1443 fstrcpy( tmp_string, profile_path );
1444 if (expand_explicit) {
1445 standard_sub_basic( username, domain, tmp_string,
1446 sizeof(tmp_string) );
1448 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1450 else {
1451 pdb_set_profile_path(sampass,
1452 talloc_sub_basic(sampass, username, domain,
1453 lp_logon_path()),
1454 PDB_DEFAULT);
1457 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1458 pdb_set_workstations(sampass, workstations, PDB_SET);
1459 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1461 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1462 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1463 ret = False;
1464 goto done;
1468 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1469 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1470 ret = False;
1471 goto done;
1475 /* Change from V1 is addition of password history field. */
1476 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1477 if (pwHistLen) {
1478 uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
1479 if (!pw_hist) {
1480 ret = False;
1481 goto done;
1483 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1484 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1485 int i;
1486 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1487 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1488 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1489 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1490 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1491 PW_HISTORY_ENTRY_LEN);
1494 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1495 SAFE_FREE(pw_hist);
1496 ret = False;
1497 goto done;
1499 SAFE_FREE(pw_hist);
1500 } else {
1501 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1504 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1505 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1506 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1507 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1508 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1509 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1510 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1511 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1512 pdb_set_hours(sampass, hours, PDB_SET);
1514 done:
1516 SAFE_FREE(username);
1517 SAFE_FREE(domain);
1518 SAFE_FREE(nt_username);
1519 SAFE_FREE(fullname);
1520 SAFE_FREE(homedir);
1521 SAFE_FREE(dir_drive);
1522 SAFE_FREE(logon_script);
1523 SAFE_FREE(profile_path);
1524 SAFE_FREE(acct_desc);
1525 SAFE_FREE(workstations);
1526 SAFE_FREE(munged_dial);
1527 SAFE_FREE(unknown_str);
1528 SAFE_FREE(lm_pw_ptr);
1529 SAFE_FREE(nt_pw_ptr);
1530 SAFE_FREE(nt_pw_hist_ptr);
1531 SAFE_FREE(hours);
1533 return ret;
1536 /*********************************************************************
1537 *********************************************************************/
1539 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1542 /* times are stored as 32bit integer
1543 take care on system with 64bit wide time_t
1544 --SSS */
1545 uint32_t logon_time,
1546 logoff_time,
1547 kickoff_time,
1548 bad_password_time,
1549 pass_last_set_time,
1550 pass_can_change_time,
1551 pass_must_change_time;
1552 char *username = NULL;
1553 char *domain = NULL;
1554 char *nt_username = NULL;
1555 char *dir_drive = NULL;
1556 char *comment = NULL;
1557 char *munged_dial = NULL;
1558 char *fullname = NULL;
1559 char *homedir = NULL;
1560 char *logon_script = NULL;
1561 char *profile_path = NULL;
1562 char *acct_desc = NULL;
1563 char *workstations = NULL;
1564 uint32_t username_len, domain_len, nt_username_len,
1565 dir_drive_len, comment_len, munged_dial_len,
1566 fullname_len, homedir_len, logon_script_len,
1567 profile_path_len, acct_desc_len, workstations_len;
1569 uint32_t user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1570 uint16_t logon_divs;
1571 uint16_t bad_password_count, logon_count;
1572 uint8_t *hours = NULL;
1573 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1574 uint32_t len = 0;
1575 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1576 uint32_t pwHistLen = 0;
1577 bool ret = True;
1578 fstring tmp_string;
1579 bool expand_explicit = lp_passdb_expand_explicit();
1581 if(sampass == NULL || buf == NULL) {
1582 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1583 return False;
1586 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1588 /* unpack the buffer into variables */
1589 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1590 &logon_time, /* d */
1591 &logoff_time, /* d */
1592 &kickoff_time, /* d */
1593 &bad_password_time, /* d */
1594 &pass_last_set_time, /* d */
1595 &pass_can_change_time, /* d */
1596 &pass_must_change_time, /* d */
1597 &username_len, &username, /* B */
1598 &domain_len, &domain, /* B */
1599 &nt_username_len, &nt_username, /* B */
1600 &fullname_len, &fullname, /* B */
1601 &homedir_len, &homedir, /* B */
1602 &dir_drive_len, &dir_drive, /* B */
1603 &logon_script_len, &logon_script, /* B */
1604 &profile_path_len, &profile_path, /* B */
1605 &acct_desc_len, &acct_desc, /* B */
1606 &workstations_len, &workstations, /* B */
1607 &comment_len, &comment, /* B */
1608 &munged_dial_len, &munged_dial, /* B */
1609 &user_rid, /* d */
1610 &group_rid, /* d */
1611 &lm_pw_len, &lm_pw_ptr, /* B */
1612 &nt_pw_len, &nt_pw_ptr, /* B */
1613 /* Change from V1 is addition of password history field. */
1614 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1615 /* Change from V2 is the uint32_t acb_mask */
1616 &acct_ctrl, /* d */
1617 /* Also "remove_me" field was removed. */
1618 &logon_divs, /* w */
1619 &hours_len, /* d */
1620 &hourslen, &hours, /* B */
1621 &bad_password_count, /* w */
1622 &logon_count, /* w */
1623 &unknown_6); /* d */
1625 if (len == (uint32_t) -1) {
1626 ret = False;
1627 goto done;
1630 pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
1631 pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
1632 pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
1633 pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
1634 pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
1635 pdb_set_pass_must_change_time(sampass, convert_uint32_t_to_time_t(pass_must_change_time), PDB_SET);
1636 pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
1638 pdb_set_username(sampass, username, PDB_SET);
1639 pdb_set_domain(sampass, domain, PDB_SET);
1640 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1641 pdb_set_fullname(sampass, fullname, PDB_SET);
1643 if (homedir) {
1644 fstrcpy( tmp_string, homedir );
1645 if (expand_explicit) {
1646 standard_sub_basic( username, domain, tmp_string,
1647 sizeof(tmp_string) );
1649 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1651 else {
1652 pdb_set_homedir(sampass,
1653 talloc_sub_basic(sampass, username, domain,
1654 lp_logon_home()),
1655 PDB_DEFAULT);
1658 if (dir_drive)
1659 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1660 else
1661 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1663 if (logon_script) {
1664 fstrcpy( tmp_string, logon_script );
1665 if (expand_explicit) {
1666 standard_sub_basic( username, domain, tmp_string,
1667 sizeof(tmp_string) );
1669 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1671 else {
1672 pdb_set_logon_script(sampass,
1673 talloc_sub_basic(sampass, username, domain,
1674 lp_logon_script()),
1675 PDB_DEFAULT);
1678 if (profile_path) {
1679 fstrcpy( tmp_string, profile_path );
1680 if (expand_explicit) {
1681 standard_sub_basic( username, domain, tmp_string,
1682 sizeof(tmp_string) );
1684 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1686 else {
1687 pdb_set_profile_path(sampass,
1688 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1689 PDB_DEFAULT);
1692 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1693 pdb_set_comment(sampass, comment, PDB_SET);
1694 pdb_set_workstations(sampass, workstations, PDB_SET);
1695 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1697 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1698 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1699 ret = False;
1700 goto done;
1704 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1705 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1706 ret = False;
1707 goto done;
1711 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1712 if (pwHistLen) {
1713 uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1714 if (!pw_hist) {
1715 ret = False;
1716 goto done;
1718 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1719 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1720 int i;
1721 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1722 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1723 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1724 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1725 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1726 PW_HISTORY_ENTRY_LEN);
1729 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1730 SAFE_FREE(pw_hist);
1731 ret = False;
1732 goto done;
1734 SAFE_FREE(pw_hist);
1735 } else {
1736 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1739 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1740 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1741 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1742 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1743 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1744 /* Change from V2 is the uint32_t acct_ctrl */
1745 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1746 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1747 pdb_set_hours(sampass, hours, PDB_SET);
1749 done:
1751 SAFE_FREE(username);
1752 SAFE_FREE(domain);
1753 SAFE_FREE(nt_username);
1754 SAFE_FREE(fullname);
1755 SAFE_FREE(homedir);
1756 SAFE_FREE(dir_drive);
1757 SAFE_FREE(logon_script);
1758 SAFE_FREE(profile_path);
1759 SAFE_FREE(acct_desc);
1760 SAFE_FREE(workstations);
1761 SAFE_FREE(munged_dial);
1762 SAFE_FREE(comment);
1763 SAFE_FREE(lm_pw_ptr);
1764 SAFE_FREE(nt_pw_ptr);
1765 SAFE_FREE(nt_pw_hist_ptr);
1766 SAFE_FREE(hours);
1768 return ret;
1771 /*********************************************************************
1772 *********************************************************************/
1774 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
1776 size_t len, buflen;
1778 /* times are stored as 32bit integer
1779 take care on system with 64bit wide time_t
1780 --SSS */
1781 uint32_t logon_time,
1782 logoff_time,
1783 kickoff_time,
1784 bad_password_time,
1785 pass_last_set_time,
1786 pass_can_change_time,
1787 pass_must_change_time;
1789 uint32_t user_rid, group_rid;
1791 const char *username;
1792 const char *domain;
1793 const char *nt_username;
1794 const char *dir_drive;
1795 const char *comment;
1796 const char *munged_dial;
1797 const char *fullname;
1798 const char *homedir;
1799 const char *logon_script;
1800 const char *profile_path;
1801 const char *acct_desc;
1802 const char *workstations;
1803 uint32_t username_len, domain_len, nt_username_len,
1804 dir_drive_len, comment_len, munged_dial_len,
1805 fullname_len, homedir_len, logon_script_len,
1806 profile_path_len, acct_desc_len, workstations_len;
1808 const uint8_t *lm_pw;
1809 const uint8_t *nt_pw;
1810 const uint8_t *nt_pw_hist;
1811 uint32_t lm_pw_len = 16;
1812 uint32_t nt_pw_len = 16;
1813 uint32_t nt_pw_hist_len;
1814 uint32_t pwHistLen = 0;
1816 *buf = NULL;
1817 buflen = 0;
1819 logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
1820 logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
1821 kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
1822 bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
1823 pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
1824 pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
1825 pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
1827 user_rid = pdb_get_user_rid(sampass);
1828 group_rid = pdb_get_group_rid(sampass);
1830 username = pdb_get_username(sampass);
1831 if (username) {
1832 username_len = strlen(username) +1;
1833 } else {
1834 username_len = 0;
1837 domain = pdb_get_domain(sampass);
1838 if (domain) {
1839 domain_len = strlen(domain) +1;
1840 } else {
1841 domain_len = 0;
1844 nt_username = pdb_get_nt_username(sampass);
1845 if (nt_username) {
1846 nt_username_len = strlen(nt_username) +1;
1847 } else {
1848 nt_username_len = 0;
1851 fullname = pdb_get_fullname(sampass);
1852 if (fullname) {
1853 fullname_len = strlen(fullname) +1;
1854 } else {
1855 fullname_len = 0;
1859 * Only updates fields which have been set (not defaults from smb.conf)
1862 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1863 dir_drive = pdb_get_dir_drive(sampass);
1864 } else {
1865 dir_drive = NULL;
1867 if (dir_drive) {
1868 dir_drive_len = strlen(dir_drive) +1;
1869 } else {
1870 dir_drive_len = 0;
1873 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1874 homedir = pdb_get_homedir(sampass);
1875 } else {
1876 homedir = NULL;
1878 if (homedir) {
1879 homedir_len = strlen(homedir) +1;
1880 } else {
1881 homedir_len = 0;
1884 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1885 logon_script = pdb_get_logon_script(sampass);
1886 } else {
1887 logon_script = NULL;
1889 if (logon_script) {
1890 logon_script_len = strlen(logon_script) +1;
1891 } else {
1892 logon_script_len = 0;
1895 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1896 profile_path = pdb_get_profile_path(sampass);
1897 } else {
1898 profile_path = NULL;
1900 if (profile_path) {
1901 profile_path_len = strlen(profile_path) +1;
1902 } else {
1903 profile_path_len = 0;
1906 lm_pw = pdb_get_lanman_passwd(sampass);
1907 if (!lm_pw) {
1908 lm_pw_len = 0;
1911 nt_pw = pdb_get_nt_passwd(sampass);
1912 if (!nt_pw) {
1913 nt_pw_len = 0;
1916 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1917 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1918 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1919 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1920 } else {
1921 nt_pw_hist_len = 0;
1924 acct_desc = pdb_get_acct_desc(sampass);
1925 if (acct_desc) {
1926 acct_desc_len = strlen(acct_desc) +1;
1927 } else {
1928 acct_desc_len = 0;
1931 workstations = pdb_get_workstations(sampass);
1932 if (workstations) {
1933 workstations_len = strlen(workstations) +1;
1934 } else {
1935 workstations_len = 0;
1938 comment = pdb_get_comment(sampass);
1939 if (comment) {
1940 comment_len = strlen(comment) +1;
1941 } else {
1942 comment_len = 0;
1945 munged_dial = pdb_get_munged_dial(sampass);
1946 if (munged_dial) {
1947 munged_dial_len = strlen(munged_dial) +1;
1948 } else {
1949 munged_dial_len = 0;
1952 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1954 /* one time to get the size needed */
1955 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3,
1956 logon_time, /* d */
1957 logoff_time, /* d */
1958 kickoff_time, /* d */
1959 bad_password_time, /* d */
1960 pass_last_set_time, /* d */
1961 pass_can_change_time, /* d */
1962 pass_must_change_time, /* d */
1963 username_len, username, /* B */
1964 domain_len, domain, /* B */
1965 nt_username_len, nt_username, /* B */
1966 fullname_len, fullname, /* B */
1967 homedir_len, homedir, /* B */
1968 dir_drive_len, dir_drive, /* B */
1969 logon_script_len, logon_script, /* B */
1970 profile_path_len, profile_path, /* B */
1971 acct_desc_len, acct_desc, /* B */
1972 workstations_len, workstations, /* B */
1973 comment_len, comment, /* B */
1974 munged_dial_len, munged_dial, /* B */
1975 user_rid, /* d */
1976 group_rid, /* d */
1977 lm_pw_len, lm_pw, /* B */
1978 nt_pw_len, nt_pw, /* B */
1979 nt_pw_hist_len, nt_pw_hist, /* B */
1980 pdb_get_acct_ctrl(sampass), /* d */
1981 pdb_get_logon_divs(sampass), /* w */
1982 pdb_get_hours_len(sampass), /* d */
1983 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1984 pdb_get_bad_password_count(sampass), /* w */
1985 pdb_get_logon_count(sampass), /* w */
1986 pdb_get_unknown_6(sampass)); /* d */
1988 if (size_only) {
1989 return buflen;
1992 /* malloc the space needed */
1993 if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
1994 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1995 return (-1);
1998 /* now for the real call to tdb_pack() */
1999 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
2000 logon_time, /* d */
2001 logoff_time, /* d */
2002 kickoff_time, /* d */
2003 bad_password_time, /* d */
2004 pass_last_set_time, /* d */
2005 pass_can_change_time, /* d */
2006 pass_must_change_time, /* d */
2007 username_len, username, /* B */
2008 domain_len, domain, /* B */
2009 nt_username_len, nt_username, /* B */
2010 fullname_len, fullname, /* B */
2011 homedir_len, homedir, /* B */
2012 dir_drive_len, dir_drive, /* B */
2013 logon_script_len, logon_script, /* B */
2014 profile_path_len, profile_path, /* B */
2015 acct_desc_len, acct_desc, /* B */
2016 workstations_len, workstations, /* B */
2017 comment_len, comment, /* B */
2018 munged_dial_len, munged_dial, /* B */
2019 user_rid, /* d */
2020 group_rid, /* d */
2021 lm_pw_len, lm_pw, /* B */
2022 nt_pw_len, nt_pw, /* B */
2023 nt_pw_hist_len, nt_pw_hist, /* B */
2024 pdb_get_acct_ctrl(sampass), /* d */
2025 pdb_get_logon_divs(sampass), /* w */
2026 pdb_get_hours_len(sampass), /* d */
2027 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2028 pdb_get_bad_password_count(sampass), /* w */
2029 pdb_get_logon_count(sampass), /* w */
2030 pdb_get_unknown_6(sampass)); /* d */
2032 /* check to make sure we got it correct */
2033 if (buflen != len) {
2034 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2035 (unsigned long)buflen, (unsigned long)len));
2036 /* error */
2037 SAFE_FREE (*buf);
2038 return (-1);
2041 return (buflen);
2044 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
2046 /* nothing changed between V3 and V4 */
2047 return init_samu_from_buffer_v3(sampass, buf, buflen);
2050 static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
2052 /* nothing changed between V3 and V4 */
2053 return init_buffer_from_samu_v3(buf, sampass, size_only);
2056 /**********************************************************************
2057 Intialize a struct samu struct from a BYTE buffer of size len
2058 *********************************************************************/
2060 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2061 uint8_t *buf, uint32_t buflen)
2063 switch (level) {
2064 case SAMU_BUFFER_V0:
2065 return init_samu_from_buffer_v0(sampass, buf, buflen);
2066 case SAMU_BUFFER_V1:
2067 return init_samu_from_buffer_v1(sampass, buf, buflen);
2068 case SAMU_BUFFER_V2:
2069 return init_samu_from_buffer_v2(sampass, buf, buflen);
2070 case SAMU_BUFFER_V3:
2071 return init_samu_from_buffer_v3(sampass, buf, buflen);
2072 case SAMU_BUFFER_V4:
2073 return init_samu_from_buffer_v4(sampass, buf, buflen);
2076 return false;
2079 /**********************************************************************
2080 Intialize a BYTE buffer from a struct samu struct
2081 *********************************************************************/
2083 uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
2085 return init_buffer_from_samu_v4(buf, sampass, size_only);
2088 /*********************************************************************
2089 *********************************************************************/
2091 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2093 uint8_t *buf = NULL;
2094 int len;
2096 len = init_buffer_from_samu(&buf, src, False);
2097 if (len == -1 || !buf) {
2098 SAFE_FREE(buf);
2099 return False;
2102 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2103 free(buf);
2104 return False;
2107 dst->methods = src->methods;
2109 if ( src->unix_pw ) {
2110 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2111 if (!dst->unix_pw) {
2112 free(buf);
2113 return False;
2117 if (src->group_sid) {
2118 pdb_set_group_sid(dst, src->group_sid, PDB_SET);
2121 free(buf);
2122 return True;
2125 /*********************************************************************
2126 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2127 *********************************************************************/
2129 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2131 time_t LastBadPassword;
2132 uint16_t BadPasswordCount;
2133 uint32_t resettime;
2134 bool res;
2136 BadPasswordCount = pdb_get_bad_password_count(sampass);
2137 if (!BadPasswordCount) {
2138 DEBUG(9, ("No bad password attempts.\n"));
2139 return True;
2142 become_root();
2143 res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2144 unbecome_root();
2146 if (!res) {
2147 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2148 return False;
2151 /* First, check if there is a reset time to compare */
2152 if ((resettime == (uint32_t) -1) || (resettime == 0)) {
2153 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2154 return True;
2157 LastBadPassword = pdb_get_bad_password_time(sampass);
2158 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2159 (uint32_t) LastBadPassword, resettime, (uint32_t)time(NULL)));
2160 if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
2161 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2162 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2163 if (updated) {
2164 *updated = True;
2168 return True;
2171 /*********************************************************************
2172 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2173 *********************************************************************/
2175 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2177 uint32_t duration;
2178 time_t LastBadPassword;
2179 bool res;
2181 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2182 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2183 pdb_get_username(sampass)));
2184 return True;
2187 become_root();
2188 res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2189 unbecome_root();
2191 if (!res) {
2192 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2193 return False;
2196 /* First, check if there is a duration to compare */
2197 if ((duration == (uint32_t) -1) || (duration == 0)) {
2198 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2199 return True;
2202 LastBadPassword = pdb_get_bad_password_time(sampass);
2203 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2204 pdb_get_username(sampass), (uint32_t)LastBadPassword, duration*60, (uint32_t)time(NULL)));
2206 if (LastBadPassword == (time_t)0) {
2207 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2208 "administratively locked out with no bad password "
2209 "time. Leaving locked out.\n",
2210 pdb_get_username(sampass) ));
2211 return True;
2214 if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
2215 pdb_set_acct_ctrl(sampass,
2216 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2217 PDB_CHANGED);
2218 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2219 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2220 if (updated) {
2221 *updated = True;
2225 return True;
2228 /*********************************************************************
2229 Increment the bad_password_count
2230 *********************************************************************/
2232 bool pdb_increment_bad_password_count(struct samu *sampass)
2234 uint32_t account_policy_lockout;
2235 bool autolock_updated = False, badpw_updated = False;
2236 bool ret;
2238 /* Retrieve the account lockout policy */
2239 become_root();
2240 ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2241 unbecome_root();
2242 if ( !ret ) {
2243 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2244 return False;
2247 /* If there is no policy, we don't need to continue checking */
2248 if (!account_policy_lockout) {
2249 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2250 return True;
2253 /* Check if the autolock needs to be cleared */
2254 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2255 return False;
2257 /* Check if the badpw count needs to be reset */
2258 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2259 return False;
2262 Ok, now we can assume that any resetting that needs to be
2263 done has been done, and just get on with incrementing
2264 and autolocking if necessary
2267 pdb_set_bad_password_count(sampass,
2268 pdb_get_bad_password_count(sampass)+1,
2269 PDB_CHANGED);
2270 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2273 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2274 return True;
2276 if (!pdb_set_acct_ctrl(sampass,
2277 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2278 PDB_CHANGED)) {
2279 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2280 return False;
2283 return True;
2286 bool is_dc_trusted_domain_situation(const char *domain_name)
2288 return IS_DC && !strequal(domain_name, lp_workgroup());
2291 /*******************************************************************
2292 Wrapper around retrieving the clear text trust account password.
2293 appropriate account name is stored in account_name.
2294 Caller must free password, but not account_name.
2295 *******************************************************************/
2297 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2298 const char **account_name,
2299 enum netr_SchannelType *channel)
2301 char *pwd;
2302 time_t last_set_time;
2304 /* if we are a DC and this is not our domain, then lookup an account
2305 * for the domain trust */
2307 if (is_dc_trusted_domain_situation(domain)) {
2308 if (!lp_allow_trusted_domains()) {
2309 return false;
2312 if (!pdb_get_trusteddom_pw(domain, ret_pwd, NULL,
2313 &last_set_time))
2315 DEBUG(0, ("get_trust_pw: could not fetch trust "
2316 "account password for trusted domain %s\n",
2317 domain));
2318 return false;
2321 if (channel != NULL) {
2322 *channel = SEC_CHAN_DOMAIN;
2325 if (account_name != NULL) {
2326 *account_name = lp_workgroup();
2329 return true;
2333 * Since we can only be member of one single domain, we are now
2334 * in a member situation:
2336 * - Either we are a DC (selfjoined) and the domain is our
2337 * own domain.
2338 * - Or we are on a member and the domain is our own or some
2339 * other (potentially trusted) domain.
2341 * In both cases, we can only get the machine account password
2342 * for our own domain to connect to our own dc. (For a member,
2343 * request to trusted domains are performed through our dc.)
2345 * So we simply use our own domain name to retrieve the
2346 * machine account passowrd and ignore the request domain here.
2349 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2351 if (pwd != NULL) {
2352 *ret_pwd = pwd;
2353 if (account_name != NULL) {
2354 *account_name = global_myname();
2357 return true;
2360 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2361 "account password for domain %s\n", domain));
2362 return false;
2365 /*******************************************************************
2366 Wrapper around retrieving the trust account password.
2367 appropriate account name is stored in account_name.
2368 *******************************************************************/
2370 bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
2371 const char **account_name,
2372 enum netr_SchannelType *channel)
2374 char *pwd = NULL;
2375 time_t last_set_time;
2377 if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
2378 E_md4hash(pwd, ret_pwd);
2379 SAFE_FREE(pwd);
2380 return true;
2381 } else if (is_dc_trusted_domain_situation(domain)) {
2382 return false;
2385 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2387 if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
2388 &last_set_time,
2389 channel))
2391 if (account_name != NULL) {
2392 *account_name = global_myname();
2395 return true;
2398 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2399 "password for domain %s\n", domain));
2400 return False;