s3: Attempt to fix the build without kerberos
[Samba/gebeck_regimport.git] / source3 / passdb / passdb.c
blob6d3f42e720ffc10fb19f75326aa05297315d1fdb
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"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_PASSDB
37 /******************************************************************
38 Get the default domain/netbios name to be used when
39 testing authentication.
41 LEGACY: this function provides the legacy domain mapping used with
42 the lp_map_untrusted_to_domain() parameter
43 ******************************************************************/
45 const char *my_sam_name(void)
47 /* Standalone servers can only use the local netbios name */
48 if ( lp_server_role() == ROLE_STANDALONE )
49 return lp_netbios_name();
51 /* Default to the DOMAIN name when not specified */
52 return lp_workgroup();
55 /**********************************************************************
56 ***********************************************************************/
58 static int samu_destroy(struct samu *user)
60 data_blob_clear_free( &user->lm_pw );
61 data_blob_clear_free( &user->nt_pw );
63 if ( user->plaintext_pw )
64 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
66 return 0;
69 /**********************************************************************
70 generate a new struct samuser
71 ***********************************************************************/
73 struct samu *samu_new( TALLOC_CTX *ctx )
75 struct samu *user;
77 if ( !(user = talloc_zero( ctx, struct samu )) ) {
78 DEBUG(0,("samuser_new: Talloc failed!\n"));
79 return NULL;
82 talloc_set_destructor( user, samu_destroy );
84 /* no initial methods */
86 user->methods = NULL;
88 /* Don't change these timestamp settings without a good reason.
89 They are important for NT member server compatibility. */
91 user->logon_time = (time_t)0;
92 user->pass_last_set_time = (time_t)0;
93 user->pass_can_change_time = (time_t)0;
94 user->logoff_time = get_time_t_max();
95 user->kickoff_time = get_time_t_max();
96 user->fields_present = 0x00ffffff;
97 user->logon_divs = 168; /* hours per week */
98 user->hours_len = 21; /* 21 times 8 bits = 168 */
99 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
100 user->bad_password_count = 0;
101 user->logon_count = 0;
102 user->unknown_6 = 0x000004ec; /* don't know */
104 /* Some parts of samba strlen their pdb_get...() returns,
105 so this keeps the interface unchanged for now. */
107 user->username = "";
108 user->domain = "";
109 user->nt_username = "";
110 user->full_name = "";
111 user->home_dir = "";
112 user->logon_script = "";
113 user->profile_path = "";
114 user->acct_desc = "";
115 user->workstations = "";
116 user->comment = "";
117 user->munged_dial = "";
119 user->plaintext_pw = NULL;
121 /* Unless we know otherwise have a Account Control Bit
122 value of 'normal user'. This helps User Manager, which
123 asks for a filtered list of users. */
125 user->acct_ctrl = ACB_NORMAL;
127 return user;
130 static int count_commas(const char *str)
132 int num_commas = 0;
133 const char *comma = str;
135 while ((comma = strchr(comma, ',')) != NULL) {
136 comma += 1;
137 num_commas += 1;
139 return num_commas;
142 /*********************************************************************
143 Initialize a struct samu from a struct passwd including the user
144 and group SIDs. The *user structure is filled out with the Unix
145 attributes and a user SID.
146 *********************************************************************/
148 static NTSTATUS samu_set_unix_internal(struct pdb_methods *methods,
149 struct samu *user, const struct passwd *pwd, bool create)
151 const char *guest_account = lp_guestaccount();
152 const char *domain = lp_netbios_name();
153 char *fullname;
154 uint32_t urid;
156 if ( !pwd ) {
157 return NT_STATUS_NO_SUCH_USER;
160 /* Basic properties based upon the Unix account information */
162 pdb_set_username(user, pwd->pw_name, PDB_SET);
164 fullname = NULL;
166 if (count_commas(pwd->pw_gecos) == 3) {
168 * Heuristic: This seems to be a gecos field that has been
169 * edited by chfn(1). Only use the part before the first
170 * comma. Fixes bug 5198.
172 fullname = talloc_strndup(
173 talloc_tos(), pwd->pw_gecos,
174 strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
177 if (fullname != NULL) {
178 pdb_set_fullname(user, fullname, PDB_SET);
179 } else {
180 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
182 TALLOC_FREE(fullname);
184 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
185 #if 0
186 /* This can lead to a primary group of S-1-22-2-XX which
187 will be rejected by other parts of the Samba code.
188 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
189 --jerry */
191 gid_to_sid(&group_sid, pwd->pw_gid);
192 pdb_set_group_sid(user, &group_sid, PDB_SET);
193 #endif
195 /* save the password structure for later use */
197 user->unix_pw = tcopy_passwd( user, pwd );
199 /* Special case for the guest account which must have a RID of 501 */
201 if ( strequal( pwd->pw_name, guest_account ) ) {
202 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
203 return NT_STATUS_NO_SUCH_USER;
205 return NT_STATUS_OK;
208 /* Non-guest accounts...Check for a workstation or user account */
210 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
211 /* workstation */
213 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
214 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
215 pwd->pw_name));
216 return NT_STATUS_INVALID_COMPUTER_NAME;
219 else {
220 /* user */
222 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
223 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
224 pwd->pw_name));
225 return NT_STATUS_INVALID_ACCOUNT_NAME;
228 /* set some basic attributes */
230 pdb_set_profile_path(user, talloc_sub_specified(user,
231 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
232 PDB_DEFAULT);
233 pdb_set_homedir(user, talloc_sub_specified(user,
234 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
235 PDB_DEFAULT);
236 pdb_set_dir_drive(user, talloc_sub_specified(user,
237 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
238 PDB_DEFAULT);
239 pdb_set_logon_script(user, talloc_sub_specified(user,
240 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
241 PDB_DEFAULT);
244 /* Now deal with the user SID. If we have a backend that can generate
245 RIDs, then do so. But sometimes the caller just wanted a structure
246 initialized and will fill in these fields later (such as from a
247 netr_SamInfo3 structure) */
249 if ( create && (methods->capabilities(methods) & PDB_CAP_STORE_RIDS)) {
250 uint32_t user_rid;
251 struct dom_sid user_sid;
253 if ( !methods->new_rid(methods, &user_rid) ) {
254 DEBUG(3, ("Could not allocate a new RID\n"));
255 return NT_STATUS_ACCESS_DENIED;
258 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
260 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
261 DEBUG(3, ("pdb_set_user_sid failed\n"));
262 return NT_STATUS_INTERNAL_ERROR;
265 return NT_STATUS_OK;
268 /* generate a SID for the user with the RID algorithm */
270 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
272 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
273 return NT_STATUS_INTERNAL_ERROR;
276 return NT_STATUS_OK;
279 /********************************************************************
280 Set the Unix user attributes
281 ********************************************************************/
283 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
285 return samu_set_unix_internal( NULL, user, pwd, False );
288 NTSTATUS samu_alloc_rid_unix(struct pdb_methods *methods,
289 struct samu *user, const struct passwd *pwd)
291 return samu_set_unix_internal( methods, user, pwd, True );
294 /**********************************************************
295 Encode the account control bits into a string.
296 length = length of string to encode into (including terminating
297 null). length *MUST BE MORE THAN 2* !
298 **********************************************************/
300 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
302 fstring acct_str;
303 char *result;
305 size_t i = 0;
307 SMB_ASSERT(length <= sizeof(acct_str));
309 acct_str[i++] = '[';
311 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
312 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
313 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
314 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
315 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
316 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
317 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
318 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
319 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
320 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
321 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
323 for ( ; i < length - 2 ; i++ )
324 acct_str[i] = ' ';
326 i = length - 2;
327 acct_str[i++] = ']';
328 acct_str[i++] = '\0';
330 result = talloc_strdup(talloc_tos(), acct_str);
331 SMB_ASSERT(result != NULL);
332 return result;
335 /**********************************************************
336 Decode the account control bits from a string.
337 **********************************************************/
339 uint32_t pdb_decode_acct_ctrl(const char *p)
341 uint32_t acct_ctrl = 0;
342 bool finished = false;
345 * Check if the account type bits have been encoded after the
346 * NT password (in the form [NDHTUWSLXI]).
349 if (*p != '[')
350 return 0;
352 for (p++; *p && !finished; p++) {
353 switch (*p) {
354 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
355 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
356 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
357 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
358 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
359 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
360 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
361 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
362 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
363 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
364 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
365 case ' ': { break; }
366 case ':':
367 case '\n':
368 case '\0':
369 case ']':
370 default: { finished = true; }
374 return acct_ctrl;
377 /*************************************************************
378 Routine to set 32 hex password characters from a 16 byte array.
379 **************************************************************/
381 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
383 if (pwd != NULL) {
384 int i;
385 for (i = 0; i < 16; i++)
386 slprintf(&p[i*2], 3, "%02X", pwd[i]);
387 } else {
388 if (acct_ctrl & ACB_PWNOTREQ)
389 strlcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
390 else
391 strlcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
395 /*************************************************************
396 Routine to get the 32 hex characters and turn them
397 into a 16 byte array.
398 **************************************************************/
400 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
402 int i;
403 unsigned char lonybble, hinybble;
404 const char *hexchars = "0123456789ABCDEF";
405 char *p1, *p2;
407 if (!p)
408 return false;
410 for (i = 0; i < 32; i += 2) {
411 hinybble = toupper_m(p[i]);
412 lonybble = toupper_m(p[i + 1]);
414 p1 = strchr(hexchars, hinybble);
415 p2 = strchr(hexchars, lonybble);
417 if (!p1 || !p2)
418 return false;
420 hinybble = PTR_DIFF(p1, hexchars);
421 lonybble = PTR_DIFF(p2, hexchars);
423 pwd[i / 2] = (hinybble << 4) | lonybble;
425 return true;
428 /*************************************************************
429 Routine to set 42 hex hours characters from a 21 byte array.
430 **************************************************************/
432 void pdb_sethexhours(char *p, const unsigned char *hours)
434 if (hours != NULL) {
435 int i;
436 for (i = 0; i < 21; i++) {
437 slprintf(&p[i*2], 3, "%02X", hours[i]);
439 } else {
440 strlcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
444 /*************************************************************
445 Routine to get the 42 hex characters and turn them
446 into a 21 byte array.
447 **************************************************************/
449 bool pdb_gethexhours(const char *p, unsigned char *hours)
451 int i;
452 unsigned char lonybble, hinybble;
453 const char *hexchars = "0123456789ABCDEF";
454 char *p1, *p2;
456 if (!p) {
457 return (False);
460 for (i = 0; i < 42; i += 2) {
461 hinybble = toupper_m(p[i]);
462 lonybble = toupper_m(p[i + 1]);
464 p1 = strchr(hexchars, hinybble);
465 p2 = strchr(hexchars, lonybble);
467 if (!p1 || !p2) {
468 return (False);
471 hinybble = PTR_DIFF(p1, hexchars);
472 lonybble = PTR_DIFF(p2, hexchars);
474 hours[i / 2] = (hinybble << 4) | lonybble;
476 return (True);
479 /********************************************************************
480 ********************************************************************/
482 int algorithmic_rid_base(void)
484 int rid_offset;
486 rid_offset = lp_algorithmic_rid_base();
488 if (rid_offset < BASE_RID) {
489 /* Try to prevent admin foot-shooting, we can't put algorithmic
490 rids below 1000, that's the 'well known RIDs' on NT */
491 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
492 rid_offset = BASE_RID;
494 if (rid_offset & 1) {
495 DEBUG(0, ("algorithmic rid base must be even\n"));
496 rid_offset += 1;
498 return rid_offset;
501 /*******************************************************************
502 Converts NT user RID to a UNIX uid.
503 ********************************************************************/
505 uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
507 int rid_offset = algorithmic_rid_base();
508 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
511 uid_t max_algorithmic_uid(void)
513 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
516 /*******************************************************************
517 converts UNIX uid to an NT User RID.
518 ********************************************************************/
520 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
522 int rid_offset = algorithmic_rid_base();
523 return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
526 /*******************************************************************
527 Converts NT group RID to a UNIX gid.
528 ********************************************************************/
530 gid_t pdb_group_rid_to_gid(uint32_t group_rid)
532 int rid_offset = algorithmic_rid_base();
533 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
536 gid_t max_algorithmic_gid(void)
538 return pdb_group_rid_to_gid(0xffffffff);
541 /*******************************************************************
542 converts NT Group RID to a UNIX uid.
544 warning: you must not call that function only
545 you must do a call to the group mapping first.
546 there is not anymore a direct link between the gid and the rid.
547 ********************************************************************/
549 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
551 int rid_offset = algorithmic_rid_base();
552 return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
555 /*******************************************************************
556 Decides if a RID is a well known RID.
557 ********************************************************************/
559 static bool rid_is_well_known(uint32_t rid)
561 /* Not using rid_offset here, because this is the actual
562 NT fixed value (1000) */
564 return (rid < BASE_RID);
567 /*******************************************************************
568 Decides if a RID is a user or group RID.
569 ********************************************************************/
571 bool algorithmic_pdb_rid_is_user(uint32_t rid)
573 if ( rid_is_well_known(rid) ) {
575 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
576 * and DOMAIN_RID_GUEST.
578 if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
579 return True;
580 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
581 return True;
583 return False;
586 /*******************************************************************
587 Convert a name into a SID. Used in the lookup name rpc.
588 ********************************************************************/
590 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
591 enum lsa_SidType *type)
593 GROUP_MAP *map;
594 bool ret;
596 /* Windows treats "MACHINE\None" as a special name for
597 rid 513 on non-DCs. You cannot create a user or group
598 name "None" on Windows. You will get an error that
599 the group already exists. */
601 if ( strequal( name, "None" ) ) {
602 *rid = DOMAIN_RID_USERS;
603 *type = SID_NAME_DOM_GRP;
605 return True;
608 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
609 * correctly in the case where foo also exists as a user. If the flag
610 * is set, don't look for users at all. */
612 if ((flags & LOOKUP_NAME_GROUP) == 0) {
613 struct samu *sam_account = NULL;
614 struct dom_sid user_sid;
616 if ( !(sam_account = samu_new( NULL )) ) {
617 return False;
620 become_root();
621 ret = pdb_getsampwnam(sam_account, name);
622 unbecome_root();
624 if (ret) {
625 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
628 TALLOC_FREE(sam_account);
630 if (ret) {
631 if (!sid_check_is_in_our_domain(&user_sid)) {
632 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
633 name, sid_string_dbg(&user_sid)));
634 return False;
637 sid_peek_rid(&user_sid, rid);
638 *type = SID_NAME_USER;
639 return True;
644 * Maybe it is a group ?
647 map = talloc_zero(NULL, GROUP_MAP);
648 if (!map) {
649 return false;
652 become_root();
653 ret = pdb_getgrnam(map, name);
654 unbecome_root();
656 if (!ret) {
657 TALLOC_FREE(map);
658 return False;
661 /* BUILTIN groups are looked up elsewhere */
662 if (!sid_check_is_in_our_domain(&map->sid)) {
663 DEBUG(10, ("Found group %s (%s) not in our domain -- "
664 "ignoring.", name, sid_string_dbg(&map->sid)));
665 TALLOC_FREE(map);
666 return False;
669 /* yes it's a mapped group */
670 sid_peek_rid(&map->sid, rid);
671 *type = map->sid_name_use;
672 TALLOC_FREE(map);
673 return True;
676 /*************************************************************
677 Change a password entry in the local passdb backend.
679 Assumptions:
680 - always called as root
681 - ignores the account type except when adding a new account
682 - will create/delete the unix account if the relative
683 add/delete user script is configured
685 *************************************************************/
687 NTSTATUS local_password_change(const char *user_name,
688 int local_flags,
689 const char *new_passwd,
690 char **pp_err_str,
691 char **pp_msg_str)
693 TALLOC_CTX *tosctx;
694 struct samu *sam_pass;
695 uint32_t acb;
696 uint32_t rid;
697 NTSTATUS result;
698 bool user_exists;
699 int ret = -1;
701 *pp_err_str = NULL;
702 *pp_msg_str = NULL;
704 tosctx = talloc_tos();
706 sam_pass = samu_new(tosctx);
707 if (!sam_pass) {
708 result = NT_STATUS_NO_MEMORY;
709 goto done;
712 /* Get the smb passwd entry for this user */
713 user_exists = pdb_getsampwnam(sam_pass, user_name);
715 /* Check delete first, we don't need to do anything else if we
716 * are going to delete the acocunt */
717 if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
719 result = pdb_delete_user(tosctx, sam_pass);
720 if (!NT_STATUS_IS_OK(result)) {
721 ret = asprintf(pp_err_str,
722 "Failed to delete entry for user %s.\n",
723 user_name);
724 if (ret < 0) {
725 *pp_err_str = NULL;
727 result = NT_STATUS_UNSUCCESSFUL;
728 } else {
729 ret = asprintf(pp_msg_str,
730 "Deleted user %s.\n",
731 user_name);
732 if (ret < 0) {
733 *pp_msg_str = NULL;
736 goto done;
739 if (user_exists && (local_flags & LOCAL_ADD_USER)) {
740 /* the entry already existed */
741 local_flags &= ~LOCAL_ADD_USER;
744 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
745 ret = asprintf(pp_err_str,
746 "Failed to find entry for user %s.\n",
747 user_name);
748 if (ret < 0) {
749 *pp_err_str = NULL;
751 result = NT_STATUS_NO_SUCH_USER;
752 goto done;
755 /* First thing add the new user if we are required to do so */
756 if (local_flags & LOCAL_ADD_USER) {
758 if (local_flags & LOCAL_TRUST_ACCOUNT) {
759 acb = ACB_WSTRUST;
760 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
761 acb = ACB_DOMTRUST;
762 } else {
763 acb = ACB_NORMAL;
766 result = pdb_create_user(tosctx, user_name, acb, &rid);
767 if (!NT_STATUS_IS_OK(result)) {
768 ret = asprintf(pp_err_str,
769 "Failed to add entry for user %s.\n",
770 user_name);
771 if (ret < 0) {
772 *pp_err_str = NULL;
774 result = NT_STATUS_UNSUCCESSFUL;
775 goto done;
778 sam_pass = samu_new(tosctx);
779 if (!sam_pass) {
780 result = NT_STATUS_NO_MEMORY;
781 goto done;
784 /* Now get back the smb passwd entry for this new user */
785 user_exists = pdb_getsampwnam(sam_pass, user_name);
786 if (!user_exists) {
787 ret = asprintf(pp_err_str,
788 "Failed to add entry for user %s.\n",
789 user_name);
790 if (ret < 0) {
791 *pp_err_str = NULL;
793 result = NT_STATUS_UNSUCCESSFUL;
794 goto done;
798 acb = pdb_get_acct_ctrl(sam_pass);
801 * We are root - just write the new password
802 * and the valid last change time.
804 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
805 acb |= ACB_PWNOTREQ;
806 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
807 ret = asprintf(pp_err_str,
808 "Failed to set 'no password required' "
809 "flag for user %s.\n", user_name);
810 if (ret < 0) {
811 *pp_err_str = NULL;
813 result = NT_STATUS_UNSUCCESSFUL;
814 goto done;
818 if (local_flags & LOCAL_SET_PASSWORD) {
820 * If we're dealing with setting a completely empty user account
821 * ie. One with a password of 'XXXX', but not set disabled (like
822 * an account created from scratch) then if the old password was
823 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
824 * We remove that as we're giving this user their first password
825 * and the decision hasn't really been made to disable them (ie.
826 * don't create them disabled). JRA.
828 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
829 (acb & ACB_DISABLED)) {
830 acb &= (~ACB_DISABLED);
831 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
832 ret = asprintf(pp_err_str,
833 "Failed to unset 'disabled' "
834 "flag for user %s.\n",
835 user_name);
836 if (ret < 0) {
837 *pp_err_str = NULL;
839 result = NT_STATUS_UNSUCCESSFUL;
840 goto done;
844 acb &= (~ACB_PWNOTREQ);
845 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
846 ret = asprintf(pp_err_str,
847 "Failed to unset 'no password required'"
848 " flag for user %s.\n", user_name);
849 if (ret < 0) {
850 *pp_err_str = NULL;
852 result = NT_STATUS_UNSUCCESSFUL;
853 goto done;
856 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
857 ret = asprintf(pp_err_str,
858 "Failed to set password for "
859 "user %s.\n", user_name);
860 if (ret < 0) {
861 *pp_err_str = NULL;
863 result = NT_STATUS_UNSUCCESSFUL;
864 goto done;
868 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
869 acb |= ACB_DISABLED;
870 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
871 ret = asprintf(pp_err_str,
872 "Failed to set 'disabled' flag for "
873 "user %s.\n", user_name);
874 if (ret < 0) {
875 *pp_err_str = NULL;
877 result = NT_STATUS_UNSUCCESSFUL;
878 goto done;
882 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
883 acb &= (~ACB_DISABLED);
884 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
885 ret = asprintf(pp_err_str,
886 "Failed to unset 'disabled' flag for "
887 "user %s.\n", user_name);
888 if (ret < 0) {
889 *pp_err_str = NULL;
891 result = NT_STATUS_UNSUCCESSFUL;
892 goto done;
896 /* now commit changes if any */
897 result = pdb_update_sam_account(sam_pass);
898 if (!NT_STATUS_IS_OK(result)) {
899 ret = asprintf(pp_err_str,
900 "Failed to modify entry for user %s.\n",
901 user_name);
902 if (ret < 0) {
903 *pp_err_str = NULL;
905 goto done;
908 if (local_flags & LOCAL_ADD_USER) {
909 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
910 } else if (local_flags & LOCAL_DISABLE_USER) {
911 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
912 } else if (local_flags & LOCAL_ENABLE_USER) {
913 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
914 } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
915 ret = asprintf(pp_msg_str,
916 "User %s password set to none.\n", user_name);
919 if (ret < 0) {
920 *pp_msg_str = NULL;
923 result = NT_STATUS_OK;
925 done:
926 TALLOC_FREE(sam_pass);
927 return result;
930 /**********************************************************************
931 Marshall/unmarshall struct samu structs.
932 *********************************************************************/
934 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
935 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
936 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
937 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
938 /* nothing changed between V3 and V4 */
940 /*********************************************************************
941 *********************************************************************/
943 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
946 /* times are stored as 32bit integer
947 take care on system with 64bit wide time_t
948 --SSS */
949 uint32_t logon_time,
950 logoff_time,
951 kickoff_time,
952 pass_last_set_time,
953 pass_can_change_time,
954 pass_must_change_time;
955 char *username = NULL;
956 char *domain = NULL;
957 char *nt_username = NULL;
958 char *dir_drive = NULL;
959 char *unknown_str = NULL;
960 char *munged_dial = NULL;
961 char *fullname = NULL;
962 char *homedir = NULL;
963 char *logon_script = NULL;
964 char *profile_path = NULL;
965 char *acct_desc = NULL;
966 char *workstations = NULL;
967 uint32_t username_len, domain_len, nt_username_len,
968 dir_drive_len, unknown_str_len, munged_dial_len,
969 fullname_len, homedir_len, logon_script_len,
970 profile_path_len, acct_desc_len, workstations_len;
972 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
973 uint16_t acct_ctrl, logon_divs;
974 uint16_t bad_password_count, logon_count;
975 uint8_t *hours = NULL;
976 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
977 uint32_t len = 0;
978 uint32_t lm_pw_len, nt_pw_len, hourslen;
979 bool ret = True;
981 if(sampass == NULL || buf == NULL) {
982 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
983 return False;
986 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
988 /* unpack the buffer into variables */
989 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
990 &logon_time, /* d */
991 &logoff_time, /* d */
992 &kickoff_time, /* d */
993 &pass_last_set_time, /* d */
994 &pass_can_change_time, /* d */
995 &pass_must_change_time, /* d */
996 &username_len, &username, /* B */
997 &domain_len, &domain, /* B */
998 &nt_username_len, &nt_username, /* B */
999 &fullname_len, &fullname, /* B */
1000 &homedir_len, &homedir, /* B */
1001 &dir_drive_len, &dir_drive, /* B */
1002 &logon_script_len, &logon_script, /* B */
1003 &profile_path_len, &profile_path, /* B */
1004 &acct_desc_len, &acct_desc, /* B */
1005 &workstations_len, &workstations, /* B */
1006 &unknown_str_len, &unknown_str, /* B */
1007 &munged_dial_len, &munged_dial, /* B */
1008 &user_rid, /* d */
1009 &group_rid, /* d */
1010 &lm_pw_len, &lm_pw_ptr, /* B */
1011 &nt_pw_len, &nt_pw_ptr, /* B */
1012 &acct_ctrl, /* w */
1013 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1014 &logon_divs, /* w */
1015 &hours_len, /* d */
1016 &hourslen, &hours, /* B */
1017 &bad_password_count, /* w */
1018 &logon_count, /* w */
1019 &unknown_6); /* d */
1021 if (len == (uint32_t) -1) {
1022 ret = False;
1023 goto done;
1026 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1027 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1028 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1029 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1030 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1032 pdb_set_username(sampass, username, PDB_SET);
1033 pdb_set_domain(sampass, domain, PDB_SET);
1034 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1035 pdb_set_fullname(sampass, fullname, PDB_SET);
1037 if (homedir) {
1038 pdb_set_homedir(sampass, homedir, PDB_SET);
1040 else {
1041 pdb_set_homedir(sampass,
1042 talloc_sub_basic(sampass, username, domain,
1043 lp_logon_home()),
1044 PDB_DEFAULT);
1047 if (dir_drive)
1048 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1049 else {
1050 pdb_set_dir_drive(sampass,
1051 talloc_sub_basic(sampass, username, domain,
1052 lp_logon_drive()),
1053 PDB_DEFAULT);
1056 if (logon_script)
1057 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1058 else {
1059 pdb_set_logon_script(sampass,
1060 talloc_sub_basic(sampass, username, domain,
1061 lp_logon_script()),
1062 PDB_DEFAULT);
1065 if (profile_path) {
1066 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1067 } else {
1068 pdb_set_profile_path(sampass,
1069 talloc_sub_basic(sampass, username, domain,
1070 lp_logon_path()),
1071 PDB_DEFAULT);
1074 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1075 pdb_set_workstations(sampass, workstations, PDB_SET);
1076 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1078 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1079 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1080 ret = False;
1081 goto done;
1085 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1086 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1087 ret = False;
1088 goto done;
1092 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1093 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1094 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1095 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1096 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1097 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1098 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1099 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1100 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1101 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1103 done:
1105 SAFE_FREE(username);
1106 SAFE_FREE(domain);
1107 SAFE_FREE(nt_username);
1108 SAFE_FREE(fullname);
1109 SAFE_FREE(homedir);
1110 SAFE_FREE(dir_drive);
1111 SAFE_FREE(logon_script);
1112 SAFE_FREE(profile_path);
1113 SAFE_FREE(acct_desc);
1114 SAFE_FREE(workstations);
1115 SAFE_FREE(munged_dial);
1116 SAFE_FREE(unknown_str);
1117 SAFE_FREE(lm_pw_ptr);
1118 SAFE_FREE(nt_pw_ptr);
1119 SAFE_FREE(hours);
1121 return ret;
1124 /*********************************************************************
1125 *********************************************************************/
1127 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1130 /* times are stored as 32bit integer
1131 take care on system with 64bit wide time_t
1132 --SSS */
1133 uint32_t logon_time,
1134 logoff_time,
1135 kickoff_time,
1136 bad_password_time,
1137 pass_last_set_time,
1138 pass_can_change_time,
1139 pass_must_change_time;
1140 char *username = NULL;
1141 char *domain = NULL;
1142 char *nt_username = NULL;
1143 char *dir_drive = NULL;
1144 char *unknown_str = NULL;
1145 char *munged_dial = NULL;
1146 char *fullname = NULL;
1147 char *homedir = NULL;
1148 char *logon_script = NULL;
1149 char *profile_path = NULL;
1150 char *acct_desc = NULL;
1151 char *workstations = NULL;
1152 uint32_t username_len, domain_len, nt_username_len,
1153 dir_drive_len, unknown_str_len, munged_dial_len,
1154 fullname_len, homedir_len, logon_script_len,
1155 profile_path_len, acct_desc_len, workstations_len;
1157 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
1158 uint16_t acct_ctrl, logon_divs;
1159 uint16_t bad_password_count, logon_count;
1160 uint8_t *hours = NULL;
1161 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1162 uint32_t len = 0;
1163 uint32_t lm_pw_len, nt_pw_len, hourslen;
1164 bool ret = True;
1166 if(sampass == NULL || buf == NULL) {
1167 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1168 return False;
1171 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1173 /* unpack the buffer into variables */
1174 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1175 &logon_time, /* d */
1176 &logoff_time, /* d */
1177 &kickoff_time, /* d */
1178 /* Change from V0 is addition of bad_password_time field. */
1179 &bad_password_time, /* d */
1180 &pass_last_set_time, /* d */
1181 &pass_can_change_time, /* d */
1182 &pass_must_change_time, /* d */
1183 &username_len, &username, /* B */
1184 &domain_len, &domain, /* B */
1185 &nt_username_len, &nt_username, /* B */
1186 &fullname_len, &fullname, /* B */
1187 &homedir_len, &homedir, /* B */
1188 &dir_drive_len, &dir_drive, /* B */
1189 &logon_script_len, &logon_script, /* B */
1190 &profile_path_len, &profile_path, /* B */
1191 &acct_desc_len, &acct_desc, /* B */
1192 &workstations_len, &workstations, /* B */
1193 &unknown_str_len, &unknown_str, /* B */
1194 &munged_dial_len, &munged_dial, /* B */
1195 &user_rid, /* d */
1196 &group_rid, /* d */
1197 &lm_pw_len, &lm_pw_ptr, /* B */
1198 &nt_pw_len, &nt_pw_ptr, /* B */
1199 &acct_ctrl, /* w */
1200 &remove_me, /* d */
1201 &logon_divs, /* w */
1202 &hours_len, /* d */
1203 &hourslen, &hours, /* B */
1204 &bad_password_count, /* w */
1205 &logon_count, /* w */
1206 &unknown_6); /* d */
1208 if (len == (uint32_t) -1) {
1209 ret = False;
1210 goto done;
1213 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1214 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1215 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1217 /* Change from V0 is addition of bad_password_time field. */
1218 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1219 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1220 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1222 pdb_set_username(sampass, username, PDB_SET);
1223 pdb_set_domain(sampass, domain, PDB_SET);
1224 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1225 pdb_set_fullname(sampass, fullname, PDB_SET);
1227 if (homedir) {
1228 pdb_set_homedir(sampass, homedir, PDB_SET);
1230 else {
1231 pdb_set_homedir(sampass,
1232 talloc_sub_basic(sampass, username, domain,
1233 lp_logon_home()),
1234 PDB_DEFAULT);
1237 if (dir_drive)
1238 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1239 else {
1240 pdb_set_dir_drive(sampass,
1241 talloc_sub_basic(sampass, username, domain,
1242 lp_logon_drive()),
1243 PDB_DEFAULT);
1246 if (logon_script)
1247 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1248 else {
1249 pdb_set_logon_script(sampass,
1250 talloc_sub_basic(sampass, username, domain,
1251 lp_logon_script()),
1252 PDB_DEFAULT);
1255 if (profile_path) {
1256 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1257 } else {
1258 pdb_set_profile_path(sampass,
1259 talloc_sub_basic(sampass, username, domain,
1260 lp_logon_path()),
1261 PDB_DEFAULT);
1264 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1265 pdb_set_workstations(sampass, workstations, PDB_SET);
1266 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1268 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1269 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1270 ret = False;
1271 goto done;
1275 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1276 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1277 ret = False;
1278 goto done;
1282 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1284 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1285 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1286 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1287 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1288 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1289 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1290 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1291 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1292 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1294 done:
1296 SAFE_FREE(username);
1297 SAFE_FREE(domain);
1298 SAFE_FREE(nt_username);
1299 SAFE_FREE(fullname);
1300 SAFE_FREE(homedir);
1301 SAFE_FREE(dir_drive);
1302 SAFE_FREE(logon_script);
1303 SAFE_FREE(profile_path);
1304 SAFE_FREE(acct_desc);
1305 SAFE_FREE(workstations);
1306 SAFE_FREE(munged_dial);
1307 SAFE_FREE(unknown_str);
1308 SAFE_FREE(lm_pw_ptr);
1309 SAFE_FREE(nt_pw_ptr);
1310 SAFE_FREE(hours);
1312 return ret;
1315 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1318 /* times are stored as 32bit integer
1319 take care on system with 64bit wide time_t
1320 --SSS */
1321 uint32_t logon_time,
1322 logoff_time,
1323 kickoff_time,
1324 bad_password_time,
1325 pass_last_set_time,
1326 pass_can_change_time,
1327 pass_must_change_time;
1328 char *username = NULL;
1329 char *domain = NULL;
1330 char *nt_username = NULL;
1331 char *dir_drive = NULL;
1332 char *unknown_str = NULL;
1333 char *munged_dial = NULL;
1334 char *fullname = NULL;
1335 char *homedir = NULL;
1336 char *logon_script = NULL;
1337 char *profile_path = NULL;
1338 char *acct_desc = NULL;
1339 char *workstations = NULL;
1340 uint32_t username_len, domain_len, nt_username_len,
1341 dir_drive_len, unknown_str_len, munged_dial_len,
1342 fullname_len, homedir_len, logon_script_len,
1343 profile_path_len, acct_desc_len, workstations_len;
1345 uint32_t user_rid, group_rid, hours_len, unknown_6;
1346 uint16_t acct_ctrl, logon_divs;
1347 uint16_t bad_password_count, logon_count;
1348 uint8_t *hours = NULL;
1349 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1350 uint32_t len = 0;
1351 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1352 uint32_t pwHistLen = 0;
1353 bool ret = True;
1354 fstring tmp_string;
1355 bool expand_explicit = lp_passdb_expand_explicit();
1357 if(sampass == NULL || buf == NULL) {
1358 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1359 return False;
1362 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1364 /* unpack the buffer into variables */
1365 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1366 &logon_time, /* d */
1367 &logoff_time, /* d */
1368 &kickoff_time, /* d */
1369 &bad_password_time, /* d */
1370 &pass_last_set_time, /* d */
1371 &pass_can_change_time, /* d */
1372 &pass_must_change_time, /* d */
1373 &username_len, &username, /* B */
1374 &domain_len, &domain, /* B */
1375 &nt_username_len, &nt_username, /* B */
1376 &fullname_len, &fullname, /* B */
1377 &homedir_len, &homedir, /* B */
1378 &dir_drive_len, &dir_drive, /* B */
1379 &logon_script_len, &logon_script, /* B */
1380 &profile_path_len, &profile_path, /* B */
1381 &acct_desc_len, &acct_desc, /* B */
1382 &workstations_len, &workstations, /* B */
1383 &unknown_str_len, &unknown_str, /* B */
1384 &munged_dial_len, &munged_dial, /* B */
1385 &user_rid, /* d */
1386 &group_rid, /* d */
1387 &lm_pw_len, &lm_pw_ptr, /* B */
1388 &nt_pw_len, &nt_pw_ptr, /* B */
1389 /* Change from V1 is addition of password history field. */
1390 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1391 &acct_ctrl, /* w */
1392 /* Also "remove_me" field was removed. */
1393 &logon_divs, /* w */
1394 &hours_len, /* d */
1395 &hourslen, &hours, /* B */
1396 &bad_password_count, /* w */
1397 &logon_count, /* w */
1398 &unknown_6); /* d */
1400 if (len == (uint32_t) -1) {
1401 ret = False;
1402 goto done;
1405 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1406 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1407 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1408 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1409 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1410 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1412 pdb_set_username(sampass, username, PDB_SET);
1413 pdb_set_domain(sampass, domain, PDB_SET);
1414 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1415 pdb_set_fullname(sampass, fullname, PDB_SET);
1417 if (homedir) {
1418 fstrcpy( tmp_string, homedir );
1419 if (expand_explicit) {
1420 standard_sub_basic( username, domain, tmp_string,
1421 sizeof(tmp_string) );
1423 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1425 else {
1426 pdb_set_homedir(sampass,
1427 talloc_sub_basic(sampass, username, domain,
1428 lp_logon_home()),
1429 PDB_DEFAULT);
1432 if (dir_drive)
1433 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1434 else
1435 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1437 if (logon_script) {
1438 fstrcpy( tmp_string, logon_script );
1439 if (expand_explicit) {
1440 standard_sub_basic( username, domain, tmp_string,
1441 sizeof(tmp_string) );
1443 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1445 else {
1446 pdb_set_logon_script(sampass,
1447 talloc_sub_basic(sampass, username, domain,
1448 lp_logon_script()),
1449 PDB_DEFAULT);
1452 if (profile_path) {
1453 fstrcpy( tmp_string, profile_path );
1454 if (expand_explicit) {
1455 standard_sub_basic( username, domain, tmp_string,
1456 sizeof(tmp_string) );
1458 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1460 else {
1461 pdb_set_profile_path(sampass,
1462 talloc_sub_basic(sampass, username, domain,
1463 lp_logon_path()),
1464 PDB_DEFAULT);
1467 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1468 pdb_set_workstations(sampass, workstations, PDB_SET);
1469 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1471 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1472 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1473 ret = False;
1474 goto done;
1478 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1479 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1480 ret = False;
1481 goto done;
1485 /* Change from V1 is addition of password history field. */
1486 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1487 if (pwHistLen) {
1488 uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
1489 if (!pw_hist) {
1490 ret = False;
1491 goto done;
1493 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1494 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1495 int i;
1496 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1497 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1498 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1499 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1500 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1501 PW_HISTORY_ENTRY_LEN);
1504 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1505 SAFE_FREE(pw_hist);
1506 ret = False;
1507 goto done;
1509 SAFE_FREE(pw_hist);
1510 } else {
1511 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1514 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1515 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1516 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1517 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1518 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1519 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1520 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1521 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1522 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1524 done:
1526 SAFE_FREE(username);
1527 SAFE_FREE(domain);
1528 SAFE_FREE(nt_username);
1529 SAFE_FREE(fullname);
1530 SAFE_FREE(homedir);
1531 SAFE_FREE(dir_drive);
1532 SAFE_FREE(logon_script);
1533 SAFE_FREE(profile_path);
1534 SAFE_FREE(acct_desc);
1535 SAFE_FREE(workstations);
1536 SAFE_FREE(munged_dial);
1537 SAFE_FREE(unknown_str);
1538 SAFE_FREE(lm_pw_ptr);
1539 SAFE_FREE(nt_pw_ptr);
1540 SAFE_FREE(nt_pw_hist_ptr);
1541 SAFE_FREE(hours);
1543 return ret;
1546 /*********************************************************************
1547 *********************************************************************/
1549 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1552 /* times are stored as 32bit integer
1553 take care on system with 64bit wide time_t
1554 --SSS */
1555 uint32_t logon_time,
1556 logoff_time,
1557 kickoff_time,
1558 bad_password_time,
1559 pass_last_set_time,
1560 pass_can_change_time,
1561 pass_must_change_time;
1562 char *username = NULL;
1563 char *domain = NULL;
1564 char *nt_username = NULL;
1565 char *dir_drive = NULL;
1566 char *comment = NULL;
1567 char *munged_dial = NULL;
1568 char *fullname = NULL;
1569 char *homedir = NULL;
1570 char *logon_script = NULL;
1571 char *profile_path = NULL;
1572 char *acct_desc = NULL;
1573 char *workstations = NULL;
1574 uint32_t username_len, domain_len, nt_username_len,
1575 dir_drive_len, comment_len, munged_dial_len,
1576 fullname_len, homedir_len, logon_script_len,
1577 profile_path_len, acct_desc_len, workstations_len;
1579 uint32_t user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1580 uint16_t logon_divs;
1581 uint16_t bad_password_count, logon_count;
1582 uint8_t *hours = NULL;
1583 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1584 uint32_t len = 0;
1585 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1586 uint32_t pwHistLen = 0;
1587 bool ret = True;
1588 fstring tmp_string;
1589 bool expand_explicit = lp_passdb_expand_explicit();
1591 if(sampass == NULL || buf == NULL) {
1592 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1593 return False;
1596 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1598 /* unpack the buffer into variables */
1599 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1600 &logon_time, /* d */
1601 &logoff_time, /* d */
1602 &kickoff_time, /* d */
1603 &bad_password_time, /* d */
1604 &pass_last_set_time, /* d */
1605 &pass_can_change_time, /* d */
1606 &pass_must_change_time, /* d */
1607 &username_len, &username, /* B */
1608 &domain_len, &domain, /* B */
1609 &nt_username_len, &nt_username, /* B */
1610 &fullname_len, &fullname, /* B */
1611 &homedir_len, &homedir, /* B */
1612 &dir_drive_len, &dir_drive, /* B */
1613 &logon_script_len, &logon_script, /* B */
1614 &profile_path_len, &profile_path, /* B */
1615 &acct_desc_len, &acct_desc, /* B */
1616 &workstations_len, &workstations, /* B */
1617 &comment_len, &comment, /* B */
1618 &munged_dial_len, &munged_dial, /* B */
1619 &user_rid, /* d */
1620 &group_rid, /* d */
1621 &lm_pw_len, &lm_pw_ptr, /* B */
1622 &nt_pw_len, &nt_pw_ptr, /* B */
1623 /* Change from V1 is addition of password history field. */
1624 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1625 /* Change from V2 is the uint32_t acb_mask */
1626 &acct_ctrl, /* d */
1627 /* Also "remove_me" field was removed. */
1628 &logon_divs, /* w */
1629 &hours_len, /* d */
1630 &hourslen, &hours, /* B */
1631 &bad_password_count, /* w */
1632 &logon_count, /* w */
1633 &unknown_6); /* d */
1635 if (len == (uint32_t) -1) {
1636 ret = False;
1637 goto done;
1640 pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
1641 pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
1642 pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
1643 pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
1644 pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
1645 pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
1647 pdb_set_username(sampass, username, PDB_SET);
1648 pdb_set_domain(sampass, domain, PDB_SET);
1649 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1650 pdb_set_fullname(sampass, fullname, PDB_SET);
1652 if (homedir) {
1653 fstrcpy( tmp_string, homedir );
1654 if (expand_explicit) {
1655 standard_sub_basic( username, domain, tmp_string,
1656 sizeof(tmp_string) );
1658 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1660 else {
1661 pdb_set_homedir(sampass,
1662 talloc_sub_basic(sampass, username, domain,
1663 lp_logon_home()),
1664 PDB_DEFAULT);
1667 if (dir_drive)
1668 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1669 else
1670 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1672 if (logon_script) {
1673 fstrcpy( tmp_string, logon_script );
1674 if (expand_explicit) {
1675 standard_sub_basic( username, domain, tmp_string,
1676 sizeof(tmp_string) );
1678 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1680 else {
1681 pdb_set_logon_script(sampass,
1682 talloc_sub_basic(sampass, username, domain,
1683 lp_logon_script()),
1684 PDB_DEFAULT);
1687 if (profile_path) {
1688 fstrcpy( tmp_string, profile_path );
1689 if (expand_explicit) {
1690 standard_sub_basic( username, domain, tmp_string,
1691 sizeof(tmp_string) );
1693 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1695 else {
1696 pdb_set_profile_path(sampass,
1697 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1698 PDB_DEFAULT);
1701 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1702 pdb_set_comment(sampass, comment, PDB_SET);
1703 pdb_set_workstations(sampass, workstations, PDB_SET);
1704 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1706 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1707 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1708 ret = False;
1709 goto done;
1713 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1714 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1715 ret = False;
1716 goto done;
1720 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1721 if (pwHistLen) {
1722 uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1723 if (!pw_hist) {
1724 ret = False;
1725 goto done;
1727 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1728 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1729 int i;
1730 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1731 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1732 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1733 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1734 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1735 PW_HISTORY_ENTRY_LEN);
1738 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1739 SAFE_FREE(pw_hist);
1740 ret = False;
1741 goto done;
1743 SAFE_FREE(pw_hist);
1744 } else {
1745 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1748 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1749 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1750 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1751 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1752 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1753 /* Change from V2 is the uint32_t acct_ctrl */
1754 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1755 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1756 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1758 done:
1760 SAFE_FREE(username);
1761 SAFE_FREE(domain);
1762 SAFE_FREE(nt_username);
1763 SAFE_FREE(fullname);
1764 SAFE_FREE(homedir);
1765 SAFE_FREE(dir_drive);
1766 SAFE_FREE(logon_script);
1767 SAFE_FREE(profile_path);
1768 SAFE_FREE(acct_desc);
1769 SAFE_FREE(workstations);
1770 SAFE_FREE(munged_dial);
1771 SAFE_FREE(comment);
1772 SAFE_FREE(lm_pw_ptr);
1773 SAFE_FREE(nt_pw_ptr);
1774 SAFE_FREE(nt_pw_hist_ptr);
1775 SAFE_FREE(hours);
1777 return ret;
1780 /*********************************************************************
1781 *********************************************************************/
1783 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
1785 size_t len, buflen;
1787 /* times are stored as 32bit integer
1788 take care on system with 64bit wide time_t
1789 --SSS */
1790 uint32_t logon_time,
1791 logoff_time,
1792 kickoff_time,
1793 bad_password_time,
1794 pass_last_set_time,
1795 pass_can_change_time,
1796 pass_must_change_time;
1798 uint32_t user_rid, group_rid;
1800 const char *username;
1801 const char *domain;
1802 const char *nt_username;
1803 const char *dir_drive;
1804 const char *comment;
1805 const char *munged_dial;
1806 const char *fullname;
1807 const char *homedir;
1808 const char *logon_script;
1809 const char *profile_path;
1810 const char *acct_desc;
1811 const char *workstations;
1812 uint32_t username_len, domain_len, nt_username_len,
1813 dir_drive_len, comment_len, munged_dial_len,
1814 fullname_len, homedir_len, logon_script_len,
1815 profile_path_len, acct_desc_len, workstations_len;
1817 const uint8_t *lm_pw;
1818 const uint8_t *nt_pw;
1819 const uint8_t *nt_pw_hist;
1820 uint32_t lm_pw_len = 16;
1821 uint32_t nt_pw_len = 16;
1822 uint32_t nt_pw_hist_len;
1823 uint32_t pwHistLen = 0;
1825 *buf = NULL;
1826 buflen = 0;
1828 logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
1829 logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
1830 kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
1831 bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
1832 pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
1833 pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
1834 pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
1836 user_rid = pdb_get_user_rid(sampass);
1837 group_rid = pdb_get_group_rid(sampass);
1839 username = pdb_get_username(sampass);
1840 if (username) {
1841 username_len = strlen(username) +1;
1842 } else {
1843 username_len = 0;
1846 domain = pdb_get_domain(sampass);
1847 if (domain) {
1848 domain_len = strlen(domain) +1;
1849 } else {
1850 domain_len = 0;
1853 nt_username = pdb_get_nt_username(sampass);
1854 if (nt_username) {
1855 nt_username_len = strlen(nt_username) +1;
1856 } else {
1857 nt_username_len = 0;
1860 fullname = pdb_get_fullname(sampass);
1861 if (fullname) {
1862 fullname_len = strlen(fullname) +1;
1863 } else {
1864 fullname_len = 0;
1868 * Only updates fields which have been set (not defaults from smb.conf)
1871 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1872 dir_drive = pdb_get_dir_drive(sampass);
1873 } else {
1874 dir_drive = NULL;
1876 if (dir_drive) {
1877 dir_drive_len = strlen(dir_drive) +1;
1878 } else {
1879 dir_drive_len = 0;
1882 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1883 homedir = pdb_get_homedir(sampass);
1884 } else {
1885 homedir = NULL;
1887 if (homedir) {
1888 homedir_len = strlen(homedir) +1;
1889 } else {
1890 homedir_len = 0;
1893 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1894 logon_script = pdb_get_logon_script(sampass);
1895 } else {
1896 logon_script = NULL;
1898 if (logon_script) {
1899 logon_script_len = strlen(logon_script) +1;
1900 } else {
1901 logon_script_len = 0;
1904 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1905 profile_path = pdb_get_profile_path(sampass);
1906 } else {
1907 profile_path = NULL;
1909 if (profile_path) {
1910 profile_path_len = strlen(profile_path) +1;
1911 } else {
1912 profile_path_len = 0;
1915 lm_pw = pdb_get_lanman_passwd(sampass);
1916 if (!lm_pw) {
1917 lm_pw_len = 0;
1920 nt_pw = pdb_get_nt_passwd(sampass);
1921 if (!nt_pw) {
1922 nt_pw_len = 0;
1925 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1926 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1927 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1928 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1929 } else {
1930 nt_pw_hist_len = 0;
1933 acct_desc = pdb_get_acct_desc(sampass);
1934 if (acct_desc) {
1935 acct_desc_len = strlen(acct_desc) +1;
1936 } else {
1937 acct_desc_len = 0;
1940 workstations = pdb_get_workstations(sampass);
1941 if (workstations) {
1942 workstations_len = strlen(workstations) +1;
1943 } else {
1944 workstations_len = 0;
1947 comment = pdb_get_comment(sampass);
1948 if (comment) {
1949 comment_len = strlen(comment) +1;
1950 } else {
1951 comment_len = 0;
1954 munged_dial = pdb_get_munged_dial(sampass);
1955 if (munged_dial) {
1956 munged_dial_len = strlen(munged_dial) +1;
1957 } else {
1958 munged_dial_len = 0;
1961 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1963 /* one time to get the size needed */
1964 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3,
1965 logon_time, /* d */
1966 logoff_time, /* d */
1967 kickoff_time, /* d */
1968 bad_password_time, /* d */
1969 pass_last_set_time, /* d */
1970 pass_can_change_time, /* d */
1971 pass_must_change_time, /* d */
1972 username_len, username, /* B */
1973 domain_len, domain, /* B */
1974 nt_username_len, nt_username, /* B */
1975 fullname_len, fullname, /* B */
1976 homedir_len, homedir, /* B */
1977 dir_drive_len, dir_drive, /* B */
1978 logon_script_len, logon_script, /* B */
1979 profile_path_len, profile_path, /* B */
1980 acct_desc_len, acct_desc, /* B */
1981 workstations_len, workstations, /* B */
1982 comment_len, comment, /* B */
1983 munged_dial_len, munged_dial, /* B */
1984 user_rid, /* d */
1985 group_rid, /* d */
1986 lm_pw_len, lm_pw, /* B */
1987 nt_pw_len, nt_pw, /* B */
1988 nt_pw_hist_len, nt_pw_hist, /* B */
1989 pdb_get_acct_ctrl(sampass), /* d */
1990 pdb_get_logon_divs(sampass), /* w */
1991 pdb_get_hours_len(sampass), /* d */
1992 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1993 pdb_get_bad_password_count(sampass), /* w */
1994 pdb_get_logon_count(sampass), /* w */
1995 pdb_get_unknown_6(sampass)); /* d */
1997 if (size_only) {
1998 return buflen;
2001 /* malloc the space needed */
2002 if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
2003 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
2004 return (-1);
2007 /* now for the real call to tdb_pack() */
2008 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
2009 logon_time, /* d */
2010 logoff_time, /* d */
2011 kickoff_time, /* d */
2012 bad_password_time, /* d */
2013 pass_last_set_time, /* d */
2014 pass_can_change_time, /* d */
2015 pass_must_change_time, /* d */
2016 username_len, username, /* B */
2017 domain_len, domain, /* B */
2018 nt_username_len, nt_username, /* B */
2019 fullname_len, fullname, /* B */
2020 homedir_len, homedir, /* B */
2021 dir_drive_len, dir_drive, /* B */
2022 logon_script_len, logon_script, /* B */
2023 profile_path_len, profile_path, /* B */
2024 acct_desc_len, acct_desc, /* B */
2025 workstations_len, workstations, /* B */
2026 comment_len, comment, /* B */
2027 munged_dial_len, munged_dial, /* B */
2028 user_rid, /* d */
2029 group_rid, /* d */
2030 lm_pw_len, lm_pw, /* B */
2031 nt_pw_len, nt_pw, /* B */
2032 nt_pw_hist_len, nt_pw_hist, /* B */
2033 pdb_get_acct_ctrl(sampass), /* d */
2034 pdb_get_logon_divs(sampass), /* w */
2035 pdb_get_hours_len(sampass), /* d */
2036 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2037 pdb_get_bad_password_count(sampass), /* w */
2038 pdb_get_logon_count(sampass), /* w */
2039 pdb_get_unknown_6(sampass)); /* d */
2041 /* check to make sure we got it correct */
2042 if (buflen != len) {
2043 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2044 (unsigned long)buflen, (unsigned long)len));
2045 /* error */
2046 SAFE_FREE (*buf);
2047 return (-1);
2050 return (buflen);
2053 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
2055 /* nothing changed between V3 and V4 */
2056 return init_samu_from_buffer_v3(sampass, buf, buflen);
2059 static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
2061 /* nothing changed between V3 and V4 */
2062 return init_buffer_from_samu_v3(buf, sampass, size_only);
2065 /**********************************************************************
2066 Intialize a struct samu struct from a BYTE buffer of size len
2067 *********************************************************************/
2069 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2070 uint8_t *buf, uint32_t buflen)
2072 switch (level) {
2073 case SAMU_BUFFER_V0:
2074 return init_samu_from_buffer_v0(sampass, buf, buflen);
2075 case SAMU_BUFFER_V1:
2076 return init_samu_from_buffer_v1(sampass, buf, buflen);
2077 case SAMU_BUFFER_V2:
2078 return init_samu_from_buffer_v2(sampass, buf, buflen);
2079 case SAMU_BUFFER_V3:
2080 return init_samu_from_buffer_v3(sampass, buf, buflen);
2081 case SAMU_BUFFER_V4:
2082 return init_samu_from_buffer_v4(sampass, buf, buflen);
2085 return false;
2088 /**********************************************************************
2089 Intialize a BYTE buffer from a struct samu struct
2090 *********************************************************************/
2092 uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
2094 return init_buffer_from_samu_v4(buf, sampass, size_only);
2097 /*********************************************************************
2098 *********************************************************************/
2100 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2102 uint8_t *buf = NULL;
2103 int len;
2105 len = init_buffer_from_samu(&buf, src, False);
2106 if (len == -1 || !buf) {
2107 SAFE_FREE(buf);
2108 return False;
2111 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2112 free(buf);
2113 return False;
2116 dst->methods = src->methods;
2118 if ( src->unix_pw ) {
2119 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2120 if (!dst->unix_pw) {
2121 free(buf);
2122 return False;
2126 if (src->group_sid) {
2127 pdb_set_group_sid(dst, src->group_sid, PDB_SET);
2130 free(buf);
2131 return True;
2134 /*********************************************************************
2135 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2136 *********************************************************************/
2138 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2140 time_t LastBadPassword;
2141 uint16_t BadPasswordCount;
2142 uint32_t resettime;
2143 bool res;
2145 BadPasswordCount = pdb_get_bad_password_count(sampass);
2146 if (!BadPasswordCount) {
2147 DEBUG(9, ("No bad password attempts.\n"));
2148 return True;
2151 become_root();
2152 res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2153 unbecome_root();
2155 if (!res) {
2156 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2157 return False;
2160 /* First, check if there is a reset time to compare */
2161 if ((resettime == (uint32_t) -1) || (resettime == 0)) {
2162 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2163 return True;
2166 LastBadPassword = pdb_get_bad_password_time(sampass);
2167 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2168 (uint32_t) LastBadPassword, resettime, (uint32_t)time(NULL)));
2169 if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
2170 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2171 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2172 if (updated) {
2173 *updated = True;
2177 return True;
2180 /*********************************************************************
2181 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2182 *********************************************************************/
2184 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2186 uint32_t duration;
2187 time_t LastBadPassword;
2188 bool res;
2190 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2191 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2192 pdb_get_username(sampass)));
2193 return True;
2196 become_root();
2197 res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2198 unbecome_root();
2200 if (!res) {
2201 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2202 return False;
2205 /* First, check if there is a duration to compare */
2206 if ((duration == (uint32_t) -1) || (duration == 0)) {
2207 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2208 return True;
2211 LastBadPassword = pdb_get_bad_password_time(sampass);
2212 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2213 pdb_get_username(sampass), (uint32_t)LastBadPassword, duration*60, (uint32_t)time(NULL)));
2215 if (LastBadPassword == (time_t)0) {
2216 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2217 "administratively locked out with no bad password "
2218 "time. Leaving locked out.\n",
2219 pdb_get_username(sampass) ));
2220 return True;
2223 if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
2224 pdb_set_acct_ctrl(sampass,
2225 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2226 PDB_CHANGED);
2227 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2228 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2229 if (updated) {
2230 *updated = True;
2234 return True;
2237 /*********************************************************************
2238 Increment the bad_password_count
2239 *********************************************************************/
2241 bool pdb_increment_bad_password_count(struct samu *sampass)
2243 uint32_t account_policy_lockout;
2244 bool autolock_updated = False, badpw_updated = False;
2245 bool ret;
2247 /* Retrieve the account lockout policy */
2248 become_root();
2249 ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2250 unbecome_root();
2251 if ( !ret ) {
2252 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2253 return False;
2256 /* If there is no policy, we don't need to continue checking */
2257 if (!account_policy_lockout) {
2258 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2259 return True;
2262 /* Check if the autolock needs to be cleared */
2263 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2264 return False;
2266 /* Check if the badpw count needs to be reset */
2267 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2268 return False;
2271 Ok, now we can assume that any resetting that needs to be
2272 done has been done, and just get on with incrementing
2273 and autolocking if necessary
2276 pdb_set_bad_password_count(sampass,
2277 pdb_get_bad_password_count(sampass)+1,
2278 PDB_CHANGED);
2279 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2282 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2283 return True;
2285 if (!pdb_set_acct_ctrl(sampass,
2286 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2287 PDB_CHANGED)) {
2288 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2289 return False;
2292 return True;
2295 bool is_dc_trusted_domain_situation(const char *domain_name)
2297 return IS_DC && !strequal(domain_name, lp_workgroup());
2300 /*******************************************************************
2301 Wrapper around retrieving the clear text trust account password.
2302 appropriate account name is stored in account_name.
2303 Caller must free password, but not account_name.
2304 *******************************************************************/
2306 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2307 const char **account_name,
2308 enum netr_SchannelType *channel)
2310 char *pwd;
2311 time_t last_set_time;
2313 /* if we are a DC and this is not our domain, then lookup an account
2314 * for the domain trust */
2316 if (is_dc_trusted_domain_situation(domain)) {
2317 if (!lp_allow_trusted_domains()) {
2318 return false;
2321 if (!pdb_get_trusteddom_pw(domain, ret_pwd, NULL,
2322 &last_set_time))
2324 DEBUG(0, ("get_trust_pw: could not fetch trust "
2325 "account password for trusted domain %s\n",
2326 domain));
2327 return false;
2330 if (channel != NULL) {
2331 *channel = SEC_CHAN_DOMAIN;
2334 if (account_name != NULL) {
2335 *account_name = lp_workgroup();
2338 return true;
2342 * Since we can only be member of one single domain, we are now
2343 * in a member situation:
2345 * - Either we are a DC (selfjoined) and the domain is our
2346 * own domain.
2347 * - Or we are on a member and the domain is our own or some
2348 * other (potentially trusted) domain.
2350 * In both cases, we can only get the machine account password
2351 * for our own domain to connect to our own dc. (For a member,
2352 * request to trusted domains are performed through our dc.)
2354 * So we simply use our own domain name to retrieve the
2355 * machine account passowrd and ignore the request domain here.
2358 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2360 if (pwd != NULL) {
2361 *ret_pwd = pwd;
2362 if (account_name != NULL) {
2363 *account_name = lp_netbios_name();
2366 return true;
2369 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2370 "account password for domain %s\n", domain));
2371 return false;
2374 /*******************************************************************
2375 Wrapper around retrieving the trust account password.
2376 appropriate account name is stored in account_name.
2377 *******************************************************************/
2379 bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
2380 const char **account_name,
2381 enum netr_SchannelType *channel)
2383 char *pwd = NULL;
2384 time_t last_set_time;
2386 if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
2387 E_md4hash(pwd, ret_pwd);
2388 SAFE_FREE(pwd);
2389 return true;
2390 } else if (is_dc_trusted_domain_situation(domain)) {
2391 return false;
2394 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2396 if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
2397 &last_set_time,
2398 channel))
2400 if (account_name != NULL) {
2401 *account_name = lp_netbios_name();
2404 return true;
2407 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2408 "password for domain %s\n", domain));
2409 return False;