passdb: add linefeed to debug message
[Samba.git] / source3 / passdb / passdb.c
blob5873c54974772028f8daaa3616e2c3fb72a7cd8f
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 Get the default domain/netbios name to be used when
41 testing authentication.
43 LEGACY: this function provides the legacy domain mapping used with
44 the lp_map_untrusted_to_domain() parameter
45 ******************************************************************/
47 const char *my_sam_name(void)
49 /* Standalone servers can only use the local netbios name */
50 if ( lp_server_role() == ROLE_STANDALONE )
51 return lp_netbios_name();
53 /* Default to the DOMAIN name when not specified */
54 return lp_workgroup();
57 /**********************************************************************
58 ***********************************************************************/
60 static int samu_destroy(struct samu *user)
62 data_blob_clear_free( &user->lm_pw );
63 data_blob_clear_free( &user->nt_pw );
65 if ( user->plaintext_pw )
66 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
68 return 0;
71 /**********************************************************************
72 generate a new struct samuser
73 ***********************************************************************/
75 struct samu *samu_new( TALLOC_CTX *ctx )
77 struct samu *user;
79 if ( !(user = talloc_zero( ctx, struct samu )) ) {
80 DEBUG(0,("samuser_new: Talloc failed!\n"));
81 return NULL;
84 talloc_set_destructor( user, samu_destroy );
86 /* no initial methods */
88 user->methods = NULL;
90 /* Don't change these timestamp settings without a good reason.
91 They are important for NT member server compatibility. */
93 user->logon_time = (time_t)0;
94 user->pass_last_set_time = (time_t)0;
95 user->pass_can_change_time = (time_t)0;
96 user->logoff_time = get_time_t_max();
97 user->kickoff_time = get_time_t_max();
98 user->fields_present = 0x00ffffff;
99 user->logon_divs = 168; /* hours per week */
100 user->hours_len = 21; /* 21 times 8 bits = 168 */
101 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
102 user->bad_password_count = 0;
103 user->logon_count = 0;
104 user->unknown_6 = 0x000004ec; /* don't know */
106 /* Some parts of samba strlen their pdb_get...() returns,
107 so this keeps the interface unchanged for now. */
109 user->username = "";
110 user->domain = "";
111 user->nt_username = "";
112 user->full_name = "";
113 user->home_dir = "";
114 user->logon_script = "";
115 user->profile_path = "";
116 user->acct_desc = "";
117 user->workstations = "";
118 user->comment = "";
119 user->munged_dial = "";
121 user->plaintext_pw = NULL;
123 /* Unless we know otherwise have a Account Control Bit
124 value of 'normal user'. This helps User Manager, which
125 asks for a filtered list of users. */
127 user->acct_ctrl = ACB_NORMAL;
129 return user;
132 static int count_commas(const char *str)
134 int num_commas = 0;
135 const char *comma = str;
137 while ((comma = strchr(comma, ',')) != NULL) {
138 comma += 1;
139 num_commas += 1;
141 return num_commas;
144 /*********************************************************************
145 Initialize a struct samu from a struct passwd including the user
146 and group SIDs. The *user structure is filled out with the Unix
147 attributes and a user SID.
148 *********************************************************************/
150 static NTSTATUS samu_set_unix_internal(struct pdb_methods *methods,
151 struct samu *user, const struct passwd *pwd, bool create)
153 const char *guest_account = lp_guest_account();
154 const char *domain = lp_netbios_name();
155 char *fullname;
156 uint32_t urid;
158 if ( !pwd ) {
159 return NT_STATUS_NO_SUCH_USER;
162 /* Basic properties based upon the Unix account information */
164 pdb_set_username(user, pwd->pw_name, PDB_SET);
166 fullname = NULL;
168 if (count_commas(pwd->pw_gecos) == 3) {
170 * Heuristic: This seems to be a gecos field that has been
171 * edited by chfn(1). Only use the part before the first
172 * comma. Fixes bug 5198.
174 fullname = talloc_strndup(
175 talloc_tos(), pwd->pw_gecos,
176 strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
179 if (fullname != NULL) {
180 pdb_set_fullname(user, fullname, PDB_SET);
181 } else {
182 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
184 TALLOC_FREE(fullname);
186 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
187 #if 0
188 /* This can lead to a primary group of S-1-22-2-XX which
189 will be rejected by other parts of the Samba code.
190 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
191 --jerry */
193 gid_to_sid(&group_sid, pwd->pw_gid);
194 pdb_set_group_sid(user, &group_sid, PDB_SET);
195 #endif
197 /* save the password structure for later use */
199 user->unix_pw = tcopy_passwd( user, pwd );
201 /* Special case for the guest account which must have a RID of 501 */
203 if ( strequal( pwd->pw_name, guest_account ) ) {
204 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
205 return NT_STATUS_NO_SUCH_USER;
207 return NT_STATUS_OK;
210 /* Non-guest accounts...Check for a workstation or user account */
212 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
213 /* workstation */
215 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
216 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
217 pwd->pw_name));
218 return NT_STATUS_INVALID_COMPUTER_NAME;
221 else {
222 /* user */
224 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
225 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
226 pwd->pw_name));
227 return NT_STATUS_INVALID_ACCOUNT_NAME;
230 /* set some basic attributes */
232 pdb_set_profile_path(user, talloc_sub_specified(user,
233 lp_logon_path(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
234 PDB_DEFAULT);
235 pdb_set_homedir(user, talloc_sub_specified(user,
236 lp_logon_home(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
237 PDB_DEFAULT);
238 pdb_set_dir_drive(user, talloc_sub_specified(user,
239 lp_logon_drive(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
240 PDB_DEFAULT);
241 pdb_set_logon_script(user, talloc_sub_specified(user,
242 lp_logon_script(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
243 PDB_DEFAULT);
246 /* Now deal with the user SID. If we have a backend that can generate
247 RIDs, then do so. But sometimes the caller just wanted a structure
248 initialized and will fill in these fields later (such as from a
249 netr_SamInfo3 structure) */
251 if ( create && (methods->capabilities(methods) & PDB_CAP_STORE_RIDS)) {
252 uint32_t user_rid;
253 struct dom_sid user_sid;
255 if ( !methods->new_rid(methods, &user_rid) ) {
256 DEBUG(3, ("Could not allocate a new RID\n"));
257 return NT_STATUS_ACCESS_DENIED;
260 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
262 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
263 DEBUG(3, ("pdb_set_user_sid failed\n"));
264 return NT_STATUS_INTERNAL_ERROR;
267 return NT_STATUS_OK;
270 /* generate a SID for the user with the RID algorithm */
272 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
274 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
275 return NT_STATUS_INTERNAL_ERROR;
278 return NT_STATUS_OK;
281 /********************************************************************
282 Set the Unix user attributes
283 ********************************************************************/
285 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
287 return samu_set_unix_internal( NULL, user, pwd, False );
290 NTSTATUS samu_alloc_rid_unix(struct pdb_methods *methods,
291 struct samu *user, const struct passwd *pwd)
293 return samu_set_unix_internal( methods, user, pwd, True );
296 /**********************************************************
297 Encode the account control bits into a string.
298 length = length of string to encode into (including terminating
299 null). length *MUST BE MORE THAN 2* !
300 **********************************************************/
302 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
304 fstring acct_str;
305 char *result;
307 size_t i = 0;
309 SMB_ASSERT(length <= sizeof(acct_str));
311 acct_str[i++] = '[';
313 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
314 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
315 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
316 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
317 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
318 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
319 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
320 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
321 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
322 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
323 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
325 for ( ; i < length - 2 ; i++ )
326 acct_str[i] = ' ';
328 i = length - 2;
329 acct_str[i++] = ']';
330 acct_str[i++] = '\0';
332 result = talloc_strdup(talloc_tos(), acct_str);
333 SMB_ASSERT(result != NULL);
334 return result;
337 /**********************************************************
338 Decode the account control bits from a string.
339 **********************************************************/
341 uint32_t pdb_decode_acct_ctrl(const char *p)
343 uint32_t acct_ctrl = 0;
344 bool finished = false;
347 * Check if the account type bits have been encoded after the
348 * NT password (in the form [NDHTUWSLXI]).
351 if (*p != '[')
352 return 0;
354 for (p++; *p && !finished; p++) {
355 switch (*p) {
356 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
357 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
358 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
359 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
360 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
361 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
362 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
363 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
364 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
365 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
366 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
367 case ' ': { break; }
368 case ':':
369 case '\n':
370 case '\0':
371 case ']':
372 default: { finished = true; }
376 return acct_ctrl;
379 /*************************************************************
380 Routine to set 32 hex password characters from a 16 byte array.
381 **************************************************************/
383 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
385 if (pwd != NULL) {
386 hex_encode_buf(p, pwd, 16);
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 hex_encode_buf(p, hours, 21);
436 } else {
437 strlcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
441 /*************************************************************
442 Routine to get the 42 hex characters and turn them
443 into a 21 byte array.
444 **************************************************************/
446 bool pdb_gethexhours(const char *p, unsigned char *hours)
448 int i;
449 unsigned char lonybble, hinybble;
450 const char *hexchars = "0123456789ABCDEF";
451 char *p1, *p2;
453 if (!p) {
454 return (False);
457 for (i = 0; i < 42; i += 2) {
458 hinybble = toupper_m(p[i]);
459 lonybble = toupper_m(p[i + 1]);
461 p1 = strchr(hexchars, hinybble);
462 p2 = strchr(hexchars, lonybble);
464 if (!p1 || !p2) {
465 return (False);
468 hinybble = PTR_DIFF(p1, hexchars);
469 lonybble = PTR_DIFF(p2, hexchars);
471 hours[i / 2] = (hinybble << 4) | lonybble;
473 return (True);
476 /********************************************************************
477 ********************************************************************/
479 int algorithmic_rid_base(void)
481 int rid_offset;
483 rid_offset = lp_algorithmic_rid_base();
485 if (rid_offset < BASE_RID) {
486 /* Try to prevent admin foot-shooting, we can't put algorithmic
487 rids below 1000, that's the 'well known RIDs' on NT */
488 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
489 rid_offset = BASE_RID;
491 if (rid_offset & 1) {
492 DEBUG(0, ("algorithmic rid base must be even\n"));
493 rid_offset += 1;
495 return rid_offset;
498 /*******************************************************************
499 Converts NT user RID to a UNIX uid.
500 ********************************************************************/
502 uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
504 int rid_offset = algorithmic_rid_base();
505 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
508 uid_t max_algorithmic_uid(void)
510 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
513 /*******************************************************************
514 converts UNIX uid to an NT User RID.
515 ********************************************************************/
517 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
519 int rid_offset = algorithmic_rid_base();
520 return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
523 /*******************************************************************
524 Converts NT group RID to a UNIX gid.
525 ********************************************************************/
527 gid_t pdb_group_rid_to_gid(uint32_t group_rid)
529 int rid_offset = algorithmic_rid_base();
530 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
533 gid_t max_algorithmic_gid(void)
535 return pdb_group_rid_to_gid(0xffffffff);
538 /*******************************************************************
539 converts NT Group RID to a UNIX uid.
541 warning: you must not call that function only
542 you must do a call to the group mapping first.
543 there is not anymore a direct link between the gid and the rid.
544 ********************************************************************/
546 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
548 int rid_offset = algorithmic_rid_base();
549 return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
552 /*******************************************************************
553 Decides if a RID is a well known RID.
554 ********************************************************************/
556 static bool rid_is_well_known(uint32_t rid)
558 /* Not using rid_offset here, because this is the actual
559 NT fixed value (1000) */
561 return (rid < BASE_RID);
564 /*******************************************************************
565 Decides if a RID is a user or group RID.
566 ********************************************************************/
568 bool algorithmic_pdb_rid_is_user(uint32_t rid)
570 if ( rid_is_well_known(rid) ) {
572 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
573 * and DOMAIN_RID_GUEST.
575 if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
576 return True;
577 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
578 return True;
580 return False;
583 /*******************************************************************
584 Convert a name into a SID. Used in the lookup name rpc.
585 ********************************************************************/
587 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
588 enum lsa_SidType *type)
590 GROUP_MAP *map;
591 bool ret;
593 /* Windows treats "MACHINE\None" as a special name for
594 rid 513 on non-DCs. You cannot create a user or group
595 name "None" on Windows. You will get an error that
596 the group already exists. */
598 if ( strequal( name, "None" ) ) {
599 *rid = DOMAIN_RID_USERS;
600 *type = SID_NAME_DOM_GRP;
602 return True;
605 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
606 * correctly in the case where foo also exists as a user. If the flag
607 * is set, don't look for users at all. */
609 if ((flags & LOOKUP_NAME_GROUP) == 0) {
610 struct samu *sam_account = NULL;
611 struct dom_sid user_sid;
613 if ( !(sam_account = samu_new( NULL )) ) {
614 return False;
617 become_root();
618 ret = pdb_getsampwnam(sam_account, name);
619 unbecome_root();
621 if (ret) {
622 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
625 TALLOC_FREE(sam_account);
627 if (ret) {
628 if (!sid_check_is_in_our_sam(&user_sid)) {
629 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
630 name, sid_string_dbg(&user_sid)));
631 return False;
634 sid_peek_rid(&user_sid, rid);
635 *type = SID_NAME_USER;
636 return True;
641 * Maybe it is a group ?
644 map = talloc_zero(NULL, GROUP_MAP);
645 if (!map) {
646 return false;
649 become_root();
650 ret = pdb_getgrnam(map, name);
651 unbecome_root();
653 if (!ret) {
654 TALLOC_FREE(map);
655 return False;
658 /* BUILTIN groups are looked up elsewhere */
659 if (!sid_check_is_in_our_sam(&map->sid)) {
660 DEBUG(10, ("Found group %s (%s) not in our domain -- "
661 "ignoring.\n",
662 name, sid_string_dbg(&map->sid)));
663 TALLOC_FREE(map);
664 return False;
667 /* yes it's a mapped group */
668 sid_peek_rid(&map->sid, rid);
669 *type = map->sid_name_use;
670 TALLOC_FREE(map);
671 return True;
674 /*************************************************************
675 Change a password entry in the local passdb backend.
677 Assumptions:
678 - always called as root
679 - ignores the account type except when adding a new account
680 - will create/delete the unix account if the relative
681 add/delete user script is configured
683 *************************************************************/
685 NTSTATUS local_password_change(const char *user_name,
686 int local_flags,
687 const char *new_passwd,
688 char **pp_err_str,
689 char **pp_msg_str)
691 TALLOC_CTX *tosctx;
692 struct samu *sam_pass;
693 uint32_t acb;
694 uint32_t rid;
695 NTSTATUS result;
696 bool user_exists;
697 int ret = -1;
699 *pp_err_str = NULL;
700 *pp_msg_str = NULL;
702 tosctx = talloc_tos();
704 sam_pass = samu_new(tosctx);
705 if (!sam_pass) {
706 result = NT_STATUS_NO_MEMORY;
707 goto done;
710 /* Get the smb passwd entry for this user */
711 user_exists = pdb_getsampwnam(sam_pass, user_name);
713 /* Check delete first, we don't need to do anything else if we
714 * are going to delete the acocunt */
715 if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
717 result = pdb_delete_user(tosctx, sam_pass);
718 if (!NT_STATUS_IS_OK(result)) {
719 ret = asprintf(pp_err_str,
720 "Failed to delete entry for user %s.\n",
721 user_name);
722 if (ret < 0) {
723 *pp_err_str = NULL;
725 result = NT_STATUS_UNSUCCESSFUL;
726 } else {
727 ret = asprintf(pp_msg_str,
728 "Deleted user %s.\n",
729 user_name);
730 if (ret < 0) {
731 *pp_msg_str = NULL;
734 goto done;
737 if (user_exists && (local_flags & LOCAL_ADD_USER)) {
738 /* the entry already existed */
739 local_flags &= ~LOCAL_ADD_USER;
742 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
743 ret = asprintf(pp_err_str,
744 "Failed to find entry for user %s.\n",
745 user_name);
746 if (ret < 0) {
747 *pp_err_str = NULL;
749 result = NT_STATUS_NO_SUCH_USER;
750 goto done;
753 /* First thing add the new user if we are required to do so */
754 if (local_flags & LOCAL_ADD_USER) {
756 if (local_flags & LOCAL_TRUST_ACCOUNT) {
757 acb = ACB_WSTRUST;
758 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
759 acb = ACB_DOMTRUST;
760 } else {
761 acb = ACB_NORMAL;
764 result = pdb_create_user(tosctx, user_name, acb, &rid);
765 if (!NT_STATUS_IS_OK(result)) {
766 ret = asprintf(pp_err_str,
767 "Failed to add entry for user %s.\n",
768 user_name);
769 if (ret < 0) {
770 *pp_err_str = NULL;
772 result = NT_STATUS_UNSUCCESSFUL;
773 goto done;
776 sam_pass = samu_new(tosctx);
777 if (!sam_pass) {
778 result = NT_STATUS_NO_MEMORY;
779 goto done;
782 /* Now get back the smb passwd entry for this new user */
783 user_exists = pdb_getsampwnam(sam_pass, user_name);
784 if (!user_exists) {
785 ret = asprintf(pp_err_str,
786 "Failed to add entry for user %s.\n",
787 user_name);
788 if (ret < 0) {
789 *pp_err_str = NULL;
791 result = NT_STATUS_UNSUCCESSFUL;
792 goto done;
796 acb = pdb_get_acct_ctrl(sam_pass);
799 * We are root - just write the new password
800 * and the valid last change time.
802 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
803 acb |= ACB_PWNOTREQ;
804 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
805 ret = asprintf(pp_err_str,
806 "Failed to set 'no password required' "
807 "flag for user %s.\n", user_name);
808 if (ret < 0) {
809 *pp_err_str = NULL;
811 result = NT_STATUS_UNSUCCESSFUL;
812 goto done;
816 if (local_flags & LOCAL_SET_PASSWORD) {
818 * If we're dealing with setting a completely empty user account
819 * ie. One with a password of 'XXXX', but not set disabled (like
820 * an account created from scratch) then if the old password was
821 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
822 * We remove that as we're giving this user their first password
823 * and the decision hasn't really been made to disable them (ie.
824 * don't create them disabled). JRA.
826 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
827 (acb & ACB_DISABLED)) {
828 acb &= (~ACB_DISABLED);
829 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
830 ret = asprintf(pp_err_str,
831 "Failed to unset 'disabled' "
832 "flag for user %s.\n",
833 user_name);
834 if (ret < 0) {
835 *pp_err_str = NULL;
837 result = NT_STATUS_UNSUCCESSFUL;
838 goto done;
842 acb &= (~ACB_PWNOTREQ);
843 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
844 ret = asprintf(pp_err_str,
845 "Failed to unset 'no password required'"
846 " flag for user %s.\n", user_name);
847 if (ret < 0) {
848 *pp_err_str = NULL;
850 result = NT_STATUS_UNSUCCESSFUL;
851 goto done;
854 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
855 ret = asprintf(pp_err_str,
856 "Failed to set password for "
857 "user %s.\n", user_name);
858 if (ret < 0) {
859 *pp_err_str = NULL;
861 result = NT_STATUS_UNSUCCESSFUL;
862 goto done;
866 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
867 acb |= ACB_DISABLED;
868 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
869 ret = asprintf(pp_err_str,
870 "Failed to set 'disabled' flag for "
871 "user %s.\n", user_name);
872 if (ret < 0) {
873 *pp_err_str = NULL;
875 result = NT_STATUS_UNSUCCESSFUL;
876 goto done;
880 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
881 acb &= (~ACB_DISABLED);
882 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
883 ret = asprintf(pp_err_str,
884 "Failed to unset 'disabled' flag for "
885 "user %s.\n", user_name);
886 if (ret < 0) {
887 *pp_err_str = NULL;
889 result = NT_STATUS_UNSUCCESSFUL;
890 goto done;
894 /* now commit changes if any */
895 result = pdb_update_sam_account(sam_pass);
896 if (!NT_STATUS_IS_OK(result)) {
897 ret = asprintf(pp_err_str,
898 "Failed to modify entry for user %s.\n",
899 user_name);
900 if (ret < 0) {
901 *pp_err_str = NULL;
903 goto done;
906 if (local_flags & LOCAL_ADD_USER) {
907 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
908 } else if (local_flags & LOCAL_DISABLE_USER) {
909 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
910 } else if (local_flags & LOCAL_ENABLE_USER) {
911 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
912 } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
913 ret = asprintf(pp_msg_str,
914 "User %s password set to none.\n", user_name);
917 if (ret < 0) {
918 *pp_msg_str = NULL;
921 result = NT_STATUS_OK;
923 done:
924 TALLOC_FREE(sam_pass);
925 return result;
928 /**********************************************************************
929 Marshall/unmarshall struct samu structs.
930 *********************************************************************/
932 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
933 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
934 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
935 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
936 /* nothing changed between V3 and V4 */
938 /*********************************************************************
939 *********************************************************************/
941 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
944 /* times are stored as 32bit integer
945 take care on system with 64bit wide time_t
946 --SSS */
947 uint32_t logon_time,
948 logoff_time,
949 kickoff_time,
950 pass_last_set_time,
951 pass_can_change_time,
952 pass_must_change_time;
953 char *username = NULL;
954 char *domain = NULL;
955 char *nt_username = NULL;
956 char *dir_drive = NULL;
957 char *unknown_str = NULL;
958 char *munged_dial = NULL;
959 char *fullname = NULL;
960 char *homedir = NULL;
961 char *logon_script = NULL;
962 char *profile_path = NULL;
963 char *acct_desc = NULL;
964 char *workstations = NULL;
965 uint32_t username_len, domain_len, nt_username_len,
966 dir_drive_len, unknown_str_len, munged_dial_len,
967 fullname_len, homedir_len, logon_script_len,
968 profile_path_len, acct_desc_len, workstations_len;
970 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
971 uint16_t acct_ctrl, logon_divs;
972 uint16_t bad_password_count, logon_count;
973 uint8_t *hours = NULL;
974 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
975 uint32_t len = 0;
976 uint32_t lm_pw_len, nt_pw_len, hourslen;
977 bool ret = True;
979 if(sampass == NULL || buf == NULL) {
980 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
981 return False;
984 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
986 /* unpack the buffer into variables */
987 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
988 &logon_time, /* d */
989 &logoff_time, /* d */
990 &kickoff_time, /* d */
991 &pass_last_set_time, /* d */
992 &pass_can_change_time, /* d */
993 &pass_must_change_time, /* d */
994 &username_len, &username, /* B */
995 &domain_len, &domain, /* B */
996 &nt_username_len, &nt_username, /* B */
997 &fullname_len, &fullname, /* B */
998 &homedir_len, &homedir, /* B */
999 &dir_drive_len, &dir_drive, /* B */
1000 &logon_script_len, &logon_script, /* B */
1001 &profile_path_len, &profile_path, /* B */
1002 &acct_desc_len, &acct_desc, /* B */
1003 &workstations_len, &workstations, /* B */
1004 &unknown_str_len, &unknown_str, /* B */
1005 &munged_dial_len, &munged_dial, /* B */
1006 &user_rid, /* d */
1007 &group_rid, /* d */
1008 &lm_pw_len, &lm_pw_ptr, /* B */
1009 &nt_pw_len, &nt_pw_ptr, /* B */
1010 &acct_ctrl, /* w */
1011 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1012 &logon_divs, /* w */
1013 &hours_len, /* d */
1014 &hourslen, &hours, /* B */
1015 &bad_password_count, /* w */
1016 &logon_count, /* w */
1017 &unknown_6); /* d */
1019 if (len == (uint32_t) -1) {
1020 ret = False;
1021 goto done;
1024 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1025 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1026 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1027 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1028 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1030 pdb_set_username(sampass, username, PDB_SET);
1031 pdb_set_domain(sampass, domain, PDB_SET);
1032 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1033 pdb_set_fullname(sampass, fullname, PDB_SET);
1035 if (homedir) {
1036 pdb_set_homedir(sampass, homedir, PDB_SET);
1038 else {
1039 pdb_set_homedir(sampass,
1040 talloc_sub_basic(sampass, username, domain,
1041 lp_logon_home()),
1042 PDB_DEFAULT);
1045 if (dir_drive)
1046 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1047 else {
1048 pdb_set_dir_drive(sampass,
1049 talloc_sub_basic(sampass, username, domain,
1050 lp_logon_drive()),
1051 PDB_DEFAULT);
1054 if (logon_script)
1055 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1056 else {
1057 pdb_set_logon_script(sampass,
1058 talloc_sub_basic(sampass, username, domain,
1059 lp_logon_script()),
1060 PDB_DEFAULT);
1063 if (profile_path) {
1064 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1065 } else {
1066 pdb_set_profile_path(sampass,
1067 talloc_sub_basic(sampass, username, domain,
1068 lp_logon_path()),
1069 PDB_DEFAULT);
1072 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1073 pdb_set_workstations(sampass, workstations, PDB_SET);
1074 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1076 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1077 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1078 ret = False;
1079 goto done;
1083 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1084 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1085 ret = False;
1086 goto done;
1090 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1091 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1092 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1093 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1094 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1095 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1096 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1097 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1098 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1099 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1101 done:
1103 SAFE_FREE(username);
1104 SAFE_FREE(domain);
1105 SAFE_FREE(nt_username);
1106 SAFE_FREE(fullname);
1107 SAFE_FREE(homedir);
1108 SAFE_FREE(dir_drive);
1109 SAFE_FREE(logon_script);
1110 SAFE_FREE(profile_path);
1111 SAFE_FREE(acct_desc);
1112 SAFE_FREE(workstations);
1113 SAFE_FREE(munged_dial);
1114 SAFE_FREE(unknown_str);
1115 SAFE_FREE(lm_pw_ptr);
1116 SAFE_FREE(nt_pw_ptr);
1117 SAFE_FREE(hours);
1119 return ret;
1122 /*********************************************************************
1123 *********************************************************************/
1125 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1128 /* times are stored as 32bit integer
1129 take care on system with 64bit wide time_t
1130 --SSS */
1131 uint32_t logon_time,
1132 logoff_time,
1133 kickoff_time,
1134 bad_password_time,
1135 pass_last_set_time,
1136 pass_can_change_time,
1137 pass_must_change_time;
1138 char *username = NULL;
1139 char *domain = NULL;
1140 char *nt_username = NULL;
1141 char *dir_drive = NULL;
1142 char *unknown_str = NULL;
1143 char *munged_dial = NULL;
1144 char *fullname = NULL;
1145 char *homedir = NULL;
1146 char *logon_script = NULL;
1147 char *profile_path = NULL;
1148 char *acct_desc = NULL;
1149 char *workstations = NULL;
1150 uint32_t username_len, domain_len, nt_username_len,
1151 dir_drive_len, unknown_str_len, munged_dial_len,
1152 fullname_len, homedir_len, logon_script_len,
1153 profile_path_len, acct_desc_len, workstations_len;
1155 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
1156 uint16_t acct_ctrl, logon_divs;
1157 uint16_t bad_password_count, logon_count;
1158 uint8_t *hours = NULL;
1159 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1160 uint32_t len = 0;
1161 uint32_t lm_pw_len, nt_pw_len, hourslen;
1162 bool ret = True;
1164 if(sampass == NULL || buf == NULL) {
1165 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1166 return False;
1169 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1171 /* unpack the buffer into variables */
1172 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1173 &logon_time, /* d */
1174 &logoff_time, /* d */
1175 &kickoff_time, /* d */
1176 /* Change from V0 is addition of bad_password_time field. */
1177 &bad_password_time, /* d */
1178 &pass_last_set_time, /* d */
1179 &pass_can_change_time, /* d */
1180 &pass_must_change_time, /* d */
1181 &username_len, &username, /* B */
1182 &domain_len, &domain, /* B */
1183 &nt_username_len, &nt_username, /* B */
1184 &fullname_len, &fullname, /* B */
1185 &homedir_len, &homedir, /* B */
1186 &dir_drive_len, &dir_drive, /* B */
1187 &logon_script_len, &logon_script, /* B */
1188 &profile_path_len, &profile_path, /* B */
1189 &acct_desc_len, &acct_desc, /* B */
1190 &workstations_len, &workstations, /* B */
1191 &unknown_str_len, &unknown_str, /* B */
1192 &munged_dial_len, &munged_dial, /* B */
1193 &user_rid, /* d */
1194 &group_rid, /* d */
1195 &lm_pw_len, &lm_pw_ptr, /* B */
1196 &nt_pw_len, &nt_pw_ptr, /* B */
1197 &acct_ctrl, /* w */
1198 &remove_me, /* d */
1199 &logon_divs, /* w */
1200 &hours_len, /* d */
1201 &hourslen, &hours, /* B */
1202 &bad_password_count, /* w */
1203 &logon_count, /* w */
1204 &unknown_6); /* d */
1206 if (len == (uint32_t) -1) {
1207 ret = False;
1208 goto done;
1211 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1212 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1213 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1215 /* Change from V0 is addition of bad_password_time field. */
1216 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1217 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1218 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1220 pdb_set_username(sampass, username, PDB_SET);
1221 pdb_set_domain(sampass, domain, PDB_SET);
1222 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1223 pdb_set_fullname(sampass, fullname, PDB_SET);
1225 if (homedir) {
1226 pdb_set_homedir(sampass, homedir, PDB_SET);
1228 else {
1229 pdb_set_homedir(sampass,
1230 talloc_sub_basic(sampass, username, domain,
1231 lp_logon_home()),
1232 PDB_DEFAULT);
1235 if (dir_drive)
1236 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1237 else {
1238 pdb_set_dir_drive(sampass,
1239 talloc_sub_basic(sampass, username, domain,
1240 lp_logon_drive()),
1241 PDB_DEFAULT);
1244 if (logon_script)
1245 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1246 else {
1247 pdb_set_logon_script(sampass,
1248 talloc_sub_basic(sampass, username, domain,
1249 lp_logon_script()),
1250 PDB_DEFAULT);
1253 if (profile_path) {
1254 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1255 } else {
1256 pdb_set_profile_path(sampass,
1257 talloc_sub_basic(sampass, username, domain,
1258 lp_logon_path()),
1259 PDB_DEFAULT);
1262 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1263 pdb_set_workstations(sampass, workstations, PDB_SET);
1264 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1266 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1267 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1268 ret = False;
1269 goto done;
1273 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1274 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1275 ret = False;
1276 goto done;
1280 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1282 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1283 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1284 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1285 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1286 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1287 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1288 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1289 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1290 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1292 done:
1294 SAFE_FREE(username);
1295 SAFE_FREE(domain);
1296 SAFE_FREE(nt_username);
1297 SAFE_FREE(fullname);
1298 SAFE_FREE(homedir);
1299 SAFE_FREE(dir_drive);
1300 SAFE_FREE(logon_script);
1301 SAFE_FREE(profile_path);
1302 SAFE_FREE(acct_desc);
1303 SAFE_FREE(workstations);
1304 SAFE_FREE(munged_dial);
1305 SAFE_FREE(unknown_str);
1306 SAFE_FREE(lm_pw_ptr);
1307 SAFE_FREE(nt_pw_ptr);
1308 SAFE_FREE(hours);
1310 return ret;
1313 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1316 /* times are stored as 32bit integer
1317 take care on system with 64bit wide time_t
1318 --SSS */
1319 uint32_t logon_time,
1320 logoff_time,
1321 kickoff_time,
1322 bad_password_time,
1323 pass_last_set_time,
1324 pass_can_change_time,
1325 pass_must_change_time;
1326 char *username = NULL;
1327 char *domain = NULL;
1328 char *nt_username = NULL;
1329 char *dir_drive = NULL;
1330 char *unknown_str = NULL;
1331 char *munged_dial = NULL;
1332 char *fullname = NULL;
1333 char *homedir = NULL;
1334 char *logon_script = NULL;
1335 char *profile_path = NULL;
1336 char *acct_desc = NULL;
1337 char *workstations = NULL;
1338 uint32_t username_len, domain_len, nt_username_len,
1339 dir_drive_len, unknown_str_len, munged_dial_len,
1340 fullname_len, homedir_len, logon_script_len,
1341 profile_path_len, acct_desc_len, workstations_len;
1343 uint32_t user_rid, group_rid, hours_len, unknown_6;
1344 uint16_t acct_ctrl, logon_divs;
1345 uint16_t bad_password_count, logon_count;
1346 uint8_t *hours = NULL;
1347 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1348 uint32_t len = 0;
1349 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1350 uint32_t pwHistLen = 0;
1351 bool ret = True;
1352 fstring tmp_string;
1353 bool expand_explicit = lp_passdb_expand_explicit();
1355 if(sampass == NULL || buf == NULL) {
1356 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1357 return False;
1360 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1362 /* unpack the buffer into variables */
1363 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1364 &logon_time, /* d */
1365 &logoff_time, /* d */
1366 &kickoff_time, /* d */
1367 &bad_password_time, /* d */
1368 &pass_last_set_time, /* d */
1369 &pass_can_change_time, /* d */
1370 &pass_must_change_time, /* d */
1371 &username_len, &username, /* B */
1372 &domain_len, &domain, /* B */
1373 &nt_username_len, &nt_username, /* B */
1374 &fullname_len, &fullname, /* B */
1375 &homedir_len, &homedir, /* B */
1376 &dir_drive_len, &dir_drive, /* B */
1377 &logon_script_len, &logon_script, /* B */
1378 &profile_path_len, &profile_path, /* B */
1379 &acct_desc_len, &acct_desc, /* B */
1380 &workstations_len, &workstations, /* B */
1381 &unknown_str_len, &unknown_str, /* B */
1382 &munged_dial_len, &munged_dial, /* B */
1383 &user_rid, /* d */
1384 &group_rid, /* d */
1385 &lm_pw_len, &lm_pw_ptr, /* B */
1386 &nt_pw_len, &nt_pw_ptr, /* B */
1387 /* Change from V1 is addition of password history field. */
1388 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1389 &acct_ctrl, /* w */
1390 /* Also "remove_me" field was removed. */
1391 &logon_divs, /* w */
1392 &hours_len, /* d */
1393 &hourslen, &hours, /* B */
1394 &bad_password_count, /* w */
1395 &logon_count, /* w */
1396 &unknown_6); /* d */
1398 if (len == (uint32_t) -1) {
1399 ret = False;
1400 goto done;
1403 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1404 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1405 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1406 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1407 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1408 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1410 pdb_set_username(sampass, username, PDB_SET);
1411 pdb_set_domain(sampass, domain, PDB_SET);
1412 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1413 pdb_set_fullname(sampass, fullname, PDB_SET);
1415 if (homedir) {
1416 fstrcpy( tmp_string, homedir );
1417 if (expand_explicit) {
1418 standard_sub_basic( username, domain, tmp_string,
1419 sizeof(tmp_string) );
1421 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1423 else {
1424 pdb_set_homedir(sampass,
1425 talloc_sub_basic(sampass, username, domain,
1426 lp_logon_home()),
1427 PDB_DEFAULT);
1430 if (dir_drive)
1431 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1432 else
1433 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1435 if (logon_script) {
1436 fstrcpy( tmp_string, logon_script );
1437 if (expand_explicit) {
1438 standard_sub_basic( username, domain, tmp_string,
1439 sizeof(tmp_string) );
1441 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1443 else {
1444 pdb_set_logon_script(sampass,
1445 talloc_sub_basic(sampass, username, domain,
1446 lp_logon_script()),
1447 PDB_DEFAULT);
1450 if (profile_path) {
1451 fstrcpy( tmp_string, profile_path );
1452 if (expand_explicit) {
1453 standard_sub_basic( username, domain, tmp_string,
1454 sizeof(tmp_string) );
1456 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1458 else {
1459 pdb_set_profile_path(sampass,
1460 talloc_sub_basic(sampass, username, domain,
1461 lp_logon_path()),
1462 PDB_DEFAULT);
1465 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1466 pdb_set_workstations(sampass, workstations, PDB_SET);
1467 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1469 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1470 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1471 ret = False;
1472 goto done;
1476 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1477 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1478 ret = False;
1479 goto done;
1483 /* Change from V1 is addition of password history field. */
1484 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1485 if (pwHistLen) {
1486 uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
1487 if (!pw_hist) {
1488 ret = False;
1489 goto done;
1491 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1492 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1493 int i;
1494 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1495 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1496 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1497 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1498 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1499 PW_HISTORY_ENTRY_LEN);
1502 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1503 SAFE_FREE(pw_hist);
1504 ret = False;
1505 goto done;
1507 SAFE_FREE(pw_hist);
1508 } else {
1509 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1512 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1513 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1514 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1515 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1516 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1517 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1518 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1519 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1520 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1522 done:
1524 SAFE_FREE(username);
1525 SAFE_FREE(domain);
1526 SAFE_FREE(nt_username);
1527 SAFE_FREE(fullname);
1528 SAFE_FREE(homedir);
1529 SAFE_FREE(dir_drive);
1530 SAFE_FREE(logon_script);
1531 SAFE_FREE(profile_path);
1532 SAFE_FREE(acct_desc);
1533 SAFE_FREE(workstations);
1534 SAFE_FREE(munged_dial);
1535 SAFE_FREE(unknown_str);
1536 SAFE_FREE(lm_pw_ptr);
1537 SAFE_FREE(nt_pw_ptr);
1538 SAFE_FREE(nt_pw_hist_ptr);
1539 SAFE_FREE(hours);
1541 return ret;
1544 /*********************************************************************
1545 *********************************************************************/
1547 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1550 /* times are stored as 32bit integer
1551 take care on system with 64bit wide time_t
1552 --SSS */
1553 uint32_t logon_time,
1554 logoff_time,
1555 kickoff_time,
1556 bad_password_time,
1557 pass_last_set_time,
1558 pass_can_change_time,
1559 pass_must_change_time;
1560 char *username = NULL;
1561 char *domain = NULL;
1562 char *nt_username = NULL;
1563 char *dir_drive = NULL;
1564 char *comment = NULL;
1565 char *munged_dial = NULL;
1566 char *fullname = NULL;
1567 char *homedir = NULL;
1568 char *logon_script = NULL;
1569 char *profile_path = NULL;
1570 char *acct_desc = NULL;
1571 char *workstations = NULL;
1572 uint32_t username_len, domain_len, nt_username_len,
1573 dir_drive_len, comment_len, munged_dial_len,
1574 fullname_len, homedir_len, logon_script_len,
1575 profile_path_len, acct_desc_len, workstations_len;
1577 uint32_t user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1578 uint16_t logon_divs;
1579 uint16_t bad_password_count, logon_count;
1580 uint8_t *hours = NULL;
1581 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1582 uint32_t len = 0;
1583 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1584 uint32_t pwHistLen = 0;
1585 bool ret = True;
1586 fstring tmp_string;
1587 bool expand_explicit = lp_passdb_expand_explicit();
1589 if(sampass == NULL || buf == NULL) {
1590 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1591 return False;
1594 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1596 /* unpack the buffer into variables */
1597 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1598 &logon_time, /* d */
1599 &logoff_time, /* d */
1600 &kickoff_time, /* d */
1601 &bad_password_time, /* d */
1602 &pass_last_set_time, /* d */
1603 &pass_can_change_time, /* d */
1604 &pass_must_change_time, /* d */
1605 &username_len, &username, /* B */
1606 &domain_len, &domain, /* B */
1607 &nt_username_len, &nt_username, /* B */
1608 &fullname_len, &fullname, /* B */
1609 &homedir_len, &homedir, /* B */
1610 &dir_drive_len, &dir_drive, /* B */
1611 &logon_script_len, &logon_script, /* B */
1612 &profile_path_len, &profile_path, /* B */
1613 &acct_desc_len, &acct_desc, /* B */
1614 &workstations_len, &workstations, /* B */
1615 &comment_len, &comment, /* B */
1616 &munged_dial_len, &munged_dial, /* B */
1617 &user_rid, /* d */
1618 &group_rid, /* d */
1619 &lm_pw_len, &lm_pw_ptr, /* B */
1620 &nt_pw_len, &nt_pw_ptr, /* B */
1621 /* Change from V1 is addition of password history field. */
1622 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1623 /* Change from V2 is the uint32_t acb_mask */
1624 &acct_ctrl, /* d */
1625 /* Also "remove_me" field was removed. */
1626 &logon_divs, /* w */
1627 &hours_len, /* d */
1628 &hourslen, &hours, /* B */
1629 &bad_password_count, /* w */
1630 &logon_count, /* w */
1631 &unknown_6); /* d */
1633 if (len == (uint32_t) -1) {
1634 ret = False;
1635 goto done;
1638 pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
1639 pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
1640 pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
1641 pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
1642 pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
1643 pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
1645 pdb_set_username(sampass, username, PDB_SET);
1646 pdb_set_domain(sampass, domain, PDB_SET);
1647 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1648 pdb_set_fullname(sampass, fullname, PDB_SET);
1650 if (homedir) {
1651 fstrcpy( tmp_string, homedir );
1652 if (expand_explicit) {
1653 standard_sub_basic( username, domain, tmp_string,
1654 sizeof(tmp_string) );
1656 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1658 else {
1659 pdb_set_homedir(sampass,
1660 talloc_sub_basic(sampass, username, domain,
1661 lp_logon_home()),
1662 PDB_DEFAULT);
1665 if (dir_drive)
1666 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1667 else
1668 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1670 if (logon_script) {
1671 fstrcpy( tmp_string, logon_script );
1672 if (expand_explicit) {
1673 standard_sub_basic( username, domain, tmp_string,
1674 sizeof(tmp_string) );
1676 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1678 else {
1679 pdb_set_logon_script(sampass,
1680 talloc_sub_basic(sampass, username, domain,
1681 lp_logon_script()),
1682 PDB_DEFAULT);
1685 if (profile_path) {
1686 fstrcpy( tmp_string, profile_path );
1687 if (expand_explicit) {
1688 standard_sub_basic( username, domain, tmp_string,
1689 sizeof(tmp_string) );
1691 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1693 else {
1694 pdb_set_profile_path(sampass,
1695 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1696 PDB_DEFAULT);
1699 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1700 pdb_set_comment(sampass, comment, PDB_SET);
1701 pdb_set_workstations(sampass, workstations, PDB_SET);
1702 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1704 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1705 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1706 ret = False;
1707 goto done;
1711 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1712 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1713 ret = False;
1714 goto done;
1718 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1719 if (pwHistLen) {
1720 uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1721 if (!pw_hist) {
1722 ret = False;
1723 goto done;
1725 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1726 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1727 int i;
1728 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1729 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1730 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1731 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1732 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1733 PW_HISTORY_ENTRY_LEN);
1736 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1737 SAFE_FREE(pw_hist);
1738 ret = False;
1739 goto done;
1741 SAFE_FREE(pw_hist);
1742 } else {
1743 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1746 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1747 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1748 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1749 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1750 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1751 /* Change from V2 is the uint32_t acct_ctrl */
1752 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1753 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1754 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1756 done:
1758 SAFE_FREE(username);
1759 SAFE_FREE(domain);
1760 SAFE_FREE(nt_username);
1761 SAFE_FREE(fullname);
1762 SAFE_FREE(homedir);
1763 SAFE_FREE(dir_drive);
1764 SAFE_FREE(logon_script);
1765 SAFE_FREE(profile_path);
1766 SAFE_FREE(acct_desc);
1767 SAFE_FREE(workstations);
1768 SAFE_FREE(munged_dial);
1769 SAFE_FREE(comment);
1770 SAFE_FREE(lm_pw_ptr);
1771 SAFE_FREE(nt_pw_ptr);
1772 SAFE_FREE(nt_pw_hist_ptr);
1773 SAFE_FREE(hours);
1775 return ret;
1778 /*********************************************************************
1779 *********************************************************************/
1781 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
1783 size_t len, buflen;
1785 /* times are stored as 32bit integer
1786 take care on system with 64bit wide time_t
1787 --SSS */
1788 uint32_t logon_time,
1789 logoff_time,
1790 kickoff_time,
1791 bad_password_time,
1792 pass_last_set_time,
1793 pass_can_change_time,
1794 pass_must_change_time;
1796 uint32_t user_rid, group_rid;
1798 const char *username;
1799 const char *domain;
1800 const char *nt_username;
1801 const char *dir_drive;
1802 const char *comment;
1803 const char *munged_dial;
1804 const char *fullname;
1805 const char *homedir;
1806 const char *logon_script;
1807 const char *profile_path;
1808 const char *acct_desc;
1809 const char *workstations;
1810 uint32_t username_len, domain_len, nt_username_len,
1811 dir_drive_len, comment_len, munged_dial_len,
1812 fullname_len, homedir_len, logon_script_len,
1813 profile_path_len, acct_desc_len, workstations_len;
1815 const uint8_t *lm_pw;
1816 const uint8_t *nt_pw;
1817 const uint8_t *nt_pw_hist;
1818 uint32_t lm_pw_len = 16;
1819 uint32_t nt_pw_len = 16;
1820 uint32_t nt_pw_hist_len;
1821 uint32_t pwHistLen = 0;
1823 *buf = NULL;
1824 buflen = 0;
1826 logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
1827 logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
1828 kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
1829 bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
1830 pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
1831 pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
1832 pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
1834 user_rid = pdb_get_user_rid(sampass);
1835 group_rid = pdb_get_group_rid(sampass);
1837 username = pdb_get_username(sampass);
1838 if (username) {
1839 username_len = strlen(username) +1;
1840 } else {
1841 username_len = 0;
1844 domain = pdb_get_domain(sampass);
1845 if (domain) {
1846 domain_len = strlen(domain) +1;
1847 } else {
1848 domain_len = 0;
1851 nt_username = pdb_get_nt_username(sampass);
1852 if (nt_username) {
1853 nt_username_len = strlen(nt_username) +1;
1854 } else {
1855 nt_username_len = 0;
1858 fullname = pdb_get_fullname(sampass);
1859 if (fullname) {
1860 fullname_len = strlen(fullname) +1;
1861 } else {
1862 fullname_len = 0;
1866 * Only updates fields which have been set (not defaults from smb.conf)
1869 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1870 dir_drive = pdb_get_dir_drive(sampass);
1871 } else {
1872 dir_drive = NULL;
1874 if (dir_drive) {
1875 dir_drive_len = strlen(dir_drive) +1;
1876 } else {
1877 dir_drive_len = 0;
1880 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1881 homedir = pdb_get_homedir(sampass);
1882 } else {
1883 homedir = NULL;
1885 if (homedir) {
1886 homedir_len = strlen(homedir) +1;
1887 } else {
1888 homedir_len = 0;
1891 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1892 logon_script = pdb_get_logon_script(sampass);
1893 } else {
1894 logon_script = NULL;
1896 if (logon_script) {
1897 logon_script_len = strlen(logon_script) +1;
1898 } else {
1899 logon_script_len = 0;
1902 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1903 profile_path = pdb_get_profile_path(sampass);
1904 } else {
1905 profile_path = NULL;
1907 if (profile_path) {
1908 profile_path_len = strlen(profile_path) +1;
1909 } else {
1910 profile_path_len = 0;
1913 lm_pw = pdb_get_lanman_passwd(sampass);
1914 if (!lm_pw) {
1915 lm_pw_len = 0;
1918 nt_pw = pdb_get_nt_passwd(sampass);
1919 if (!nt_pw) {
1920 nt_pw_len = 0;
1923 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1924 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1925 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1926 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1927 } else {
1928 nt_pw_hist_len = 0;
1931 acct_desc = pdb_get_acct_desc(sampass);
1932 if (acct_desc) {
1933 acct_desc_len = strlen(acct_desc) +1;
1934 } else {
1935 acct_desc_len = 0;
1938 workstations = pdb_get_workstations(sampass);
1939 if (workstations) {
1940 workstations_len = strlen(workstations) +1;
1941 } else {
1942 workstations_len = 0;
1945 comment = pdb_get_comment(sampass);
1946 if (comment) {
1947 comment_len = strlen(comment) +1;
1948 } else {
1949 comment_len = 0;
1952 munged_dial = pdb_get_munged_dial(sampass);
1953 if (munged_dial) {
1954 munged_dial_len = strlen(munged_dial) +1;
1955 } else {
1956 munged_dial_len = 0;
1959 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1961 /* one time to get the size needed */
1962 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3,
1963 logon_time, /* d */
1964 logoff_time, /* d */
1965 kickoff_time, /* d */
1966 bad_password_time, /* d */
1967 pass_last_set_time, /* d */
1968 pass_can_change_time, /* d */
1969 pass_must_change_time, /* d */
1970 username_len, username, /* B */
1971 domain_len, domain, /* B */
1972 nt_username_len, nt_username, /* B */
1973 fullname_len, fullname, /* B */
1974 homedir_len, homedir, /* B */
1975 dir_drive_len, dir_drive, /* B */
1976 logon_script_len, logon_script, /* B */
1977 profile_path_len, profile_path, /* B */
1978 acct_desc_len, acct_desc, /* B */
1979 workstations_len, workstations, /* B */
1980 comment_len, comment, /* B */
1981 munged_dial_len, munged_dial, /* B */
1982 user_rid, /* d */
1983 group_rid, /* d */
1984 lm_pw_len, lm_pw, /* B */
1985 nt_pw_len, nt_pw, /* B */
1986 nt_pw_hist_len, nt_pw_hist, /* B */
1987 pdb_get_acct_ctrl(sampass), /* d */
1988 pdb_get_logon_divs(sampass), /* w */
1989 pdb_get_hours_len(sampass), /* d */
1990 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1991 pdb_get_bad_password_count(sampass), /* w */
1992 pdb_get_logon_count(sampass), /* w */
1993 pdb_get_unknown_6(sampass)); /* d */
1995 if (size_only) {
1996 return buflen;
1999 /* malloc the space needed */
2000 if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
2001 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
2002 return (-1);
2005 /* now for the real call to tdb_pack() */
2006 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
2007 logon_time, /* d */
2008 logoff_time, /* d */
2009 kickoff_time, /* d */
2010 bad_password_time, /* d */
2011 pass_last_set_time, /* d */
2012 pass_can_change_time, /* d */
2013 pass_must_change_time, /* d */
2014 username_len, username, /* B */
2015 domain_len, domain, /* B */
2016 nt_username_len, nt_username, /* B */
2017 fullname_len, fullname, /* B */
2018 homedir_len, homedir, /* B */
2019 dir_drive_len, dir_drive, /* B */
2020 logon_script_len, logon_script, /* B */
2021 profile_path_len, profile_path, /* B */
2022 acct_desc_len, acct_desc, /* B */
2023 workstations_len, workstations, /* B */
2024 comment_len, comment, /* B */
2025 munged_dial_len, munged_dial, /* B */
2026 user_rid, /* d */
2027 group_rid, /* d */
2028 lm_pw_len, lm_pw, /* B */
2029 nt_pw_len, nt_pw, /* B */
2030 nt_pw_hist_len, nt_pw_hist, /* B */
2031 pdb_get_acct_ctrl(sampass), /* d */
2032 pdb_get_logon_divs(sampass), /* w */
2033 pdb_get_hours_len(sampass), /* d */
2034 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2035 pdb_get_bad_password_count(sampass), /* w */
2036 pdb_get_logon_count(sampass), /* w */
2037 pdb_get_unknown_6(sampass)); /* d */
2039 /* check to make sure we got it correct */
2040 if (buflen != len) {
2041 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2042 (unsigned long)buflen, (unsigned long)len));
2043 /* error */
2044 SAFE_FREE (*buf);
2045 return (-1);
2048 return (buflen);
2051 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
2053 /* nothing changed between V3 and V4 */
2054 return init_samu_from_buffer_v3(sampass, buf, buflen);
2057 static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
2059 /* nothing changed between V3 and V4 */
2060 return init_buffer_from_samu_v3(buf, sampass, size_only);
2063 /**********************************************************************
2064 Intialize a struct samu struct from a BYTE buffer of size len
2065 *********************************************************************/
2067 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2068 uint8_t *buf, uint32_t buflen)
2070 switch (level) {
2071 case SAMU_BUFFER_V0:
2072 return init_samu_from_buffer_v0(sampass, buf, buflen);
2073 case SAMU_BUFFER_V1:
2074 return init_samu_from_buffer_v1(sampass, buf, buflen);
2075 case SAMU_BUFFER_V2:
2076 return init_samu_from_buffer_v2(sampass, buf, buflen);
2077 case SAMU_BUFFER_V3:
2078 return init_samu_from_buffer_v3(sampass, buf, buflen);
2079 case SAMU_BUFFER_V4:
2080 return init_samu_from_buffer_v4(sampass, buf, buflen);
2083 return false;
2086 /**********************************************************************
2087 Intialize a BYTE buffer from a struct samu struct
2088 *********************************************************************/
2090 uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
2092 return init_buffer_from_samu_v4(buf, sampass, size_only);
2095 /*********************************************************************
2096 *********************************************************************/
2098 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2100 uint8_t *buf = NULL;
2101 int len;
2103 len = init_buffer_from_samu(&buf, src, False);
2104 if (len == -1 || !buf) {
2105 SAFE_FREE(buf);
2106 return False;
2109 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2110 free(buf);
2111 return False;
2114 dst->methods = src->methods;
2116 if ( src->unix_pw ) {
2117 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2118 if (!dst->unix_pw) {
2119 free(buf);
2120 return False;
2124 if (src->group_sid) {
2125 pdb_set_group_sid(dst, src->group_sid, PDB_SET);
2128 free(buf);
2129 return True;
2132 /*********************************************************************
2133 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2134 *********************************************************************/
2136 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2138 time_t LastBadPassword;
2139 uint16_t BadPasswordCount;
2140 uint32_t resettime;
2141 bool res;
2143 BadPasswordCount = pdb_get_bad_password_count(sampass);
2144 if (!BadPasswordCount) {
2145 DEBUG(9, ("No bad password attempts.\n"));
2146 return True;
2149 become_root();
2150 res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2151 unbecome_root();
2153 if (!res) {
2154 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2155 return False;
2158 /* First, check if there is a reset time to compare */
2159 if ((resettime == (uint32_t) -1) || (resettime == 0)) {
2160 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2161 return True;
2164 LastBadPassword = pdb_get_bad_password_time(sampass);
2165 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2166 (uint32_t) LastBadPassword, resettime, (uint32_t)time(NULL)));
2167 if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
2168 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2169 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2170 if (updated) {
2171 *updated = True;
2175 return True;
2178 /*********************************************************************
2179 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2180 *********************************************************************/
2182 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2184 uint32_t duration;
2185 time_t LastBadPassword;
2186 bool res;
2188 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2189 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2190 pdb_get_username(sampass)));
2191 return True;
2194 become_root();
2195 res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2196 unbecome_root();
2198 if (!res) {
2199 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2200 return False;
2203 /* First, check if there is a duration to compare */
2204 if ((duration == (uint32_t) -1) || (duration == 0)) {
2205 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2206 return True;
2209 LastBadPassword = pdb_get_bad_password_time(sampass);
2210 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2211 pdb_get_username(sampass), (uint32_t)LastBadPassword, duration*60, (uint32_t)time(NULL)));
2213 if (LastBadPassword == (time_t)0) {
2214 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2215 "administratively locked out with no bad password "
2216 "time. Leaving locked out.\n",
2217 pdb_get_username(sampass) ));
2218 return True;
2221 if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
2222 pdb_set_acct_ctrl(sampass,
2223 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2224 PDB_CHANGED);
2225 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2226 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2227 if (updated) {
2228 *updated = True;
2232 return True;
2235 /*********************************************************************
2236 Increment the bad_password_count
2237 *********************************************************************/
2239 bool pdb_increment_bad_password_count(struct samu *sampass)
2241 uint32_t account_policy_lockout;
2242 bool autolock_updated = False, badpw_updated = False;
2243 bool ret;
2245 /* Retrieve the account lockout policy */
2246 become_root();
2247 ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2248 unbecome_root();
2249 if ( !ret ) {
2250 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2251 return False;
2254 /* If there is no policy, we don't need to continue checking */
2255 if (!account_policy_lockout) {
2256 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2257 return True;
2260 /* Check if the autolock needs to be cleared */
2261 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2262 return False;
2264 /* Check if the badpw count needs to be reset */
2265 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2266 return False;
2269 Ok, now we can assume that any resetting that needs to be
2270 done has been done, and just get on with incrementing
2271 and autolocking if necessary
2274 pdb_set_bad_password_count(sampass,
2275 pdb_get_bad_password_count(sampass)+1,
2276 PDB_CHANGED);
2277 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2280 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2281 return True;
2283 if (!pdb_set_acct_ctrl(sampass,
2284 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2285 PDB_CHANGED)) {
2286 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2287 return False;
2290 return True;
2293 bool is_dc_trusted_domain_situation(const char *domain_name)
2295 return IS_DC && !strequal(domain_name, lp_workgroup());
2298 /*******************************************************************
2299 Wrapper around retrieving the clear text trust account password.
2300 appropriate account name is stored in account_name.
2301 Caller must free password, but not account_name.
2302 *******************************************************************/
2304 static bool get_trust_pw_clear2(const char *domain,
2305 const char **account_name,
2306 enum netr_SchannelType *channel,
2307 char **cur_pw,
2308 time_t *_last_set_time,
2309 char **prev_pw)
2311 char *pwd;
2312 time_t last_set_time;
2314 if (cur_pw != NULL) {
2315 *cur_pw = NULL;
2317 if (_last_set_time != NULL) {
2318 *_last_set_time = 0;
2320 if (prev_pw != NULL) {
2321 *prev_pw = NULL;
2324 /* if we are a DC and this is not our domain, then lookup an account
2325 * for the domain trust */
2327 if (is_dc_trusted_domain_situation(domain)) {
2328 if (!lp_allow_trusted_domains()) {
2329 return false;
2332 if (!pdb_get_trusteddom_pw(domain, cur_pw, NULL,
2333 &last_set_time))
2335 DEBUG(0, ("get_trust_pw: could not fetch trust "
2336 "account password for trusted domain %s\n",
2337 domain));
2338 return false;
2341 if (channel != NULL) {
2342 *channel = SEC_CHAN_DOMAIN;
2345 if (account_name != NULL) {
2346 *account_name = lp_workgroup();
2349 if (_last_set_time != NULL) {
2350 *_last_set_time = last_set_time;
2353 return true;
2357 * Since we can only be member of one single domain, we are now
2358 * in a member situation:
2360 * - Either we are a DC (selfjoined) and the domain is our
2361 * own domain.
2362 * - Or we are on a member and the domain is our own or some
2363 * other (potentially trusted) domain.
2365 * In both cases, we can only get the machine account password
2366 * for our own domain to connect to our own dc. (For a member,
2367 * request to trusted domains are performed through our dc.)
2369 * So we simply use our own domain name to retrieve the
2370 * machine account passowrd and ignore the request domain here.
2373 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2375 if (pwd != NULL) {
2376 struct timeval expire;
2378 *cur_pw = pwd;
2380 if (account_name != NULL) {
2381 *account_name = lp_netbios_name();
2384 if (_last_set_time != NULL) {
2385 *_last_set_time = last_set_time;
2388 if (prev_pw == NULL) {
2389 return true;
2392 ZERO_STRUCT(expire);
2393 expire.tv_sec = lp_machine_password_timeout();
2394 expire.tv_sec /= 2;
2395 expire.tv_sec += last_set_time;
2396 if (timeval_expired(&expire)) {
2397 return true;
2400 pwd = secrets_fetch_prev_machine_password(lp_workgroup());
2401 if (pwd != NULL) {
2402 *prev_pw = pwd;
2405 return true;
2408 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2409 "account password for domain %s\n", domain));
2410 return false;
2413 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2414 const char **account_name,
2415 enum netr_SchannelType *channel)
2417 return get_trust_pw_clear2(domain,
2418 account_name,
2419 channel,
2420 ret_pwd,
2421 NULL,
2422 NULL);
2425 /*******************************************************************
2426 Wrapper around retrieving the trust account password.
2427 appropriate account name is stored in account_name.
2428 *******************************************************************/
2430 static bool get_trust_pw_hash2(const char *domain,
2431 const char **account_name,
2432 enum netr_SchannelType *channel,
2433 struct samr_Password *current_nt_hash,
2434 time_t *last_set_time,
2435 struct samr_Password **_previous_nt_hash)
2437 char *cur_pw = NULL;
2438 char *prev_pw = NULL;
2439 char **_prev_pw = NULL;
2440 bool ok;
2442 if (_previous_nt_hash != NULL) {
2443 *_previous_nt_hash = NULL;
2444 _prev_pw = &prev_pw;
2447 ok = get_trust_pw_clear2(domain, account_name, channel,
2448 &cur_pw, last_set_time, _prev_pw);
2449 if (ok) {
2450 struct samr_Password *previous_nt_hash = NULL;
2452 E_md4hash(cur_pw, current_nt_hash->hash);
2453 SAFE_FREE(cur_pw);
2455 if (prev_pw == NULL) {
2456 return true;
2459 previous_nt_hash = SMB_MALLOC_P(struct samr_Password);
2460 if (previous_nt_hash == NULL) {
2461 return false;
2464 E_md4hash(prev_pw, previous_nt_hash->hash);
2465 SAFE_FREE(prev_pw);
2467 *_previous_nt_hash = previous_nt_hash;
2468 return true;
2469 } else if (is_dc_trusted_domain_situation(domain)) {
2470 return false;
2473 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2475 if (secrets_fetch_trust_account_password_legacy(domain,
2476 current_nt_hash->hash,
2477 last_set_time,
2478 channel))
2480 if (account_name != NULL) {
2481 *account_name = lp_netbios_name();
2484 return true;
2487 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2488 "password for domain %s\n", domain));
2489 return False;
2492 bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
2493 const char **account_name,
2494 enum netr_SchannelType *channel)
2496 struct samr_Password current_nt_hash;
2497 bool ok;
2499 ok = get_trust_pw_hash2(domain, account_name, channel,
2500 &current_nt_hash, NULL, NULL);
2501 if (!ok) {
2502 return false;
2505 memcpy(ret_pwd, current_nt_hash.hash, sizeof(current_nt_hash.hash));
2506 return true;
2509 NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
2510 const char *dns_domain, /* optional */
2511 TALLOC_CTX *mem_ctx,
2512 struct cli_credentials **_creds)
2514 TALLOC_CTX *frame = talloc_stackframe();
2515 NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
2516 struct loadparm_context *lp_ctx;
2517 enum netr_SchannelType channel;
2518 time_t last_set_time;
2519 const char *_account_name;
2520 const char *account_name;
2521 char *cur_pw = NULL;
2522 char *prev_pw = NULL;
2523 struct samr_Password cur_nt_hash;
2524 struct cli_credentials *creds = NULL;
2525 bool ok;
2528 * If this is our primary trust relationship, use the common
2529 * code to read the secrets.ldb or secrets.tdb file.
2531 if (strequal(netbios_domain, lp_workgroup())) {
2532 struct db_context *db_ctx = secrets_db_ctx();
2533 if (db_ctx == NULL) {
2534 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2535 netbios_domain));
2536 status = NT_STATUS_INTERNAL_ERROR;
2537 goto fail;
2540 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2541 if (lp_ctx == NULL) {
2542 DEBUG(1, ("loadparm_init_s3 failed\n"));
2543 status = NT_STATUS_INTERNAL_ERROR;
2544 goto fail;
2547 creds = cli_credentials_init(mem_ctx);
2548 if (creds == NULL) {
2549 status = NT_STATUS_NO_MEMORY;
2550 goto fail;
2553 cli_credentials_set_conf(creds, lp_ctx);
2555 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2556 if (!ok) {
2557 status = NT_STATUS_NO_MEMORY;
2558 goto fail;
2561 status = cli_credentials_set_machine_account_db_ctx(creds,
2562 lp_ctx,
2563 db_ctx);
2564 if (!NT_STATUS_IS_OK(status)) {
2565 goto fail;
2567 goto done;
2568 } else if (!IS_DC) {
2569 DEBUG(1, ("Refusing to get trust account info for %s, "
2570 "which is not our primary domain %s, "
2571 "as we are not a DC\n",
2572 netbios_domain, lp_workgroup()));
2573 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2574 goto fail;
2577 status = pdb_get_trusteddom_creds(netbios_domain, mem_ctx, &creds);
2578 if (NT_STATUS_IS_OK(status)) {
2579 goto done;
2581 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
2582 goto fail;
2585 ok = get_trust_pw_clear2(netbios_domain,
2586 &_account_name,
2587 &channel,
2588 &cur_pw,
2589 &last_set_time,
2590 &prev_pw);
2591 if (!ok) {
2592 ok = get_trust_pw_hash2(netbios_domain,
2593 &_account_name,
2594 &channel,
2595 &cur_nt_hash,
2596 &last_set_time,
2597 NULL);
2598 if (!ok) {
2599 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2600 netbios_domain));
2601 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2602 goto fail;
2606 account_name = talloc_asprintf(frame, "%s$", _account_name);
2607 if (account_name == NULL) {
2608 status = NT_STATUS_NO_MEMORY;
2609 goto fail;
2612 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2613 if (lp_ctx == NULL) {
2614 DEBUG(1, ("loadparm_init_s3 failed\n"));
2615 status = NT_STATUS_INTERNAL_ERROR;
2616 goto fail;
2619 creds = cli_credentials_init(mem_ctx);
2620 if (creds == NULL) {
2621 status = NT_STATUS_NO_MEMORY;
2622 goto fail;
2625 cli_credentials_set_conf(creds, lp_ctx);
2627 cli_credentials_set_secure_channel_type(creds, channel);
2628 cli_credentials_set_password_last_changed_time(creds, last_set_time);
2630 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2631 if (!ok) {
2632 status = NT_STATUS_NO_MEMORY;
2633 goto fail;
2636 if (dns_domain != NULL) {
2637 ok = cli_credentials_set_realm(creds, dns_domain, CRED_SPECIFIED);
2638 if (!ok) {
2639 status = NT_STATUS_NO_MEMORY;
2640 goto fail;
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;
2656 goto done;
2659 ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
2660 if (!ok) {
2661 status = NT_STATUS_NO_MEMORY;
2662 goto fail;
2665 if (prev_pw != NULL) {
2666 ok = cli_credentials_set_old_password(creds, prev_pw, CRED_SPECIFIED);
2667 if (!ok) {
2668 status = NT_STATUS_NO_MEMORY;
2669 goto fail;
2673 done:
2674 *_creds = creds;
2675 creds = NULL;
2676 status = NT_STATUS_OK;
2677 fail:
2678 TALLOC_FREE(creds);
2679 SAFE_FREE(cur_pw);
2680 SAFE_FREE(prev_pw);
2681 TALLOC_FREE(frame);
2682 return status;