s3: libads: In ads_connect(), and ads_disconnect(), replace ZERO_STRUCT(ads->ldap...
[Samba.git] / source3 / passdb / passdb.c
blob8ed1bafcea32083c2a1dabf2ade26f00310c9330
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 "passdb.h"
27 #include "system/passwd.h"
28 #include "../libcli/auth/libcli_auth.h"
29 #include "secrets.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/util_pw.h"
32 #include "util_tdb.h"
33 #include "auth/credentials/credentials.h"
34 #include "lib/param/param.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_PASSDB
39 /**********************************************************************
40 ***********************************************************************/
42 static int samu_destroy(struct samu *user)
44 data_blob_clear_free( &user->lm_pw );
45 data_blob_clear_free( &user->nt_pw );
47 if ( user->plaintext_pw )
48 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
50 return 0;
53 /**********************************************************************
54 generate a new struct samuser
55 ***********************************************************************/
57 struct samu *samu_new( TALLOC_CTX *ctx )
59 struct samu *user;
61 if ( !(user = talloc_zero( ctx, struct samu )) ) {
62 DEBUG(0,("samuser_new: Talloc failed!\n"));
63 return NULL;
66 talloc_set_destructor( user, samu_destroy );
68 /* no initial methods */
70 user->methods = NULL;
72 /* Don't change these timestamp settings without a good reason.
73 They are important for NT member server compatibility. */
75 user->logon_time = (time_t)0;
76 user->pass_last_set_time = (time_t)0;
77 user->pass_can_change_time = (time_t)0;
78 user->logoff_time = get_time_t_max();
79 user->kickoff_time = get_time_t_max();
80 user->fields_present = 0x00ffffff;
81 user->logon_divs = 168; /* hours per week */
82 user->hours_len = 21; /* 21 times 8 bits = 168 */
83 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
84 user->bad_password_count = 0;
85 user->logon_count = 0;
86 user->unknown_6 = 0x000004ec; /* don't know */
88 /* Some parts of samba strlen their pdb_get...() returns,
89 so this keeps the interface unchanged for now. */
91 user->username = "";
92 user->domain = "";
93 user->nt_username = "";
94 user->full_name = "";
95 user->home_dir = "";
96 user->logon_script = "";
97 user->profile_path = "";
98 user->acct_desc = "";
99 user->workstations = "";
100 user->comment = "";
101 user->munged_dial = "";
103 user->plaintext_pw = NULL;
105 /* Unless we know otherwise have a Account Control Bit
106 value of 'normal user'. This helps User Manager, which
107 asks for a filtered list of users. */
109 user->acct_ctrl = ACB_NORMAL;
111 return user;
114 static int count_commas(const char *str)
116 int num_commas = 0;
117 const char *comma = str;
119 while ((comma = strchr(comma, ',')) != NULL) {
120 comma += 1;
121 num_commas += 1;
123 return num_commas;
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 pdb_methods *methods,
133 struct samu *user, const struct passwd *pwd, bool create)
135 const char *guest_account = lp_guest_account();
136 const char *domain = lp_netbios_name();
137 char *fullname;
138 uint32_t urid;
140 if ( !pwd ) {
141 return NT_STATUS_NO_SUCH_USER;
144 /* Basic properties based upon the Unix account information */
146 pdb_set_username(user, pwd->pw_name, PDB_SET);
148 fullname = NULL;
150 if (count_commas(pwd->pw_gecos) == 3) {
152 * Heuristic: This seems to be a gecos field that has been
153 * edited by chfn(1). Only use the part before the first
154 * comma. Fixes bug 5198.
156 fullname = talloc_strndup(
157 talloc_tos(), pwd->pw_gecos,
158 strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
161 if (fullname != NULL) {
162 pdb_set_fullname(user, fullname, PDB_SET);
163 } else {
164 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
166 TALLOC_FREE(fullname);
168 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
169 #if 0
170 /* This can lead to a primary group of S-1-22-2-XX which
171 will be rejected by other parts of the Samba code.
172 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
173 --jerry */
175 gid_to_sid(&group_sid, pwd->pw_gid);
176 pdb_set_group_sid(user, &group_sid, PDB_SET);
177 #endif
179 /* save the password structure for later use */
181 user->unix_pw = tcopy_passwd( user, pwd );
183 /* Special case for the guest account which must have a RID of 501 */
185 if ( strequal( pwd->pw_name, guest_account ) ) {
186 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
187 return NT_STATUS_NO_SUCH_USER;
189 return NT_STATUS_OK;
192 /* Non-guest accounts...Check for a workstation or user account */
194 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
195 /* workstation */
197 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
198 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
199 pwd->pw_name));
200 return NT_STATUS_INVALID_COMPUTER_NAME;
203 else {
204 /* user */
206 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
207 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
208 pwd->pw_name));
209 return NT_STATUS_INVALID_ACCOUNT_NAME;
212 /* set some basic attributes */
214 pdb_set_profile_path(user, talloc_sub_specified(user,
215 lp_logon_path(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
216 PDB_DEFAULT);
217 pdb_set_homedir(user, talloc_sub_specified(user,
218 lp_logon_home(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
219 PDB_DEFAULT);
220 pdb_set_dir_drive(user, talloc_sub_specified(user,
221 lp_logon_drive(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
222 PDB_DEFAULT);
223 pdb_set_logon_script(user, talloc_sub_specified(user,
224 lp_logon_script(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
225 PDB_DEFAULT);
228 /* Now deal with the user SID. If we have a backend that can generate
229 RIDs, then do so. But sometimes the caller just wanted a structure
230 initialized and will fill in these fields later (such as from a
231 netr_SamInfo3 structure) */
233 if ( create && (methods->capabilities(methods) & PDB_CAP_STORE_RIDS)) {
234 uint32_t user_rid;
235 struct dom_sid user_sid;
237 if ( !methods->new_rid(methods, &user_rid) ) {
238 DEBUG(3, ("Could not allocate a new RID\n"));
239 return NT_STATUS_ACCESS_DENIED;
242 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
244 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
245 DEBUG(3, ("pdb_set_user_sid failed\n"));
246 return NT_STATUS_INTERNAL_ERROR;
249 return NT_STATUS_OK;
252 /* generate a SID for the user with the RID algorithm */
254 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
256 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
257 return NT_STATUS_INTERNAL_ERROR;
260 return NT_STATUS_OK;
263 /********************************************************************
264 Set the Unix user attributes
265 ********************************************************************/
267 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
269 return samu_set_unix_internal( NULL, user, pwd, False );
272 NTSTATUS samu_alloc_rid_unix(struct pdb_methods *methods,
273 struct samu *user, const struct passwd *pwd)
275 return samu_set_unix_internal( methods, user, pwd, True );
278 /**********************************************************
279 Encode the account control bits into a string.
280 length = length of string to encode into (including terminating
281 null). length *MUST BE MORE THAN 2* !
282 **********************************************************/
284 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
286 fstring acct_str;
287 char *result;
289 size_t i = 0;
291 SMB_ASSERT(length <= sizeof(acct_str));
293 acct_str[i++] = '[';
295 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
296 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
297 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
298 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
299 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
300 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
301 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
302 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
303 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
304 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
305 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
307 for ( ; i < length - 2 ; i++ )
308 acct_str[i] = ' ';
310 i = length - 2;
311 acct_str[i++] = ']';
312 acct_str[i++] = '\0';
314 result = talloc_strdup(talloc_tos(), acct_str);
315 SMB_ASSERT(result != NULL);
316 return result;
319 /**********************************************************
320 Decode the account control bits from a string.
321 **********************************************************/
323 uint32_t pdb_decode_acct_ctrl(const char *p)
325 uint32_t acct_ctrl = 0;
326 bool finished = false;
329 * Check if the account type bits have been encoded after the
330 * NT password (in the form [NDHTUWSLXI]).
333 if (*p != '[')
334 return 0;
336 for (p++; *p && !finished; p++) {
337 switch (*p) {
338 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
339 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
340 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
341 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
342 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
343 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
344 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
345 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
346 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
347 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
348 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
349 case ' ': { break; }
350 case ':':
351 case '\n':
352 case '\0':
353 case ']':
354 default: { finished = true; }
358 return acct_ctrl;
361 /*************************************************************
362 Routine to set 32 hex password characters from a 16 byte array.
363 **************************************************************/
365 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
367 if (pwd != NULL) {
368 hex_encode_buf(p, pwd, 16);
369 } else {
370 if (acct_ctrl & ACB_PWNOTREQ)
371 strlcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
372 else
373 strlcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
377 /*************************************************************
378 Routine to get the 32 hex characters and turn them
379 into a 16 byte array.
380 **************************************************************/
382 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
384 int i;
385 unsigned char lonybble, hinybble;
386 const char *hexchars = "0123456789ABCDEF";
387 char *p1, *p2;
389 if (!p)
390 return false;
392 for (i = 0; i < 32; i += 2) {
393 hinybble = toupper_m(p[i]);
394 lonybble = toupper_m(p[i + 1]);
396 p1 = strchr(hexchars, hinybble);
397 p2 = strchr(hexchars, lonybble);
399 if (!p1 || !p2)
400 return false;
402 hinybble = PTR_DIFF(p1, hexchars);
403 lonybble = PTR_DIFF(p2, hexchars);
405 pwd[i / 2] = (hinybble << 4) | lonybble;
407 return true;
410 /*************************************************************
411 Routine to set 42 hex hours characters from a 21 byte array.
412 **************************************************************/
414 void pdb_sethexhours(char *p, const unsigned char *hours)
416 if (hours != NULL) {
417 hex_encode_buf(p, hours, 21);
418 } else {
419 strlcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
423 /*************************************************************
424 Routine to get the 42 hex characters and turn them
425 into a 21 byte array.
426 **************************************************************/
428 bool pdb_gethexhours(const char *p, unsigned char *hours)
430 int i;
431 unsigned char lonybble, hinybble;
432 const char *hexchars = "0123456789ABCDEF";
433 char *p1, *p2;
435 if (!p) {
436 return (False);
439 for (i = 0; i < 42; i += 2) {
440 hinybble = toupper_m(p[i]);
441 lonybble = toupper_m(p[i + 1]);
443 p1 = strchr(hexchars, hinybble);
444 p2 = strchr(hexchars, lonybble);
446 if (!p1 || !p2) {
447 return (False);
450 hinybble = PTR_DIFF(p1, hexchars);
451 lonybble = PTR_DIFF(p2, hexchars);
453 hours[i / 2] = (hinybble << 4) | lonybble;
455 return (True);
458 /********************************************************************
459 ********************************************************************/
461 int algorithmic_rid_base(void)
463 int rid_offset;
465 rid_offset = lp_algorithmic_rid_base();
467 if (rid_offset < BASE_RID) {
468 /* Try to prevent admin foot-shooting, we can't put algorithmic
469 rids below 1000, that's the 'well known RIDs' on NT */
470 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
471 rid_offset = BASE_RID;
473 if (rid_offset & 1) {
474 DEBUG(0, ("algorithmic rid base must be even\n"));
475 rid_offset += 1;
477 return rid_offset;
480 /*******************************************************************
481 Converts NT user RID to a UNIX uid.
482 ********************************************************************/
484 uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
486 int rid_offset = algorithmic_rid_base();
487 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
490 uid_t max_algorithmic_uid(void)
492 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
495 /*******************************************************************
496 converts UNIX uid to an NT User RID.
497 ********************************************************************/
499 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
501 int rid_offset = algorithmic_rid_base();
502 return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
505 /*******************************************************************
506 Converts NT group RID to a UNIX gid.
507 ********************************************************************/
509 gid_t pdb_group_rid_to_gid(uint32_t group_rid)
511 int rid_offset = algorithmic_rid_base();
512 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
515 gid_t max_algorithmic_gid(void)
517 return pdb_group_rid_to_gid(0xffffffff);
520 /*******************************************************************
521 converts NT Group RID to a UNIX uid.
523 warning: you must not call that function only
524 you must do a call to the group mapping first.
525 there is not anymore a direct link between the gid and the rid.
526 ********************************************************************/
528 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
530 int rid_offset = algorithmic_rid_base();
531 return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
534 /*******************************************************************
535 Decides if a RID is a well known RID.
536 ********************************************************************/
538 static bool rid_is_well_known(uint32_t rid)
540 /* Not using rid_offset here, because this is the actual
541 NT fixed value (1000) */
543 return (rid < BASE_RID);
546 /*******************************************************************
547 Decides if a RID is a user or group RID.
548 ********************************************************************/
550 bool algorithmic_pdb_rid_is_user(uint32_t rid)
552 if ( rid_is_well_known(rid) ) {
554 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
555 * and DOMAIN_RID_GUEST.
557 if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
558 return True;
559 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
560 return True;
562 return False;
565 /*******************************************************************
566 Convert a name into a SID. Used in the lookup name rpc.
567 ********************************************************************/
569 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
570 enum lsa_SidType *type)
572 GROUP_MAP *map;
573 bool ret;
575 /* Windows treats "MACHINE\None" as a special name for
576 rid 513 on non-DCs. You cannot create a user or group
577 name "None" on Windows. You will get an error that
578 the group already exists. */
580 if ( strequal( name, "None" ) ) {
581 *rid = DOMAIN_RID_USERS;
582 *type = SID_NAME_DOM_GRP;
584 return True;
587 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
588 * correctly in the case where foo also exists as a user. If the flag
589 * is set, don't look for users at all. */
591 if ((flags & LOOKUP_NAME_GROUP) == 0) {
592 struct samu *sam_account = NULL;
593 struct dom_sid user_sid;
595 if ( !(sam_account = samu_new( NULL )) ) {
596 return False;
599 become_root();
600 ret = pdb_getsampwnam(sam_account, name);
601 unbecome_root();
603 if (ret) {
604 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
607 TALLOC_FREE(sam_account);
609 if (ret) {
610 if (!sid_check_is_in_our_sam(&user_sid)) {
611 struct dom_sid_buf buf;
612 DBG_ERR("User %s with invalid SID %s"
613 " in passdb\n",
614 name,
615 dom_sid_str_buf(&user_sid, &buf));
616 return False;
619 sid_peek_rid(&user_sid, rid);
620 *type = SID_NAME_USER;
621 return True;
626 * Maybe it is a group ?
629 map = talloc_zero(NULL, GROUP_MAP);
630 if (!map) {
631 return false;
634 become_root();
635 ret = pdb_getgrnam(map, name);
636 unbecome_root();
638 if (!ret) {
639 TALLOC_FREE(map);
640 return False;
643 /* BUILTIN groups are looked up elsewhere */
644 if (!sid_check_is_in_our_sam(&map->sid)) {
645 struct dom_sid_buf buf;
646 DEBUG(10, ("Found group %s (%s) not in our domain -- "
647 "ignoring.\n",
648 name,
649 dom_sid_str_buf(&map->sid, &buf)));
650 TALLOC_FREE(map);
651 return False;
654 /* yes it's a mapped group */
655 sid_peek_rid(&map->sid, rid);
656 *type = map->sid_name_use;
657 TALLOC_FREE(map);
658 return True;
661 /*************************************************************
662 Change a password entry in the local passdb backend.
664 Assumptions:
665 - always called as root
666 - ignores the account type except when adding a new account
667 - will create/delete the unix account if the relative
668 add/delete user script is configured
670 *************************************************************/
672 NTSTATUS local_password_change(const char *user_name,
673 int local_flags,
674 const char *new_passwd,
675 char **pp_err_str,
676 char **pp_msg_str)
678 TALLOC_CTX *tosctx;
679 struct samu *sam_pass;
680 uint32_t acb;
681 uint32_t rid;
682 NTSTATUS result;
683 bool user_exists;
684 int ret = -1;
686 *pp_err_str = NULL;
687 *pp_msg_str = NULL;
689 tosctx = talloc_tos();
691 sam_pass = samu_new(tosctx);
692 if (!sam_pass) {
693 result = NT_STATUS_NO_MEMORY;
694 goto done;
697 /* Get the smb passwd entry for this user */
698 user_exists = pdb_getsampwnam(sam_pass, user_name);
700 /* Check delete first, we don't need to do anything else if we
701 * are going to delete the acocunt */
702 if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
704 result = pdb_delete_user(tosctx, sam_pass);
705 if (!NT_STATUS_IS_OK(result)) {
706 ret = asprintf(pp_err_str,
707 "Failed to delete entry for user %s.\n",
708 user_name);
709 if (ret < 0) {
710 *pp_err_str = NULL;
712 result = NT_STATUS_UNSUCCESSFUL;
713 } else {
714 ret = asprintf(pp_msg_str,
715 "Deleted user %s.\n",
716 user_name);
717 if (ret < 0) {
718 *pp_msg_str = NULL;
721 goto done;
724 if (user_exists && (local_flags & LOCAL_ADD_USER)) {
725 /* the entry already existed */
726 local_flags &= ~LOCAL_ADD_USER;
729 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
730 ret = asprintf(pp_err_str,
731 "Failed to find entry for user %s.\n",
732 user_name);
733 if (ret < 0) {
734 *pp_err_str = NULL;
736 result = NT_STATUS_NO_SUCH_USER;
737 goto done;
740 /* First thing add the new user if we are required to do so */
741 if (local_flags & LOCAL_ADD_USER) {
743 if (local_flags & LOCAL_TRUST_ACCOUNT) {
744 acb = ACB_WSTRUST;
745 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
746 acb = ACB_DOMTRUST;
747 } else {
748 acb = ACB_NORMAL;
751 result = pdb_create_user(tosctx, user_name, acb, &rid);
752 if (!NT_STATUS_IS_OK(result)) {
753 ret = asprintf(pp_err_str,
754 "Failed to add entry for user %s.\n",
755 user_name);
756 if (ret < 0) {
757 *pp_err_str = NULL;
759 result = NT_STATUS_UNSUCCESSFUL;
760 goto done;
763 sam_pass = samu_new(tosctx);
764 if (!sam_pass) {
765 result = NT_STATUS_NO_MEMORY;
766 goto done;
769 /* Now get back the smb passwd entry for this new user */
770 user_exists = pdb_getsampwnam(sam_pass, user_name);
771 if (!user_exists) {
772 ret = asprintf(pp_err_str,
773 "Failed to add entry for user %s.\n",
774 user_name);
775 if (ret < 0) {
776 *pp_err_str = NULL;
778 result = NT_STATUS_UNSUCCESSFUL;
779 goto done;
783 acb = pdb_get_acct_ctrl(sam_pass);
786 * We are root - just write the new password
787 * and the valid last change time.
789 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
790 acb |= ACB_PWNOTREQ;
791 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
792 ret = asprintf(pp_err_str,
793 "Failed to set 'no password required' "
794 "flag for user %s.\n", user_name);
795 if (ret < 0) {
796 *pp_err_str = NULL;
798 result = NT_STATUS_UNSUCCESSFUL;
799 goto done;
803 if (local_flags & LOCAL_SET_PASSWORD) {
805 * If we're dealing with setting a completely empty user account
806 * ie. One with a password of 'XXXX', but not set disabled (like
807 * an account created from scratch) then if the old password was
808 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
809 * We remove that as we're giving this user their first password
810 * and the decision hasn't really been made to disable them (ie.
811 * don't create them disabled). JRA.
813 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
814 (acb & ACB_DISABLED)) {
815 acb &= (~ACB_DISABLED);
816 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
817 ret = asprintf(pp_err_str,
818 "Failed to unset 'disabled' "
819 "flag for user %s.\n",
820 user_name);
821 if (ret < 0) {
822 *pp_err_str = NULL;
824 result = NT_STATUS_UNSUCCESSFUL;
825 goto done;
829 acb &= (~ACB_PWNOTREQ);
830 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
831 ret = asprintf(pp_err_str,
832 "Failed to unset 'no password required'"
833 " flag for user %s.\n", user_name);
834 if (ret < 0) {
835 *pp_err_str = NULL;
837 result = NT_STATUS_UNSUCCESSFUL;
838 goto done;
841 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
842 ret = asprintf(pp_err_str,
843 "Failed to set password for "
844 "user %s.\n", user_name);
845 if (ret < 0) {
846 *pp_err_str = NULL;
848 result = NT_STATUS_UNSUCCESSFUL;
849 goto done;
853 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
854 acb |= ACB_DISABLED;
855 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
856 ret = asprintf(pp_err_str,
857 "Failed to set 'disabled' flag for "
858 "user %s.\n", user_name);
859 if (ret < 0) {
860 *pp_err_str = NULL;
862 result = NT_STATUS_UNSUCCESSFUL;
863 goto done;
867 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
868 acb &= (~ACB_DISABLED);
869 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
870 ret = asprintf(pp_err_str,
871 "Failed to unset 'disabled' flag for "
872 "user %s.\n", user_name);
873 if (ret < 0) {
874 *pp_err_str = NULL;
876 result = NT_STATUS_UNSUCCESSFUL;
877 goto done;
881 /* now commit changes if any */
882 result = pdb_update_sam_account(sam_pass);
883 if (!NT_STATUS_IS_OK(result)) {
884 ret = asprintf(pp_err_str,
885 "Failed to modify entry for user %s.\n",
886 user_name);
887 if (ret < 0) {
888 *pp_err_str = NULL;
890 goto done;
893 if (local_flags & LOCAL_ADD_USER) {
894 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
895 } else if (local_flags & LOCAL_DISABLE_USER) {
896 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
897 } else if (local_flags & LOCAL_ENABLE_USER) {
898 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
899 } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
900 ret = asprintf(pp_msg_str,
901 "User %s password set to none.\n", user_name);
904 if (ret < 0) {
905 *pp_msg_str = NULL;
908 result = NT_STATUS_OK;
910 done:
911 TALLOC_FREE(sam_pass);
912 return result;
915 /**********************************************************************
916 Marshall/unmarshall struct samu structs.
917 *********************************************************************/
919 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
920 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
921 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
922 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
923 /* nothing changed between V3 and V4 */
925 /*********************************************************************
926 *********************************************************************/
928 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
931 /* times are stored as 32bit integer
932 take care on system with 64bit wide time_t
933 --SSS */
934 uint32_t logon_time,
935 logoff_time,
936 kickoff_time,
937 pass_last_set_time,
938 pass_can_change_time,
939 pass_must_change_time;
940 char *username = NULL;
941 char *domain = NULL;
942 char *nt_username = NULL;
943 char *dir_drive = NULL;
944 char *unknown_str = NULL;
945 char *munged_dial = NULL;
946 char *fullname = NULL;
947 char *homedir = NULL;
948 char *logon_script = NULL;
949 char *profile_path = NULL;
950 char *acct_desc = NULL;
951 char *workstations = NULL;
952 uint32_t username_len, domain_len, nt_username_len,
953 dir_drive_len, unknown_str_len, munged_dial_len,
954 fullname_len, homedir_len, logon_script_len,
955 profile_path_len, acct_desc_len, workstations_len;
957 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
958 uint16_t acct_ctrl, logon_divs;
959 uint16_t bad_password_count, logon_count;
960 uint8_t *hours = NULL;
961 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
962 uint32_t len = 0;
963 uint32_t lm_pw_len, nt_pw_len, hourslen;
964 bool ret = True;
966 if(sampass == NULL || buf == NULL) {
967 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
968 return False;
971 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
973 /* unpack the buffer into variables */
974 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
975 &logon_time, /* d */
976 &logoff_time, /* d */
977 &kickoff_time, /* d */
978 &pass_last_set_time, /* d */
979 &pass_can_change_time, /* d */
980 &pass_must_change_time, /* d */
981 &username_len, &username, /* B */
982 &domain_len, &domain, /* B */
983 &nt_username_len, &nt_username, /* B */
984 &fullname_len, &fullname, /* B */
985 &homedir_len, &homedir, /* B */
986 &dir_drive_len, &dir_drive, /* B */
987 &logon_script_len, &logon_script, /* B */
988 &profile_path_len, &profile_path, /* B */
989 &acct_desc_len, &acct_desc, /* B */
990 &workstations_len, &workstations, /* B */
991 &unknown_str_len, &unknown_str, /* B */
992 &munged_dial_len, &munged_dial, /* B */
993 &user_rid, /* d */
994 &group_rid, /* d */
995 &lm_pw_len, &lm_pw_ptr, /* B */
996 &nt_pw_len, &nt_pw_ptr, /* B */
997 &acct_ctrl, /* w */
998 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
999 &logon_divs, /* w */
1000 &hours_len, /* d */
1001 &hourslen, &hours, /* B */
1002 &bad_password_count, /* w */
1003 &logon_count, /* w */
1004 &unknown_6); /* d */
1006 if (len == (uint32_t) -1) {
1007 ret = False;
1008 goto done;
1011 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1012 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1013 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1014 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1015 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1017 pdb_set_username(sampass, username, PDB_SET);
1018 pdb_set_domain(sampass, domain, PDB_SET);
1019 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1020 pdb_set_fullname(sampass, fullname, PDB_SET);
1022 if (homedir) {
1023 pdb_set_homedir(sampass, homedir, PDB_SET);
1025 else {
1026 pdb_set_homedir(sampass,
1027 talloc_sub_basic(sampass, username, domain,
1028 lp_logon_home()),
1029 PDB_DEFAULT);
1032 if (dir_drive)
1033 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1034 else {
1035 pdb_set_dir_drive(sampass,
1036 talloc_sub_basic(sampass, username, domain,
1037 lp_logon_drive()),
1038 PDB_DEFAULT);
1041 if (logon_script)
1042 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1043 else {
1044 pdb_set_logon_script(sampass,
1045 talloc_sub_basic(sampass, username, domain,
1046 lp_logon_script()),
1047 PDB_DEFAULT);
1050 if (profile_path) {
1051 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1052 } else {
1053 pdb_set_profile_path(sampass,
1054 talloc_sub_basic(sampass, username, domain,
1055 lp_logon_path()),
1056 PDB_DEFAULT);
1059 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1060 pdb_set_workstations(sampass, workstations, PDB_SET);
1061 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1063 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1064 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1065 ret = False;
1066 goto done;
1070 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1071 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1072 ret = False;
1073 goto done;
1077 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1078 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1079 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1080 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1081 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1082 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1083 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1084 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1085 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1086 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1088 done:
1090 SAFE_FREE(username);
1091 SAFE_FREE(domain);
1092 SAFE_FREE(nt_username);
1093 SAFE_FREE(fullname);
1094 SAFE_FREE(homedir);
1095 SAFE_FREE(dir_drive);
1096 SAFE_FREE(logon_script);
1097 SAFE_FREE(profile_path);
1098 SAFE_FREE(acct_desc);
1099 SAFE_FREE(workstations);
1100 SAFE_FREE(munged_dial);
1101 SAFE_FREE(unknown_str);
1102 SAFE_FREE(lm_pw_ptr);
1103 SAFE_FREE(nt_pw_ptr);
1104 SAFE_FREE(hours);
1106 return ret;
1109 /*********************************************************************
1110 *********************************************************************/
1112 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1115 /* times are stored as 32bit integer
1116 take care on system with 64bit wide time_t
1117 --SSS */
1118 uint32_t logon_time,
1119 logoff_time,
1120 kickoff_time,
1121 bad_password_time,
1122 pass_last_set_time,
1123 pass_can_change_time,
1124 pass_must_change_time;
1125 char *username = NULL;
1126 char *domain = NULL;
1127 char *nt_username = NULL;
1128 char *dir_drive = NULL;
1129 char *unknown_str = NULL;
1130 char *munged_dial = NULL;
1131 char *fullname = NULL;
1132 char *homedir = NULL;
1133 char *logon_script = NULL;
1134 char *profile_path = NULL;
1135 char *acct_desc = NULL;
1136 char *workstations = NULL;
1137 uint32_t username_len, domain_len, nt_username_len,
1138 dir_drive_len, unknown_str_len, munged_dial_len,
1139 fullname_len, homedir_len, logon_script_len,
1140 profile_path_len, acct_desc_len, workstations_len;
1142 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
1143 uint16_t acct_ctrl, logon_divs;
1144 uint16_t bad_password_count, logon_count;
1145 uint8_t *hours = NULL;
1146 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1147 uint32_t len = 0;
1148 uint32_t lm_pw_len, nt_pw_len, hourslen;
1149 bool ret = True;
1151 if(sampass == NULL || buf == NULL) {
1152 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1153 return False;
1156 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1158 /* unpack the buffer into variables */
1159 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1160 &logon_time, /* d */
1161 &logoff_time, /* d */
1162 &kickoff_time, /* d */
1163 /* Change from V0 is addition of bad_password_time field. */
1164 &bad_password_time, /* d */
1165 &pass_last_set_time, /* d */
1166 &pass_can_change_time, /* d */
1167 &pass_must_change_time, /* d */
1168 &username_len, &username, /* B */
1169 &domain_len, &domain, /* B */
1170 &nt_username_len, &nt_username, /* B */
1171 &fullname_len, &fullname, /* B */
1172 &homedir_len, &homedir, /* B */
1173 &dir_drive_len, &dir_drive, /* B */
1174 &logon_script_len, &logon_script, /* B */
1175 &profile_path_len, &profile_path, /* B */
1176 &acct_desc_len, &acct_desc, /* B */
1177 &workstations_len, &workstations, /* B */
1178 &unknown_str_len, &unknown_str, /* B */
1179 &munged_dial_len, &munged_dial, /* B */
1180 &user_rid, /* d */
1181 &group_rid, /* d */
1182 &lm_pw_len, &lm_pw_ptr, /* B */
1183 &nt_pw_len, &nt_pw_ptr, /* B */
1184 &acct_ctrl, /* w */
1185 &remove_me, /* d */
1186 &logon_divs, /* w */
1187 &hours_len, /* d */
1188 &hourslen, &hours, /* B */
1189 &bad_password_count, /* w */
1190 &logon_count, /* w */
1191 &unknown_6); /* d */
1193 if (len == (uint32_t) -1) {
1194 ret = False;
1195 goto done;
1198 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1199 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1200 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1202 /* Change from V0 is addition of bad_password_time field. */
1203 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1204 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1205 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1207 pdb_set_username(sampass, username, PDB_SET);
1208 pdb_set_domain(sampass, domain, PDB_SET);
1209 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1210 pdb_set_fullname(sampass, fullname, PDB_SET);
1212 if (homedir) {
1213 pdb_set_homedir(sampass, homedir, PDB_SET);
1215 else {
1216 pdb_set_homedir(sampass,
1217 talloc_sub_basic(sampass, username, domain,
1218 lp_logon_home()),
1219 PDB_DEFAULT);
1222 if (dir_drive)
1223 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1224 else {
1225 pdb_set_dir_drive(sampass,
1226 talloc_sub_basic(sampass, username, domain,
1227 lp_logon_drive()),
1228 PDB_DEFAULT);
1231 if (logon_script)
1232 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1233 else {
1234 pdb_set_logon_script(sampass,
1235 talloc_sub_basic(sampass, username, domain,
1236 lp_logon_script()),
1237 PDB_DEFAULT);
1240 if (profile_path) {
1241 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1242 } else {
1243 pdb_set_profile_path(sampass,
1244 talloc_sub_basic(sampass, username, domain,
1245 lp_logon_path()),
1246 PDB_DEFAULT);
1249 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1250 pdb_set_workstations(sampass, workstations, PDB_SET);
1251 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1253 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1254 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1255 ret = False;
1256 goto done;
1260 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1261 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1262 ret = False;
1263 goto done;
1267 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1269 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1270 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1271 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1272 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1273 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1274 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1275 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1276 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1277 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1279 done:
1281 SAFE_FREE(username);
1282 SAFE_FREE(domain);
1283 SAFE_FREE(nt_username);
1284 SAFE_FREE(fullname);
1285 SAFE_FREE(homedir);
1286 SAFE_FREE(dir_drive);
1287 SAFE_FREE(logon_script);
1288 SAFE_FREE(profile_path);
1289 SAFE_FREE(acct_desc);
1290 SAFE_FREE(workstations);
1291 SAFE_FREE(munged_dial);
1292 SAFE_FREE(unknown_str);
1293 SAFE_FREE(lm_pw_ptr);
1294 SAFE_FREE(nt_pw_ptr);
1295 SAFE_FREE(hours);
1297 return ret;
1300 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1303 /* times are stored as 32bit integer
1304 take care on system with 64bit wide time_t
1305 --SSS */
1306 uint32_t logon_time,
1307 logoff_time,
1308 kickoff_time,
1309 bad_password_time,
1310 pass_last_set_time,
1311 pass_can_change_time,
1312 pass_must_change_time;
1313 char *username = NULL;
1314 char *domain = NULL;
1315 char *nt_username = NULL;
1316 char *dir_drive = NULL;
1317 char *unknown_str = NULL;
1318 char *munged_dial = NULL;
1319 char *fullname = NULL;
1320 char *homedir = NULL;
1321 char *logon_script = NULL;
1322 char *profile_path = NULL;
1323 char *acct_desc = NULL;
1324 char *workstations = NULL;
1325 uint32_t username_len, domain_len, nt_username_len,
1326 dir_drive_len, unknown_str_len, munged_dial_len,
1327 fullname_len, homedir_len, logon_script_len,
1328 profile_path_len, acct_desc_len, workstations_len;
1330 uint32_t user_rid, group_rid, hours_len, unknown_6;
1331 uint16_t acct_ctrl, logon_divs;
1332 uint16_t bad_password_count, logon_count;
1333 uint8_t *hours = NULL;
1334 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1335 uint32_t len = 0;
1336 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1337 uint32_t pwHistLen = 0;
1338 bool ret = True;
1339 fstring tmp_string;
1340 bool expand_explicit = lp_passdb_expand_explicit();
1342 if(sampass == NULL || buf == NULL) {
1343 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1344 return False;
1347 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1349 /* unpack the buffer into variables */
1350 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1351 &logon_time, /* d */
1352 &logoff_time, /* d */
1353 &kickoff_time, /* d */
1354 &bad_password_time, /* d */
1355 &pass_last_set_time, /* d */
1356 &pass_can_change_time, /* d */
1357 &pass_must_change_time, /* d */
1358 &username_len, &username, /* B */
1359 &domain_len, &domain, /* B */
1360 &nt_username_len, &nt_username, /* B */
1361 &fullname_len, &fullname, /* B */
1362 &homedir_len, &homedir, /* B */
1363 &dir_drive_len, &dir_drive, /* B */
1364 &logon_script_len, &logon_script, /* B */
1365 &profile_path_len, &profile_path, /* B */
1366 &acct_desc_len, &acct_desc, /* B */
1367 &workstations_len, &workstations, /* B */
1368 &unknown_str_len, &unknown_str, /* B */
1369 &munged_dial_len, &munged_dial, /* B */
1370 &user_rid, /* d */
1371 &group_rid, /* d */
1372 &lm_pw_len, &lm_pw_ptr, /* B */
1373 &nt_pw_len, &nt_pw_ptr, /* B */
1374 /* Change from V1 is addition of password history field. */
1375 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1376 &acct_ctrl, /* w */
1377 /* Also "remove_me" field was removed. */
1378 &logon_divs, /* w */
1379 &hours_len, /* d */
1380 &hourslen, &hours, /* B */
1381 &bad_password_count, /* w */
1382 &logon_count, /* w */
1383 &unknown_6); /* d */
1385 if (len == (uint32_t) -1) {
1386 ret = False;
1387 goto done;
1390 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1391 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1392 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1393 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1394 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1395 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1397 pdb_set_username(sampass, username, PDB_SET);
1398 pdb_set_domain(sampass, domain, PDB_SET);
1399 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1400 pdb_set_fullname(sampass, fullname, PDB_SET);
1402 if (homedir) {
1403 fstrcpy( tmp_string, homedir );
1404 if (expand_explicit) {
1405 standard_sub_basic( username, domain, tmp_string,
1406 sizeof(tmp_string) );
1408 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1410 else {
1411 pdb_set_homedir(sampass,
1412 talloc_sub_basic(sampass, username, domain,
1413 lp_logon_home()),
1414 PDB_DEFAULT);
1417 if (dir_drive)
1418 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1419 else
1420 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1422 if (logon_script) {
1423 fstrcpy( tmp_string, logon_script );
1424 if (expand_explicit) {
1425 standard_sub_basic( username, domain, tmp_string,
1426 sizeof(tmp_string) );
1428 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1430 else {
1431 pdb_set_logon_script(sampass,
1432 talloc_sub_basic(sampass, username, domain,
1433 lp_logon_script()),
1434 PDB_DEFAULT);
1437 if (profile_path) {
1438 fstrcpy( tmp_string, profile_path );
1439 if (expand_explicit) {
1440 standard_sub_basic( username, domain, tmp_string,
1441 sizeof(tmp_string) );
1443 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1445 else {
1446 pdb_set_profile_path(sampass,
1447 talloc_sub_basic(sampass, username, domain,
1448 lp_logon_path()),
1449 PDB_DEFAULT);
1452 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1453 pdb_set_workstations(sampass, workstations, PDB_SET);
1454 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1456 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1457 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1458 ret = False;
1459 goto done;
1463 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1464 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1465 ret = False;
1466 goto done;
1470 /* Change from V1 is addition of password history field. */
1471 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1472 if (pwHistLen) {
1473 uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
1474 if (!pw_hist) {
1475 ret = False;
1476 goto done;
1478 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1479 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1480 int i;
1481 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1482 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1483 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1484 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1485 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1486 PW_HISTORY_ENTRY_LEN);
1489 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1490 SAFE_FREE(pw_hist);
1491 ret = False;
1492 goto done;
1494 SAFE_FREE(pw_hist);
1495 } else {
1496 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1499 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1500 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1501 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1502 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1503 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1504 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1505 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1506 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1507 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1509 done:
1511 SAFE_FREE(username);
1512 SAFE_FREE(domain);
1513 SAFE_FREE(nt_username);
1514 SAFE_FREE(fullname);
1515 SAFE_FREE(homedir);
1516 SAFE_FREE(dir_drive);
1517 SAFE_FREE(logon_script);
1518 SAFE_FREE(profile_path);
1519 SAFE_FREE(acct_desc);
1520 SAFE_FREE(workstations);
1521 SAFE_FREE(munged_dial);
1522 SAFE_FREE(unknown_str);
1523 SAFE_FREE(lm_pw_ptr);
1524 SAFE_FREE(nt_pw_ptr);
1525 SAFE_FREE(nt_pw_hist_ptr);
1526 SAFE_FREE(hours);
1528 return ret;
1531 /*********************************************************************
1532 *********************************************************************/
1534 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1537 /* times are stored as 32bit integer
1538 take care on system with 64bit wide time_t
1539 --SSS */
1540 uint32_t logon_time,
1541 logoff_time,
1542 kickoff_time,
1543 bad_password_time,
1544 pass_last_set_time,
1545 pass_can_change_time,
1546 pass_must_change_time;
1547 char *username = NULL;
1548 char *domain = NULL;
1549 char *nt_username = NULL;
1550 char *dir_drive = NULL;
1551 char *comment = NULL;
1552 char *munged_dial = NULL;
1553 char *fullname = NULL;
1554 char *homedir = NULL;
1555 char *logon_script = NULL;
1556 char *profile_path = NULL;
1557 char *acct_desc = NULL;
1558 char *workstations = NULL;
1559 uint32_t username_len, domain_len, nt_username_len,
1560 dir_drive_len, comment_len, munged_dial_len,
1561 fullname_len, homedir_len, logon_script_len,
1562 profile_path_len, acct_desc_len, workstations_len;
1564 uint32_t user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1565 uint16_t logon_divs;
1566 uint16_t bad_password_count, logon_count;
1567 uint8_t *hours = NULL;
1568 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1569 uint32_t len = 0;
1570 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1571 uint32_t pwHistLen = 0;
1572 bool ret = True;
1573 fstring tmp_string;
1574 bool expand_explicit = lp_passdb_expand_explicit();
1576 if(sampass == NULL || buf == NULL) {
1577 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1578 return False;
1581 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1583 /* unpack the buffer into variables */
1584 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1585 &logon_time, /* d */
1586 &logoff_time, /* d */
1587 &kickoff_time, /* d */
1588 &bad_password_time, /* d */
1589 &pass_last_set_time, /* d */
1590 &pass_can_change_time, /* d */
1591 &pass_must_change_time, /* d */
1592 &username_len, &username, /* B */
1593 &domain_len, &domain, /* B */
1594 &nt_username_len, &nt_username, /* B */
1595 &fullname_len, &fullname, /* B */
1596 &homedir_len, &homedir, /* B */
1597 &dir_drive_len, &dir_drive, /* B */
1598 &logon_script_len, &logon_script, /* B */
1599 &profile_path_len, &profile_path, /* B */
1600 &acct_desc_len, &acct_desc, /* B */
1601 &workstations_len, &workstations, /* B */
1602 &comment_len, &comment, /* B */
1603 &munged_dial_len, &munged_dial, /* B */
1604 &user_rid, /* d */
1605 &group_rid, /* d */
1606 &lm_pw_len, &lm_pw_ptr, /* B */
1607 &nt_pw_len, &nt_pw_ptr, /* B */
1608 /* Change from V1 is addition of password history field. */
1609 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1610 /* Change from V2 is the uint32_t acb_mask */
1611 &acct_ctrl, /* d */
1612 /* Also "remove_me" field was removed. */
1613 &logon_divs, /* w */
1614 &hours_len, /* d */
1615 &hourslen, &hours, /* B */
1616 &bad_password_count, /* w */
1617 &logon_count, /* w */
1618 &unknown_6); /* d */
1620 if (len == (uint32_t) -1) {
1621 ret = False;
1622 goto done;
1625 pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
1626 pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
1627 pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
1628 pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
1629 pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
1630 pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
1632 pdb_set_username(sampass, username, PDB_SET);
1633 pdb_set_domain(sampass, domain, PDB_SET);
1634 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1635 pdb_set_fullname(sampass, fullname, PDB_SET);
1637 if (homedir) {
1638 fstrcpy( tmp_string, homedir );
1639 if (expand_explicit) {
1640 standard_sub_basic( username, domain, tmp_string,
1641 sizeof(tmp_string) );
1643 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1645 else {
1646 pdb_set_homedir(sampass,
1647 talloc_sub_basic(sampass, username, domain,
1648 lp_logon_home()),
1649 PDB_DEFAULT);
1652 if (dir_drive)
1653 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1654 else
1655 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1657 if (logon_script) {
1658 fstrcpy( tmp_string, logon_script );
1659 if (expand_explicit) {
1660 standard_sub_basic( username, domain, tmp_string,
1661 sizeof(tmp_string) );
1663 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1665 else {
1666 pdb_set_logon_script(sampass,
1667 talloc_sub_basic(sampass, username, domain,
1668 lp_logon_script()),
1669 PDB_DEFAULT);
1672 if (profile_path) {
1673 fstrcpy( tmp_string, profile_path );
1674 if (expand_explicit) {
1675 standard_sub_basic( username, domain, tmp_string,
1676 sizeof(tmp_string) );
1678 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1680 else {
1681 pdb_set_profile_path(sampass,
1682 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1683 PDB_DEFAULT);
1686 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1687 pdb_set_comment(sampass, comment, PDB_SET);
1688 pdb_set_workstations(sampass, workstations, PDB_SET);
1689 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1691 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1692 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1693 ret = False;
1694 goto done;
1698 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1699 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1700 ret = False;
1701 goto done;
1705 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1706 if (pwHistLen) {
1707 uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1708 if (!pw_hist) {
1709 ret = False;
1710 goto done;
1712 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1713 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1714 int i;
1715 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1716 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1717 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1718 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1719 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1720 PW_HISTORY_ENTRY_LEN);
1723 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1724 SAFE_FREE(pw_hist);
1725 ret = False;
1726 goto done;
1728 SAFE_FREE(pw_hist);
1729 } else {
1730 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1733 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1734 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1735 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1736 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1737 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1738 /* Change from V2 is the uint32_t acct_ctrl */
1739 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1740 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1741 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1743 done:
1745 SAFE_FREE(username);
1746 SAFE_FREE(domain);
1747 SAFE_FREE(nt_username);
1748 SAFE_FREE(fullname);
1749 SAFE_FREE(homedir);
1750 SAFE_FREE(dir_drive);
1751 SAFE_FREE(logon_script);
1752 SAFE_FREE(profile_path);
1753 SAFE_FREE(acct_desc);
1754 SAFE_FREE(workstations);
1755 SAFE_FREE(munged_dial);
1756 SAFE_FREE(comment);
1757 SAFE_FREE(lm_pw_ptr);
1758 SAFE_FREE(nt_pw_ptr);
1759 SAFE_FREE(nt_pw_hist_ptr);
1760 SAFE_FREE(hours);
1762 return ret;
1765 /*********************************************************************
1766 *********************************************************************/
1768 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
1770 size_t len, buflen;
1772 /* times are stored as 32bit integer
1773 take care on system with 64bit wide time_t
1774 --SSS */
1775 uint32_t logon_time,
1776 logoff_time,
1777 kickoff_time,
1778 bad_password_time,
1779 pass_last_set_time,
1780 pass_can_change_time,
1781 pass_must_change_time;
1783 uint32_t user_rid, group_rid;
1785 const char *username;
1786 const char *domain;
1787 const char *nt_username;
1788 const char *dir_drive;
1789 const char *comment;
1790 const char *munged_dial;
1791 const char *fullname;
1792 const char *homedir;
1793 const char *logon_script;
1794 const char *profile_path;
1795 const char *acct_desc;
1796 const char *workstations;
1797 uint32_t username_len, domain_len, nt_username_len,
1798 dir_drive_len, comment_len, munged_dial_len,
1799 fullname_len, homedir_len, logon_script_len,
1800 profile_path_len, acct_desc_len, workstations_len;
1802 const uint8_t *lm_pw;
1803 const uint8_t *nt_pw;
1804 const uint8_t *nt_pw_hist;
1805 uint32_t lm_pw_len = 16;
1806 uint32_t nt_pw_len = 16;
1807 uint32_t nt_pw_hist_len;
1808 uint32_t pwHistLen = 0;
1810 *buf = NULL;
1811 buflen = 0;
1813 logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
1814 logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
1815 kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
1816 bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
1817 pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
1818 pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
1819 pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
1821 user_rid = pdb_get_user_rid(sampass);
1822 group_rid = pdb_get_group_rid(sampass);
1824 username = pdb_get_username(sampass);
1825 if (username) {
1826 username_len = strlen(username) +1;
1827 } else {
1828 username_len = 0;
1831 domain = pdb_get_domain(sampass);
1832 if (domain) {
1833 domain_len = strlen(domain) +1;
1834 } else {
1835 domain_len = 0;
1838 nt_username = pdb_get_nt_username(sampass);
1839 if (nt_username) {
1840 nt_username_len = strlen(nt_username) +1;
1841 } else {
1842 nt_username_len = 0;
1845 fullname = pdb_get_fullname(sampass);
1846 if (fullname) {
1847 fullname_len = strlen(fullname) +1;
1848 } else {
1849 fullname_len = 0;
1853 * Only updates fields which have been set (not defaults from smb.conf)
1856 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1857 dir_drive = pdb_get_dir_drive(sampass);
1858 } else {
1859 dir_drive = NULL;
1861 if (dir_drive) {
1862 dir_drive_len = strlen(dir_drive) +1;
1863 } else {
1864 dir_drive_len = 0;
1867 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1868 homedir = pdb_get_homedir(sampass);
1869 } else {
1870 homedir = NULL;
1872 if (homedir) {
1873 homedir_len = strlen(homedir) +1;
1874 } else {
1875 homedir_len = 0;
1878 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1879 logon_script = pdb_get_logon_script(sampass);
1880 } else {
1881 logon_script = NULL;
1883 if (logon_script) {
1884 logon_script_len = strlen(logon_script) +1;
1885 } else {
1886 logon_script_len = 0;
1889 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1890 profile_path = pdb_get_profile_path(sampass);
1891 } else {
1892 profile_path = NULL;
1894 if (profile_path) {
1895 profile_path_len = strlen(profile_path) +1;
1896 } else {
1897 profile_path_len = 0;
1900 lm_pw = pdb_get_lanman_passwd(sampass);
1901 if (!lm_pw) {
1902 lm_pw_len = 0;
1905 nt_pw = pdb_get_nt_passwd(sampass);
1906 if (!nt_pw) {
1907 nt_pw_len = 0;
1910 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1911 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1912 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1913 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1914 } else {
1915 nt_pw_hist_len = 0;
1918 acct_desc = pdb_get_acct_desc(sampass);
1919 if (acct_desc) {
1920 acct_desc_len = strlen(acct_desc) +1;
1921 } else {
1922 acct_desc_len = 0;
1925 workstations = pdb_get_workstations(sampass);
1926 if (workstations) {
1927 workstations_len = strlen(workstations) +1;
1928 } else {
1929 workstations_len = 0;
1932 comment = pdb_get_comment(sampass);
1933 if (comment) {
1934 comment_len = strlen(comment) +1;
1935 } else {
1936 comment_len = 0;
1939 munged_dial = pdb_get_munged_dial(sampass);
1940 if (munged_dial) {
1941 munged_dial_len = strlen(munged_dial) +1;
1942 } else {
1943 munged_dial_len = 0;
1946 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1948 /* one time to get the size needed */
1949 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3,
1950 logon_time, /* d */
1951 logoff_time, /* d */
1952 kickoff_time, /* d */
1953 bad_password_time, /* d */
1954 pass_last_set_time, /* d */
1955 pass_can_change_time, /* d */
1956 pass_must_change_time, /* d */
1957 username_len, username, /* B */
1958 domain_len, domain, /* B */
1959 nt_username_len, nt_username, /* B */
1960 fullname_len, fullname, /* B */
1961 homedir_len, homedir, /* B */
1962 dir_drive_len, dir_drive, /* B */
1963 logon_script_len, logon_script, /* B */
1964 profile_path_len, profile_path, /* B */
1965 acct_desc_len, acct_desc, /* B */
1966 workstations_len, workstations, /* B */
1967 comment_len, comment, /* B */
1968 munged_dial_len, munged_dial, /* B */
1969 user_rid, /* d */
1970 group_rid, /* d */
1971 lm_pw_len, lm_pw, /* B */
1972 nt_pw_len, nt_pw, /* B */
1973 nt_pw_hist_len, nt_pw_hist, /* B */
1974 pdb_get_acct_ctrl(sampass), /* d */
1975 pdb_get_logon_divs(sampass), /* w */
1976 pdb_get_hours_len(sampass), /* d */
1977 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1978 pdb_get_bad_password_count(sampass), /* w */
1979 pdb_get_logon_count(sampass), /* w */
1980 pdb_get_unknown_6(sampass)); /* d */
1982 if (size_only) {
1983 return buflen;
1986 /* malloc the space needed */
1987 if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
1988 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1989 return (-1);
1992 /* now for the real call to tdb_pack() */
1993 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
1994 logon_time, /* d */
1995 logoff_time, /* d */
1996 kickoff_time, /* d */
1997 bad_password_time, /* d */
1998 pass_last_set_time, /* d */
1999 pass_can_change_time, /* d */
2000 pass_must_change_time, /* d */
2001 username_len, username, /* B */
2002 domain_len, domain, /* B */
2003 nt_username_len, nt_username, /* B */
2004 fullname_len, fullname, /* B */
2005 homedir_len, homedir, /* B */
2006 dir_drive_len, dir_drive, /* B */
2007 logon_script_len, logon_script, /* B */
2008 profile_path_len, profile_path, /* B */
2009 acct_desc_len, acct_desc, /* B */
2010 workstations_len, workstations, /* B */
2011 comment_len, comment, /* B */
2012 munged_dial_len, munged_dial, /* B */
2013 user_rid, /* d */
2014 group_rid, /* d */
2015 lm_pw_len, lm_pw, /* B */
2016 nt_pw_len, nt_pw, /* B */
2017 nt_pw_hist_len, nt_pw_hist, /* B */
2018 pdb_get_acct_ctrl(sampass), /* d */
2019 pdb_get_logon_divs(sampass), /* w */
2020 pdb_get_hours_len(sampass), /* d */
2021 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2022 pdb_get_bad_password_count(sampass), /* w */
2023 pdb_get_logon_count(sampass), /* w */
2024 pdb_get_unknown_6(sampass)); /* d */
2026 /* check to make sure we got it correct */
2027 if (buflen != len) {
2028 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2029 (unsigned long)buflen, (unsigned long)len));
2030 /* error */
2031 SAFE_FREE (*buf);
2032 return (-1);
2035 return (buflen);
2038 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
2040 /* nothing changed between V3 and V4 */
2041 return init_samu_from_buffer_v3(sampass, buf, buflen);
2044 static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
2046 /* nothing changed between V3 and V4 */
2047 return init_buffer_from_samu_v3(buf, sampass, size_only);
2050 /**********************************************************************
2051 Intialize a struct samu struct from a BYTE buffer of size len
2052 *********************************************************************/
2054 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2055 uint8_t *buf, uint32_t buflen)
2057 switch (level) {
2058 case SAMU_BUFFER_V0:
2059 return init_samu_from_buffer_v0(sampass, buf, buflen);
2060 case SAMU_BUFFER_V1:
2061 return init_samu_from_buffer_v1(sampass, buf, buflen);
2062 case SAMU_BUFFER_V2:
2063 return init_samu_from_buffer_v2(sampass, buf, buflen);
2064 case SAMU_BUFFER_V3:
2065 return init_samu_from_buffer_v3(sampass, buf, buflen);
2066 case SAMU_BUFFER_V4:
2067 return init_samu_from_buffer_v4(sampass, buf, buflen);
2070 return false;
2073 /**********************************************************************
2074 Intialize a BYTE buffer from a struct samu struct
2075 *********************************************************************/
2077 uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
2079 return init_buffer_from_samu_v4(buf, sampass, size_only);
2082 /*********************************************************************
2083 *********************************************************************/
2085 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2087 uint8_t *buf = NULL;
2088 int len;
2090 len = init_buffer_from_samu(&buf, src, False);
2091 if (len == -1 || !buf) {
2092 SAFE_FREE(buf);
2093 return False;
2096 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2097 free(buf);
2098 return False;
2101 dst->methods = src->methods;
2103 if ( src->unix_pw ) {
2104 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2105 if (!dst->unix_pw) {
2106 free(buf);
2107 return False;
2111 if (src->group_sid) {
2112 pdb_set_group_sid(dst, src->group_sid, PDB_SET);
2115 free(buf);
2116 return True;
2119 /*********************************************************************
2120 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2121 *********************************************************************/
2123 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2125 time_t LastBadPassword;
2126 uint16_t BadPasswordCount;
2127 uint32_t resettime;
2128 bool res;
2130 BadPasswordCount = pdb_get_bad_password_count(sampass);
2131 if (!BadPasswordCount) {
2132 DEBUG(9, ("No bad password attempts.\n"));
2133 return True;
2136 become_root();
2137 res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2138 unbecome_root();
2140 if (!res) {
2141 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2142 return False;
2145 /* First, check if there is a reset time to compare */
2146 if ((resettime == (uint32_t) -1) || (resettime == 0)) {
2147 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2148 return True;
2151 LastBadPassword = pdb_get_bad_password_time(sampass);
2152 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2153 (uint32_t) LastBadPassword, resettime, (uint32_t)time(NULL)));
2154 if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
2155 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2156 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2157 if (updated) {
2158 *updated = True;
2162 return True;
2165 /*********************************************************************
2166 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2167 *********************************************************************/
2169 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2171 uint32_t duration;
2172 time_t LastBadPassword;
2173 bool res;
2175 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2176 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2177 pdb_get_username(sampass)));
2178 return True;
2181 become_root();
2182 res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2183 unbecome_root();
2185 if (!res) {
2186 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2187 return False;
2190 /* First, check if there is a duration to compare */
2191 if ((duration == (uint32_t) -1) || (duration == 0)) {
2192 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2193 return True;
2196 LastBadPassword = pdb_get_bad_password_time(sampass);
2197 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2198 pdb_get_username(sampass), (uint32_t)LastBadPassword, duration*60, (uint32_t)time(NULL)));
2200 if (LastBadPassword == (time_t)0) {
2201 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2202 "administratively locked out with no bad password "
2203 "time. Leaving locked out.\n",
2204 pdb_get_username(sampass) ));
2205 return True;
2208 if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
2209 pdb_set_acct_ctrl(sampass,
2210 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2211 PDB_CHANGED);
2212 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2213 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2214 if (updated) {
2215 *updated = True;
2219 return True;
2222 /*********************************************************************
2223 Increment the bad_password_count
2224 *********************************************************************/
2226 bool pdb_increment_bad_password_count(struct samu *sampass)
2228 uint32_t account_policy_lockout;
2229 bool autolock_updated = False, badpw_updated = False;
2230 bool ret;
2232 /* Retrieve the account lockout policy */
2233 become_root();
2234 ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2235 unbecome_root();
2236 if ( !ret ) {
2237 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2238 return False;
2241 /* If there is no policy, we don't need to continue checking */
2242 if (!account_policy_lockout) {
2243 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2244 return True;
2247 /* Check if the autolock needs to be cleared */
2248 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2249 return False;
2251 /* Check if the badpw count needs to be reset */
2252 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2253 return False;
2256 Ok, now we can assume that any resetting that needs to be
2257 done has been done, and just get on with incrementing
2258 and autolocking if necessary
2261 pdb_set_bad_password_count(sampass,
2262 pdb_get_bad_password_count(sampass)+1,
2263 PDB_CHANGED);
2264 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2267 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2268 return True;
2270 if (!pdb_set_acct_ctrl(sampass,
2271 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2272 PDB_CHANGED)) {
2273 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2274 return False;
2277 return True;
2280 bool is_dc_trusted_domain_situation(const char *domain_name)
2282 return IS_DC && !strequal(domain_name, lp_workgroup());
2285 /*******************************************************************
2286 Wrapper around retrieving the clear text trust account password.
2287 appropriate account name is stored in account_name.
2288 Caller must free password, but not account_name.
2289 *******************************************************************/
2291 static bool get_trust_pw_clear2(const char *domain,
2292 const char **account_name,
2293 enum netr_SchannelType *channel,
2294 char **cur_pw,
2295 time_t *_last_set_time,
2296 char **prev_pw)
2298 char *pwd;
2299 time_t last_set_time;
2301 if (cur_pw != NULL) {
2302 *cur_pw = NULL;
2304 if (_last_set_time != NULL) {
2305 *_last_set_time = 0;
2307 if (prev_pw != NULL) {
2308 *prev_pw = NULL;
2311 /* if we are a DC and this is not our domain, then lookup an account
2312 * for the domain trust */
2314 if (is_dc_trusted_domain_situation(domain)) {
2315 if (!lp_allow_trusted_domains()) {
2316 return false;
2319 if (!pdb_get_trusteddom_pw(domain, cur_pw, NULL,
2320 &last_set_time))
2322 DEBUG(0, ("get_trust_pw: could not fetch trust "
2323 "account password for trusted domain %s\n",
2324 domain));
2325 return false;
2328 if (channel != NULL) {
2329 *channel = SEC_CHAN_DOMAIN;
2332 if (account_name != NULL) {
2333 *account_name = lp_workgroup();
2336 if (_last_set_time != NULL) {
2337 *_last_set_time = last_set_time;
2340 return true;
2344 * Since we can only be member of one single domain, we are now
2345 * in a member situation:
2347 * - Either we are a DC (selfjoined) and the domain is our
2348 * own domain.
2349 * - Or we are on a member and the domain is our own or some
2350 * other (potentially trusted) domain.
2352 * In both cases, we can only get the machine account password
2353 * for our own domain to connect to our own dc. (For a member,
2354 * request to trusted domains are performed through our dc.)
2356 * So we simply use our own domain name to retrieve the
2357 * machine account passowrd and ignore the request domain here.
2360 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2362 if (pwd != NULL) {
2363 struct timeval expire;
2365 *cur_pw = pwd;
2367 if (account_name != NULL) {
2368 *account_name = lp_netbios_name();
2371 if (_last_set_time != NULL) {
2372 *_last_set_time = last_set_time;
2375 if (prev_pw == NULL) {
2376 return true;
2379 ZERO_STRUCT(expire);
2380 expire.tv_sec = lp_machine_password_timeout();
2381 expire.tv_sec /= 2;
2382 expire.tv_sec += last_set_time;
2383 if (timeval_expired(&expire)) {
2384 return true;
2387 pwd = secrets_fetch_prev_machine_password(lp_workgroup());
2388 if (pwd != NULL) {
2389 *prev_pw = pwd;
2392 return true;
2395 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2396 "account password for domain %s\n", domain));
2397 return false;
2400 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2401 const char **account_name,
2402 enum netr_SchannelType *channel)
2404 return get_trust_pw_clear2(domain,
2405 account_name,
2406 channel,
2407 ret_pwd,
2408 NULL,
2409 NULL);
2412 /*******************************************************************
2413 Wrapper around retrieving the trust account password.
2414 appropriate account name is stored in account_name.
2415 *******************************************************************/
2417 static bool get_trust_pw_hash2(const char *domain,
2418 const char **account_name,
2419 enum netr_SchannelType *channel,
2420 struct samr_Password *current_nt_hash,
2421 time_t *last_set_time,
2422 struct samr_Password **_previous_nt_hash)
2424 char *cur_pw = NULL;
2425 char *prev_pw = NULL;
2426 char **_prev_pw = NULL;
2427 bool ok;
2429 if (_previous_nt_hash != NULL) {
2430 *_previous_nt_hash = NULL;
2431 _prev_pw = &prev_pw;
2434 ok = get_trust_pw_clear2(domain, account_name, channel,
2435 &cur_pw, last_set_time, _prev_pw);
2436 if (ok) {
2437 struct samr_Password *previous_nt_hash = NULL;
2439 E_md4hash(cur_pw, current_nt_hash->hash);
2440 SAFE_FREE(cur_pw);
2442 if (prev_pw == NULL) {
2443 return true;
2446 previous_nt_hash = SMB_MALLOC_P(struct samr_Password);
2447 if (previous_nt_hash == NULL) {
2448 return false;
2451 E_md4hash(prev_pw, previous_nt_hash->hash);
2452 SAFE_FREE(prev_pw);
2454 *_previous_nt_hash = previous_nt_hash;
2455 return true;
2456 } else if (is_dc_trusted_domain_situation(domain)) {
2457 return false;
2460 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2462 if (secrets_fetch_trust_account_password_legacy(domain,
2463 current_nt_hash->hash,
2464 last_set_time,
2465 channel))
2467 if (account_name != NULL) {
2468 *account_name = lp_netbios_name();
2471 return true;
2474 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2475 "password for domain %s\n", domain));
2476 return False;
2479 bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
2480 const char **account_name,
2481 enum netr_SchannelType *channel)
2483 struct samr_Password current_nt_hash;
2484 bool ok;
2486 ok = get_trust_pw_hash2(domain, account_name, channel,
2487 &current_nt_hash, NULL, NULL);
2488 if (!ok) {
2489 return false;
2492 memcpy(ret_pwd, current_nt_hash.hash, sizeof(current_nt_hash.hash));
2493 return true;
2496 NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
2497 const char *dns_domain, /* optional */
2498 TALLOC_CTX *mem_ctx,
2499 struct cli_credentials **_creds)
2501 TALLOC_CTX *frame = talloc_stackframe();
2502 NTSTATUS status;
2503 struct loadparm_context *lp_ctx;
2504 enum netr_SchannelType channel;
2505 time_t last_set_time;
2506 const char *_account_name;
2507 const char *account_name;
2508 char *cur_pw = NULL;
2509 char *prev_pw = NULL;
2510 struct samr_Password cur_nt_hash;
2511 struct cli_credentials *creds = NULL;
2512 bool ok;
2515 * If this is our primary trust relationship, use the common
2516 * code to read the secrets.ldb or secrets.tdb file.
2518 if (strequal(netbios_domain, lp_workgroup())) {
2519 struct db_context *db_ctx = secrets_db_ctx();
2520 if (db_ctx == NULL) {
2521 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2522 netbios_domain));
2523 status = NT_STATUS_INTERNAL_ERROR;
2524 goto fail;
2527 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2528 if (lp_ctx == NULL) {
2529 DEBUG(1, ("loadparm_init_s3 failed\n"));
2530 status = NT_STATUS_INTERNAL_ERROR;
2531 goto fail;
2534 creds = cli_credentials_init(mem_ctx);
2535 if (creds == NULL) {
2536 status = NT_STATUS_NO_MEMORY;
2537 goto fail;
2540 cli_credentials_set_conf(creds, lp_ctx);
2542 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2543 if (!ok) {
2544 status = NT_STATUS_NO_MEMORY;
2545 goto fail;
2548 status = cli_credentials_set_machine_account_db_ctx(creds,
2549 lp_ctx,
2550 db_ctx);
2551 if (!NT_STATUS_IS_OK(status)) {
2552 goto fail;
2554 goto done;
2555 } else if (!IS_DC) {
2556 DEBUG(1, ("Refusing to get trust account info for %s, "
2557 "which is not our primary domain %s, "
2558 "as we are not a DC\n",
2559 netbios_domain, lp_workgroup()));
2560 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2561 goto fail;
2564 status = pdb_get_trusteddom_creds(netbios_domain, mem_ctx, &creds);
2565 if (NT_STATUS_IS_OK(status)) {
2566 goto done;
2568 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
2569 goto fail;
2572 ok = get_trust_pw_clear2(netbios_domain,
2573 &_account_name,
2574 &channel,
2575 &cur_pw,
2576 &last_set_time,
2577 &prev_pw);
2578 if (!ok) {
2579 ok = get_trust_pw_hash2(netbios_domain,
2580 &_account_name,
2581 &channel,
2582 &cur_nt_hash,
2583 &last_set_time,
2584 NULL);
2585 if (!ok) {
2586 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2587 netbios_domain));
2588 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2589 goto fail;
2593 account_name = talloc_asprintf(frame, "%s$", _account_name);
2594 if (account_name == NULL) {
2595 status = NT_STATUS_NO_MEMORY;
2596 goto fail;
2599 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2600 if (lp_ctx == NULL) {
2601 DEBUG(1, ("loadparm_init_s3 failed\n"));
2602 status = NT_STATUS_INTERNAL_ERROR;
2603 goto fail;
2606 creds = cli_credentials_init(mem_ctx);
2607 if (creds == NULL) {
2608 status = NT_STATUS_NO_MEMORY;
2609 goto fail;
2612 cli_credentials_set_conf(creds, lp_ctx);
2614 cli_credentials_set_secure_channel_type(creds, channel);
2615 cli_credentials_set_password_last_changed_time(creds, last_set_time);
2617 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2618 if (!ok) {
2619 status = NT_STATUS_NO_MEMORY;
2620 goto fail;
2623 if (dns_domain != NULL) {
2624 ok = cli_credentials_set_realm(creds, dns_domain, CRED_SPECIFIED);
2625 if (!ok) {
2626 status = NT_STATUS_NO_MEMORY;
2627 goto fail;
2631 * It's not possible to use NTLMSSP with a domain trust account.
2633 cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS);
2634 } else {
2636 * We can't use kerberos against an NT4 domain.
2638 * We should have a mode that also disallows NTLMSSP here,
2639 * as only NETLOGON SCHANNEL is possible.
2641 cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
2644 ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
2645 if (!ok) {
2646 status = NT_STATUS_NO_MEMORY;
2647 goto fail;
2650 if (cur_pw == NULL) {
2651 ok = cli_credentials_set_nt_hash(creds, &cur_nt_hash, CRED_SPECIFIED);
2652 if (!ok) {
2653 status = NT_STATUS_NO_MEMORY;
2654 goto fail;
2657 * We currently can't do kerberos just with an NTHASH.
2659 cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
2660 goto done;
2663 ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
2664 if (!ok) {
2665 status = NT_STATUS_NO_MEMORY;
2666 goto fail;
2669 if (prev_pw != NULL) {
2670 ok = cli_credentials_set_old_password(creds, prev_pw, CRED_SPECIFIED);
2671 if (!ok) {
2672 status = NT_STATUS_NO_MEMORY;
2673 goto fail;
2677 done:
2678 *_creds = creds;
2679 creds = NULL;
2680 status = NT_STATUS_OK;
2681 fail:
2682 TALLOC_FREE(creds);
2683 SAFE_FREE(cur_pw);
2684 SAFE_FREE(prev_pw);
2685 TALLOC_FREE(frame);
2686 return status;