r5021: Starting to look at final code for 3.0.11rc1.
[Samba.git] / source / passdb / passdb.c
blobc7cd59a4c5f66cdf9d9ad7d6834d2fea2bd01beb
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-2001
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Simo Sorce 2003
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
30 /******************************************************************
31 get the default domain/netbios name to be used when
32 testing authentication. For example, if you connect
33 to a Windows member server using a bogus domain name, the
34 Windows box will map the BOGUS\user to DOMAIN\user. A
35 standalone box will map to WKS\user.
36 ******************************************************************/
38 const char *get_default_sam_name(void)
40 /* standalone servers can only use the local netbios name */
41 if ( lp_server_role() == ROLE_STANDALONE )
42 return global_myname();
44 /* Windows domain members default to the DOMAIN
45 name when not specified */
46 return lp_workgroup();
49 /************************************************************
50 Fill the SAM_ACCOUNT with default values.
51 ***********************************************************/
53 void pdb_fill_default_sam(SAM_ACCOUNT *user)
55 ZERO_STRUCT(user->private); /* Don't touch the talloc context */
57 /* no initial methods */
58 user->methods = NULL;
60 /* Don't change these timestamp settings without a good reason.
61 They are important for NT member server compatibility. */
63 user->private.logon_time = (time_t)0;
64 user->private.pass_last_set_time = (time_t)0;
65 user->private.pass_can_change_time = (time_t)0;
66 user->private.logoff_time =
67 user->private.kickoff_time =
68 user->private.pass_must_change_time = get_time_t_max();
69 user->private.fields_present = 0x00ffffff;
70 user->private.logon_divs = 168; /* hours per week */
71 user->private.hours_len = 21; /* 21 times 8 bits = 168 */
72 memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
73 user->private.bad_password_count = 0;
74 user->private.logon_count = 0;
75 user->private.unknown_6 = 0x000004ec; /* don't know */
77 /* Some parts of samba strlen their pdb_get...() returns,
78 so this keeps the interface unchanged for now. */
80 user->private.username = "";
81 user->private.domain = "";
82 user->private.nt_username = "";
83 user->private.full_name = "";
84 user->private.home_dir = "";
85 user->private.logon_script = "";
86 user->private.profile_path = "";
87 user->private.acct_desc = "";
88 user->private.workstations = "";
89 user->private.unknown_str = "";
90 user->private.munged_dial = "";
92 user->private.plaintext_pw = NULL;
94 /*
95 Unless we know otherwise have a Account Control Bit
96 value of 'normal user'. This helps User Manager, which
97 asks for a filtered list of users.
100 user->private.acct_ctrl = ACB_NORMAL;
103 static void destroy_pdb_talloc(SAM_ACCOUNT **user)
105 if (*user) {
106 data_blob_clear_free(&((*user)->private.lm_pw));
107 data_blob_clear_free(&((*user)->private.nt_pw));
109 if((*user)->private.plaintext_pw!=NULL)
110 memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw));
111 talloc_destroy((*user)->mem_ctx);
112 *user = NULL;
117 /**********************************************************************
118 Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.
119 ***********************************************************************/
121 NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
123 if (*user != NULL) {
124 DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
125 #if 0
126 smb_panic("non-NULL pointer passed to pdb_init_sam\n");
127 #endif
128 return NT_STATUS_UNSUCCESSFUL;
131 if (!mem_ctx) {
132 DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
133 return NT_STATUS_UNSUCCESSFUL;
136 *user=TALLOC_P(mem_ctx, SAM_ACCOUNT);
138 if (*user==NULL) {
139 DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
140 return NT_STATUS_NO_MEMORY;
143 (*user)->mem_ctx = mem_ctx;
145 (*user)->free_fn = NULL;
147 pdb_fill_default_sam(*user);
149 return NT_STATUS_OK;
153 /*************************************************************
154 Allocates memory and initialises a struct sam_passwd.
155 ************************************************************/
157 NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
159 TALLOC_CTX *mem_ctx;
160 NTSTATUS nt_status;
162 mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");
164 if (!mem_ctx) {
165 DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
166 return NT_STATUS_NO_MEMORY;
169 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
170 talloc_destroy(mem_ctx);
171 return nt_status;
174 (*user)->free_fn = destroy_pdb_talloc;
176 return NT_STATUS_OK;
179 /**************************************************************************
180 * This function will take care of all the steps needed to correctly
181 * allocate and set the user SID, please do use this function to create new
182 * users, messing with SIDs is not good.
184 * account_data must be provided initialized, pwd may be null.
185 * SSS
186 ***************************************************************************/
188 static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
190 const char *guest_account = lp_guestaccount();
191 GROUP_MAP map;
192 BOOL ret;
194 if (!account_data || !pwd) {
195 return NT_STATUS_INVALID_PARAMETER;
198 /* this is a hack this thing should not be set
199 this way --SSS */
200 if (!(guest_account && *guest_account)) {
201 DEBUG(1, ("NULL guest account!?!?\n"));
202 return NT_STATUS_UNSUCCESSFUL;
203 } else {
204 /* Ensure this *must* be set right */
205 if (strcmp(pwd->pw_name, guest_account) == 0) {
206 if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
207 return NT_STATUS_UNSUCCESSFUL;
209 if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) {
210 return NT_STATUS_UNSUCCESSFUL;
212 return NT_STATUS_OK;
216 if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
217 DEBUG(0,("Can't set User SID from RID!\n"));
218 return NT_STATUS_INVALID_PARAMETER;
221 /* call the mapping code here */
222 become_root();
223 ret = pdb_getgrgid(&map, pwd->pw_gid);
224 unbecome_root();
226 if( ret ) {
227 if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
228 DEBUG(0,("Can't set Group SID!\n"));
229 return NT_STATUS_INVALID_PARAMETER;
232 else {
233 if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
234 DEBUG(0,("Can't set Group SID\n"));
235 return NT_STATUS_INVALID_PARAMETER;
239 return NT_STATUS_OK;
242 /*************************************************************
243 Initialises a struct sam_passwd with sane values.
244 ************************************************************/
246 NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
248 NTSTATUS ret;
250 if (!pwd) {
251 return NT_STATUS_UNSUCCESSFUL;
254 pdb_fill_default_sam(sam_account);
256 pdb_set_username(sam_account, pwd->pw_name, PDB_SET);
257 pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);
259 pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);
261 pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);
263 /* When we get a proper uid -> SID and SID -> uid allocation
264 mechinism, we should call it here.
266 We can't just set this to 0 or allow it only to be filled
267 in when added to the backend, because the user's SID
268 may already be in security descriptors etc.
270 -- abartlet 11-May-02
273 ret = pdb_set_sam_sids(sam_account, pwd);
274 if (!NT_STATUS_IS_OK(ret)) return ret;
276 /* check if this is a user account or a machine account */
277 if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
279 pdb_set_profile_path(sam_account,
280 talloc_sub_specified((sam_account)->mem_ctx,
281 lp_logon_path(),
282 pwd->pw_name, global_myname(),
283 pwd->pw_uid, pwd->pw_gid),
284 PDB_DEFAULT);
286 pdb_set_homedir(sam_account,
287 talloc_sub_specified((sam_account)->mem_ctx,
288 lp_logon_home(),
289 pwd->pw_name, global_myname(),
290 pwd->pw_uid, pwd->pw_gid),
291 PDB_DEFAULT);
293 pdb_set_dir_drive(sam_account,
294 talloc_sub_specified((sam_account)->mem_ctx,
295 lp_logon_drive(),
296 pwd->pw_name, global_myname(),
297 pwd->pw_uid, pwd->pw_gid),
298 PDB_DEFAULT);
300 pdb_set_logon_script(sam_account,
301 talloc_sub_specified((sam_account)->mem_ctx,
302 lp_logon_script(),
303 pwd->pw_name, global_myname(),
304 pwd->pw_uid, pwd->pw_gid),
305 PDB_DEFAULT);
306 if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {
307 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
308 return NT_STATUS_UNSUCCESSFUL;
310 } else {
311 if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {
312 DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
313 return NT_STATUS_UNSUCCESSFUL;
316 return NT_STATUS_OK;
320 /*************************************************************
321 Initialises a struct sam_passwd with sane values.
322 ************************************************************/
324 NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
326 NTSTATUS nt_status;
328 if (!pwd) {
329 new_sam_acct = NULL;
330 return NT_STATUS_INVALID_PARAMETER;
333 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
334 new_sam_acct = NULL;
335 return nt_status;
338 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
339 pdb_free_sam(new_sam_acct);
340 new_sam_acct = NULL;
341 return nt_status;
344 return NT_STATUS_OK;
348 /*************************************************************
349 Initialises a SAM_ACCOUNT ready to add a new account, based
350 on the UNIX user. Pass in a RID if you have one
351 ************************************************************/
353 NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,
354 uint32 rid)
356 NTSTATUS nt_status = NT_STATUS_NO_MEMORY;
357 struct passwd *pwd;
358 BOOL ret;
360 pwd = Get_Pwnam(username);
362 if (!pwd)
363 return NT_STATUS_NO_SUCH_USER;
365 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
366 *new_sam_acct = NULL;
367 return nt_status;
370 /* see if we need to generate a new rid using the 2.2 algorithm */
371 if ( rid == 0 && lp_enable_rid_algorithm() ) {
372 DEBUG(10,("pdb_init_sam_new: no RID specified. Generating one via old algorithm\n"));
373 rid = algorithmic_pdb_uid_to_user_rid(pwd->pw_uid);
376 /* set the new SID */
378 ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );
380 return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);
385 * Free the contets of the SAM_ACCOUNT, but not the structure.
387 * Also wipes the LM and NT hashes and plaintext password from
388 * memory.
390 * @param user SAM_ACCOUNT to free members of.
393 static void pdb_free_sam_contents(SAM_ACCOUNT *user)
396 /* Kill off sensitive data. Free()ed by the
397 talloc mechinism */
399 data_blob_clear_free(&(user->private.lm_pw));
400 data_blob_clear_free(&(user->private.nt_pw));
401 if (user->private.plaintext_pw!=NULL)
402 memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw));
404 if (user->private.backend_private_data && user->private.backend_private_data_free_fn) {
405 user->private.backend_private_data_free_fn(&user->private.backend_private_data);
410 /************************************************************
411 Reset the SAM_ACCOUNT and free the NT/LM hashes.
412 ***********************************************************/
414 NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
416 if (user == NULL) {
417 DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
418 #if 0
419 smb_panic("NULL pointer passed to pdb_free_sam\n");
420 #endif
421 return NT_STATUS_UNSUCCESSFUL;
424 pdb_free_sam_contents(user);
426 pdb_fill_default_sam(user);
428 return NT_STATUS_OK;
432 /************************************************************
433 Free the SAM_ACCOUNT and the member pointers.
434 ***********************************************************/
436 NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
438 if (*user == NULL) {
439 DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
440 #if 0
441 smb_panic("NULL pointer passed to pdb_free_sam\n");
442 #endif
443 return NT_STATUS_UNSUCCESSFUL;
446 pdb_free_sam_contents(*user);
448 if ((*user)->free_fn) {
449 (*user)->free_fn(user);
452 return NT_STATUS_OK;
455 /**********************************************************
456 Encode the account control bits into a string.
457 length = length of string to encode into (including terminating
458 null). length *MUST BE MORE THAN 2* !
459 **********************************************************/
461 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
463 static fstring acct_str;
465 size_t i = 0;
467 SMB_ASSERT(length <= sizeof(acct_str));
469 acct_str[i++] = '[';
471 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
472 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
473 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
474 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
475 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
476 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
477 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
478 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
479 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
480 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
481 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
483 for ( ; i < length - 2 ; i++ )
484 acct_str[i] = ' ';
486 i = length - 2;
487 acct_str[i++] = ']';
488 acct_str[i++] = '\0';
490 return acct_str;
493 /**********************************************************
494 Decode the account control bits from a string.
495 **********************************************************/
497 uint16 pdb_decode_acct_ctrl(const char *p)
499 uint16 acct_ctrl = 0;
500 BOOL finished = False;
503 * Check if the account type bits have been encoded after the
504 * NT password (in the form [NDHTUWSLXI]).
507 if (*p != '[')
508 return 0;
510 for (p++; *p && !finished; p++) {
511 switch (*p) {
512 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
513 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
514 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
515 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
516 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
517 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
518 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
519 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
520 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
521 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
522 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
523 case ' ': { break; }
524 case ':':
525 case '\n':
526 case '\0':
527 case ']':
528 default: { finished = True; }
532 return acct_ctrl;
535 /*************************************************************
536 Routine to set 32 hex password characters from a 16 byte array.
537 **************************************************************/
539 void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
541 if (pwd != NULL) {
542 int i;
543 for (i = 0; i < 16; i++)
544 slprintf(&p[i*2], 3, "%02X", pwd[i]);
545 } else {
546 if (acct_ctrl & ACB_PWNOTREQ)
547 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
548 else
549 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
553 /*************************************************************
554 Routine to get the 32 hex characters and turn them
555 into a 16 byte array.
556 **************************************************************/
558 BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
560 int i;
561 unsigned char lonybble, hinybble;
562 const char *hexchars = "0123456789ABCDEF";
563 char *p1, *p2;
565 if (!p)
566 return (False);
568 for (i = 0; i < 32; i += 2) {
569 hinybble = toupper(p[i]);
570 lonybble = toupper(p[i + 1]);
572 p1 = strchr(hexchars, hinybble);
573 p2 = strchr(hexchars, lonybble);
575 if (!p1 || !p2)
576 return (False);
578 hinybble = PTR_DIFF(p1, hexchars);
579 lonybble = PTR_DIFF(p2, hexchars);
581 pwd[i / 2] = (hinybble << 4) | lonybble;
583 return (True);
586 /*************************************************************
587 Routine to set 42 hex hours characters from a 21 byte array.
588 **************************************************************/
590 void pdb_sethexhours(char *p, const unsigned char *hours)
592 if (hours != NULL) {
593 int i;
594 for (i = 0; i < 21; i++) {
595 slprintf(&p[i*2], 3, "%02X", hours[i]);
597 } else {
598 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
602 /*************************************************************
603 Routine to get the 42 hex characters and turn them
604 into a 21 byte array.
605 **************************************************************/
607 BOOL pdb_gethexhours(const char *p, unsigned char *hours)
609 int i;
610 unsigned char lonybble, hinybble;
611 const char *hexchars = "0123456789ABCDEF";
612 char *p1, *p2;
614 if (!p) {
615 return (False);
618 for (i = 0; i < 42; i += 2) {
619 hinybble = toupper(p[i]);
620 lonybble = toupper(p[i + 1]);
622 p1 = strchr(hexchars, hinybble);
623 p2 = strchr(hexchars, lonybble);
625 if (!p1 || !p2) {
626 return (False);
629 hinybble = PTR_DIFF(p1, hexchars);
630 lonybble = PTR_DIFF(p2, hexchars);
632 hours[i / 2] = (hinybble << 4) | lonybble;
634 return (True);
637 int algorithmic_rid_base(void)
639 static int rid_offset = 0;
641 if (rid_offset != 0)
642 return rid_offset;
644 rid_offset = lp_algorithmic_rid_base();
646 if (rid_offset < BASE_RID) {
647 /* Try to prevent admin foot-shooting, we can't put algorithmic
648 rids below 1000, that's the 'well known RIDs' on NT */
649 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
650 rid_offset = BASE_RID;
652 if (rid_offset & 1) {
653 DEBUG(0, ("algorithmic rid base must be even\n"));
654 rid_offset += 1;
656 return rid_offset;
659 /*******************************************************************
660 Converts NT user RID to a UNIX uid.
661 ********************************************************************/
663 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
665 int rid_offset = algorithmic_rid_base();
666 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
669 /*******************************************************************
670 converts UNIX uid to an NT User RID.
671 ********************************************************************/
673 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
675 int rid_offset = algorithmic_rid_base();
676 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
679 /*******************************************************************
680 Converts NT group RID to a UNIX gid.
681 ********************************************************************/
683 gid_t pdb_group_rid_to_gid(uint32 group_rid)
685 int rid_offset = algorithmic_rid_base();
686 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
689 /*******************************************************************
690 converts NT Group RID to a UNIX uid.
692 warning: you must not call that function only
693 you must do a call to the group mapping first.
694 there is not anymore a direct link between the gid and the rid.
695 ********************************************************************/
697 uint32 pdb_gid_to_group_rid(gid_t gid)
699 int rid_offset = algorithmic_rid_base();
700 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
703 /*******************************************************************
704 Decides if a RID is a well known RID.
705 ********************************************************************/
707 static BOOL pdb_rid_is_well_known(uint32 rid)
709 /* Not using rid_offset here, because this is the actual
710 NT fixed value (1000) */
712 return (rid < BASE_RID);
715 /*******************************************************************
716 Decides if a RID is a user or group RID.
717 ********************************************************************/
719 BOOL algorithmic_pdb_rid_is_user(uint32 rid)
721 if(pdb_rid_is_well_known(rid)) {
723 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
724 * and DOMAIN_USER_RID_GUEST.
726 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
727 return True;
728 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
729 return True;
731 return False;
734 /*******************************************************************
735 Convert a rid into a name. Used in the lookup SID rpc.
736 ********************************************************************/
738 BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
740 uint32 rid;
741 SAM_ACCOUNT *sam_account = NULL;
742 GROUP_MAP map;
743 BOOL ret;
745 if (sid_equal(get_global_sam_sid(), sid)) {
746 *psid_name_use = SID_NAME_DOMAIN;
747 fstrcpy(name, "");
748 DEBUG(5,("local_lookup_sid: SID is our own domain-sid: %s.\n",
749 sid_string_static(sid)));
750 return True;
753 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
754 DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
755 sid_string_static(&map.sid)));
756 return False;
758 *psid_name_use = SID_NAME_UNKNOWN;
760 DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
763 /* see if the passdb can help us with the name of the user */
764 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
765 return False;
768 /* BEING ROOT BLLOCK */
769 become_root();
770 if (pdb_getsampwsid(sam_account, sid)) {
771 unbecome_root(); /* -----> EXIT BECOME_ROOT() */
772 fstrcpy(name, pdb_get_username(sam_account));
773 *psid_name_use = SID_NAME_USER;
775 pdb_free_sam(&sam_account);
777 return True;
779 pdb_free_sam(&sam_account);
781 ret = pdb_getgrsid(&map, *sid);
782 unbecome_root();
783 /* END BECOME_ROOT BLOCK */
785 if ( ret ) {
786 if (map.gid!=(gid_t)-1) {
787 DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
788 } else {
789 DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
792 fstrcpy(name, map.nt_name);
793 *psid_name_use = map.sid_name_use;
794 return True;
797 if (algorithmic_pdb_rid_is_user(rid)) {
798 uid_t uid;
799 struct passwd *pw = NULL;
801 DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
803 uid = algorithmic_pdb_user_rid_to_uid(rid);
804 pw = sys_getpwuid( uid );
806 DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
807 pw ? "succeeded" : "failed" ));
809 if ( !pw )
810 fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
811 else
812 fstrcpy( name, pw->pw_name );
814 DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
815 (unsigned int)rid ));
817 *psid_name_use = SID_NAME_USER;
819 return ( pw != NULL );
820 } else {
821 gid_t gid;
822 struct group *gr;
824 DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
826 gid = pdb_group_rid_to_gid(rid);
827 gr = getgrgid(gid);
829 *psid_name_use = SID_NAME_ALIAS;
831 DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
832 gr ? "succeeded" : "failed" ));
834 if( !gr )
835 fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
836 else
837 fstrcpy( name, gr->gr_name);
839 DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
840 (unsigned int)rid ));
842 /* assume algorithmic groups are domain global groups */
844 *psid_name_use = SID_NAME_DOM_GRP;
846 return ( gr != NULL );
850 /*******************************************************************
851 Convert a name into a SID. Used in the lookup name rpc.
852 ********************************************************************/
854 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
856 DOM_SID local_sid;
857 DOM_SID sid;
858 fstring user;
859 SAM_ACCOUNT *sam_account = NULL;
860 struct group *grp;
861 GROUP_MAP map;
863 *psid_name_use = SID_NAME_UNKNOWN;
866 * user may be quoted a const string, and map_username and
867 * friends can modify it. Make a modifiable copy. JRA.
870 fstrcpy(user, c_user);
872 sid_copy(&local_sid, get_global_sam_sid());
874 if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
875 fstring sid_str;
876 sid_copy( psid, &sid);
877 sid_to_string(sid_str, &sid);
878 DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
879 (unsigned int)*psid_name_use ));
880 return True;
883 (void)map_username(user);
885 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
886 return False;
889 /* BEGIN ROOT BLOCK */
891 become_root();
892 if (pdb_getsampwnam(sam_account, user)) {
893 unbecome_root();
894 sid_copy(psid, pdb_get_user_sid(sam_account));
895 *psid_name_use = SID_NAME_USER;
897 pdb_free_sam(&sam_account);
898 return True;
901 pdb_free_sam(&sam_account);
904 * Maybe it was a group ?
907 /* check if it's a mapped group */
908 if (pdb_getgrnam(&map, user)) {
909 /* yes it's a mapped group */
910 sid_copy(&local_sid, &map.sid);
911 *psid_name_use = map.sid_name_use;
912 } else {
913 /* it's not a mapped group */
914 grp = getgrnam(user);
915 if(!grp) {
916 unbecome_root(); /* ---> exit form block */
917 return False;
921 *check if it's mapped, if it is reply it doesn't exist
923 * that's to prevent this case:
925 * unix group ug is mapped to nt group ng
926 * someone does a lookup on ug
927 * we must not reply as it doesn't "exist" anymore
928 * for NT. For NT only ng exists.
929 * JFM, 30/11/2001
932 if (pdb_getgrgid(&map, grp->gr_gid)){
933 unbecome_root(); /* ---> exit form block */
934 return False;
937 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
938 *psid_name_use = SID_NAME_ALIAS;
940 unbecome_root();
941 /* END ROOT BLOCK */
943 sid_copy( psid, &local_sid);
945 return True;
948 /*************************************************************
949 Change a password entry in the local smbpasswd file.
950 *************************************************************/
952 BOOL local_password_change(const char *user_name, int local_flags,
953 const char *new_passwd,
954 char *err_str, size_t err_str_len,
955 char *msg_str, size_t msg_str_len)
957 SAM_ACCOUNT *sam_pass=NULL;
958 uint16 other_acb;
960 *err_str = '\0';
961 *msg_str = '\0';
963 /* Get the smb passwd entry for this user */
964 pdb_init_sam(&sam_pass);
966 become_root();
967 if(!pdb_getsampwnam(sam_pass, user_name)) {
968 unbecome_root();
969 pdb_free_sam(&sam_pass);
971 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
972 /* Might not exist in /etc/passwd. Use rid algorithm here */
973 if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
974 slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s. Does this user exist in the UNIX password database ?\n", user_name);
975 return False;
977 } else {
978 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
979 return False;
981 } else {
982 unbecome_root();
983 /* the entry already existed */
984 local_flags &= ~LOCAL_ADD_USER;
987 /* the 'other' acb bits not being changed here */
988 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
989 if (local_flags & LOCAL_TRUST_ACCOUNT) {
990 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
991 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
992 pdb_free_sam(&sam_pass);
993 return False;
995 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
996 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
997 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
998 pdb_free_sam(&sam_pass);
999 return False;
1001 } else {
1002 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
1003 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1004 pdb_free_sam(&sam_pass);
1005 return False;
1010 * We are root - just write the new password
1011 * and the valid last change time.
1014 if (local_flags & LOCAL_DISABLE_USER) {
1015 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1016 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1017 pdb_free_sam(&sam_pass);
1018 return False;
1020 } else if (local_flags & LOCAL_ENABLE_USER) {
1021 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1022 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1023 pdb_free_sam(&sam_pass);
1024 return False;
1028 if (local_flags & LOCAL_SET_NO_PASSWORD) {
1029 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1030 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1031 pdb_free_sam(&sam_pass);
1032 return False;
1034 } else if (local_flags & LOCAL_SET_PASSWORD) {
1036 * If we're dealing with setting a completely empty user account
1037 * ie. One with a password of 'XXXX', but not set disabled (like
1038 * an account created from scratch) then if the old password was
1039 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1040 * We remove that as we're giving this user their first password
1041 * and the decision hasn't really been made to disable them (ie.
1042 * don't create them disabled). JRA.
1044 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1045 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1046 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1047 pdb_free_sam(&sam_pass);
1048 return False;
1051 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1052 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1053 pdb_free_sam(&sam_pass);
1054 return False;
1057 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1058 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1059 pdb_free_sam(&sam_pass);
1060 return False;
1064 if (local_flags & LOCAL_ADD_USER) {
1065 if (pdb_add_sam_account(sam_pass)) {
1066 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1067 pdb_free_sam(&sam_pass);
1068 return True;
1069 } else {
1070 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1071 pdb_free_sam(&sam_pass);
1072 return False;
1074 } else if (local_flags & LOCAL_DELETE_USER) {
1075 if (!pdb_delete_sam_account(sam_pass)) {
1076 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1077 pdb_free_sam(&sam_pass);
1078 return False;
1080 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1081 } else {
1082 if(!pdb_update_sam_account(sam_pass)) {
1083 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1084 pdb_free_sam(&sam_pass);
1085 return False;
1087 if(local_flags & LOCAL_DISABLE_USER)
1088 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1089 else if (local_flags & LOCAL_ENABLE_USER)
1090 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1091 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1092 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1095 pdb_free_sam(&sam_pass);
1096 return True;
1099 /****************************************************************************
1100 Convert a uid to SID - algorithmic.
1101 ****************************************************************************/
1103 DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1105 if ( !lp_enable_rid_algorithm() )
1106 return NULL;
1108 DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1109 sid_copy( psid, get_global_sam_sid() );
1110 sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
1111 DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
1112 (unsigned int)uid, sid_string_static(psid) ));
1114 return psid;
1117 /****************************************************************************
1118 Convert a uid to SID - locally.
1119 ****************************************************************************/
1121 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1123 SAM_ACCOUNT *sampw = NULL;
1124 struct passwd *unix_pw;
1125 BOOL ret;
1127 unix_pw = sys_getpwuid( uid );
1129 if ( !unix_pw ) {
1130 DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1131 return algorithmic_uid_to_sid( psid, uid);
1134 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1135 DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1136 return NULL;
1139 become_root();
1140 ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1141 unbecome_root();
1143 if ( ret )
1144 sid_copy( psid, pdb_get_user_sid(sampw) );
1145 else {
1146 DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1147 unix_pw->pw_name, (unsigned long)uid));
1149 return algorithmic_uid_to_sid( psid, uid);
1152 DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
1153 (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1155 return psid;
1158 /****************************************************************************
1159 Convert a SID to uid - locally.
1160 ****************************************************************************/
1162 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1164 SAM_ACCOUNT *sampw = NULL;
1165 struct passwd *unix_pw;
1166 const char *user_name;
1168 *name_type = SID_NAME_UNKNOWN;
1171 * We can only convert to a uid if this is our local
1172 * Domain SID (ie. we are the controling authority).
1174 if (!sid_check_is_in_our_domain(psid) ) {
1175 DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1176 return False;
1179 /* lookup the user account */
1181 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1182 DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1183 return False;
1186 become_root();
1187 if ( !pdb_getsampwsid(sampw, psid) ) {
1188 unbecome_root();
1189 DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1190 sid_string_static(psid)));
1191 return False;
1193 unbecome_root();
1195 user_name = pdb_get_username(sampw);
1197 unix_pw = sys_getpwnam( user_name );
1199 if ( !unix_pw ) {
1200 DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1201 user_name));
1202 pdb_free_sam( &sampw );
1203 return False;
1206 *puid = unix_pw->pw_uid;
1208 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1209 (unsigned int)*puid, user_name ));
1211 *name_type = SID_NAME_USER;
1213 return True;
1216 /****************************************************************************
1217 Convert a gid to SID - algorithmic.
1218 ****************************************************************************/
1220 DOM_SID *algorithmic_gid_to_sid(DOM_SID *psid, uid_t gid)
1222 if ( !lp_enable_rid_algorithm() )
1223 return NULL;
1225 DEBUG(8,("algorithmic_gid_to_sid: falling back to RID algorithm\n"));
1226 sid_copy( psid, get_global_sam_sid() );
1227 sid_append_rid( psid, pdb_gid_to_group_rid(gid) );
1228 DEBUG(10,("algorithmic_gid_to_sid: gid (%d) -> SID %s.\n",
1229 (unsigned int)gid, sid_string_static(psid) ));
1231 return psid;
1234 /****************************************************************************
1235 Convert a gid to SID - locally.
1236 ****************************************************************************/
1238 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1240 GROUP_MAP group;
1241 BOOL ret;
1243 /* we don't need to disable winbindd since the gid is stored in
1244 the GROUP_MAP object */
1246 /* done as root since ldap backend requires root to open a connection */
1248 become_root();
1249 ret = pdb_getgrgid( &group, gid );
1250 unbecome_root();
1252 if ( !ret ) {
1254 /* algorithmic to rid mapping if enabled */
1256 if ( lp_enable_rid_algorithm() ) {
1258 DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1259 (unsigned int)gid, sid_string_static(psid)));
1261 return algorithmic_gid_to_sid(psid, gid);
1263 else
1264 return NULL;
1267 sid_copy( psid, &group.sid );
1269 DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
1270 (unsigned int)gid, sid_string_static(psid)));
1272 return psid;
1275 /****************************************************************************
1276 Convert a SID to gid - locally.
1277 ****************************************************************************/
1279 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1281 uint32 rid;
1282 GROUP_MAP group;
1283 BOOL ret;
1285 *name_type = SID_NAME_UNKNOWN;
1287 /* This call can enumerate group mappings for foreign sids as well.
1288 So don't check for a match against our domain SID */
1290 /* we don't need to disable winbindd since the gid is stored in
1291 the GROUP_MAP object */
1293 become_root();
1294 ret = pdb_getgrsid(&group, *psid);
1295 unbecome_root();
1297 if ( !ret ) {
1299 /* Fallback to algorithmic rid mapping if enabled */
1301 if ( lp_enable_rid_algorithm() ) {
1303 if (!sid_check_is_in_our_domain(psid) ) {
1304 DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1305 return False;
1308 if (!sid_peek_rid(psid, &rid)) {
1309 DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1310 return False;
1313 DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1315 if (algorithmic_pdb_rid_is_user(rid)) {
1316 DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1317 return False;
1318 } else {
1319 *pgid = pdb_group_rid_to_gid(rid);
1320 DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1321 return True;
1325 return False;
1328 *pgid = group.gid;
1329 *name_type = group.sid_name_use;
1331 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1332 (unsigned int)*pgid));
1334 return True;
1337 /**********************************************************************
1338 Marshall/unmarshall SAM_ACCOUNT structs.
1339 *********************************************************************/
1341 #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1342 #define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1343 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1345 /**********************************************************************
1346 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1347 *********************************************************************/
1349 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1351 return(init_sam_from_buffer_v2(sampass, buf, buflen));
1354 /**********************************************************************
1355 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1356 *********************************************************************/
1358 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1360 return(init_buffer_from_sam_v2(buf, sampass, size_only));
1364 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1367 /* times are stored as 32bit integer
1368 take care on system with 64bit wide time_t
1369 --SSS */
1370 uint32 logon_time,
1371 logoff_time,
1372 kickoff_time,
1373 pass_last_set_time,
1374 pass_can_change_time,
1375 pass_must_change_time;
1376 char *username;
1377 char *domain;
1378 char *nt_username;
1379 char *dir_drive;
1380 char *unknown_str;
1381 char *munged_dial;
1382 char *fullname;
1383 char *homedir;
1384 char *logon_script;
1385 char *profile_path;
1386 char *acct_desc;
1387 char *workstations;
1388 uint32 username_len, domain_len, nt_username_len,
1389 dir_drive_len, unknown_str_len, munged_dial_len,
1390 fullname_len, homedir_len, logon_script_len,
1391 profile_path_len, acct_desc_len, workstations_len;
1393 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1394 uint16 acct_ctrl, logon_divs;
1395 uint16 bad_password_count, logon_count;
1396 uint8 *hours;
1397 uint8 *lm_pw_ptr, *nt_pw_ptr;
1398 uint32 len = 0;
1399 uint32 lm_pw_len, nt_pw_len, hourslen;
1400 BOOL ret = True;
1402 if(sampass == NULL || buf == NULL) {
1403 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1404 return False;
1407 /* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1409 /* unpack the buffer into variables */
1410 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1411 &logon_time, /* d */
1412 &logoff_time, /* d */
1413 &kickoff_time, /* d */
1414 &pass_last_set_time, /* d */
1415 &pass_can_change_time, /* d */
1416 &pass_must_change_time, /* d */
1417 &username_len, &username, /* B */
1418 &domain_len, &domain, /* B */
1419 &nt_username_len, &nt_username, /* B */
1420 &fullname_len, &fullname, /* B */
1421 &homedir_len, &homedir, /* B */
1422 &dir_drive_len, &dir_drive, /* B */
1423 &logon_script_len, &logon_script, /* B */
1424 &profile_path_len, &profile_path, /* B */
1425 &acct_desc_len, &acct_desc, /* B */
1426 &workstations_len, &workstations, /* B */
1427 &unknown_str_len, &unknown_str, /* B */
1428 &munged_dial_len, &munged_dial, /* B */
1429 &user_rid, /* d */
1430 &group_rid, /* d */
1431 &lm_pw_len, &lm_pw_ptr, /* B */
1432 &nt_pw_len, &nt_pw_ptr, /* B */
1433 &acct_ctrl, /* w */
1434 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1435 &logon_divs, /* w */
1436 &hours_len, /* d */
1437 &hourslen, &hours, /* B */
1438 &bad_password_count, /* w */
1439 &logon_count, /* w */
1440 &unknown_6); /* d */
1442 if (len == (uint32) -1) {
1443 ret = False;
1444 goto done;
1447 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1448 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1449 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1450 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1451 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1452 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1454 pdb_set_username(sampass, username, PDB_SET);
1455 pdb_set_domain(sampass, domain, PDB_SET);
1456 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1457 pdb_set_fullname(sampass, fullname, PDB_SET);
1459 if (homedir) {
1460 pdb_set_homedir(sampass, homedir, PDB_SET);
1462 else {
1463 pdb_set_homedir(sampass,
1464 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1465 PDB_DEFAULT);
1468 if (dir_drive)
1469 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1470 else {
1471 pdb_set_dir_drive(sampass,
1472 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1473 PDB_DEFAULT);
1476 if (logon_script)
1477 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1478 else {
1479 pdb_set_logon_script(sampass,
1480 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1481 PDB_DEFAULT);
1484 if (profile_path) {
1485 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1486 } else {
1487 pdb_set_profile_path(sampass,
1488 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1489 PDB_DEFAULT);
1492 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1493 pdb_set_workstations(sampass, workstations, PDB_SET);
1494 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1496 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1497 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1498 ret = False;
1499 goto done;
1503 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1504 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1505 ret = False;
1506 goto done;
1510 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1511 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1512 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1513 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1514 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1515 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1516 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1517 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1518 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1519 pdb_set_hours(sampass, hours, PDB_SET);
1521 done:
1523 SAFE_FREE(username);
1524 SAFE_FREE(domain);
1525 SAFE_FREE(nt_username);
1526 SAFE_FREE(fullname);
1527 SAFE_FREE(homedir);
1528 SAFE_FREE(dir_drive);
1529 SAFE_FREE(logon_script);
1530 SAFE_FREE(profile_path);
1531 SAFE_FREE(acct_desc);
1532 SAFE_FREE(workstations);
1533 SAFE_FREE(munged_dial);
1534 SAFE_FREE(unknown_str);
1535 SAFE_FREE(lm_pw_ptr);
1536 SAFE_FREE(nt_pw_ptr);
1537 SAFE_FREE(hours);
1539 return ret;
1542 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1545 /* times are stored as 32bit integer
1546 take care on system with 64bit wide time_t
1547 --SSS */
1548 uint32 logon_time,
1549 logoff_time,
1550 kickoff_time,
1551 bad_password_time,
1552 pass_last_set_time,
1553 pass_can_change_time,
1554 pass_must_change_time;
1555 char *username;
1556 char *domain;
1557 char *nt_username;
1558 char *dir_drive;
1559 char *unknown_str;
1560 char *munged_dial;
1561 char *fullname;
1562 char *homedir;
1563 char *logon_script;
1564 char *profile_path;
1565 char *acct_desc;
1566 char *workstations;
1567 uint32 username_len, domain_len, nt_username_len,
1568 dir_drive_len, unknown_str_len, munged_dial_len,
1569 fullname_len, homedir_len, logon_script_len,
1570 profile_path_len, acct_desc_len, workstations_len;
1572 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1573 uint16 acct_ctrl, logon_divs;
1574 uint16 bad_password_count, logon_count;
1575 uint8 *hours;
1576 uint8 *lm_pw_ptr, *nt_pw_ptr;
1577 uint32 len = 0;
1578 uint32 lm_pw_len, nt_pw_len, hourslen;
1579 BOOL ret = True;
1581 if(sampass == NULL || buf == NULL) {
1582 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1583 return False;
1586 /* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1588 /* unpack the buffer into variables */
1589 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1590 &logon_time, /* d */
1591 &logoff_time, /* d */
1592 &kickoff_time, /* d */
1593 /* Change from V0 is addition of bad_password_time field. */
1594 &bad_password_time, /* d */
1595 &pass_last_set_time, /* d */
1596 &pass_can_change_time, /* d */
1597 &pass_must_change_time, /* d */
1598 &username_len, &username, /* B */
1599 &domain_len, &domain, /* B */
1600 &nt_username_len, &nt_username, /* B */
1601 &fullname_len, &fullname, /* B */
1602 &homedir_len, &homedir, /* B */
1603 &dir_drive_len, &dir_drive, /* B */
1604 &logon_script_len, &logon_script, /* B */
1605 &profile_path_len, &profile_path, /* B */
1606 &acct_desc_len, &acct_desc, /* B */
1607 &workstations_len, &workstations, /* B */
1608 &unknown_str_len, &unknown_str, /* B */
1609 &munged_dial_len, &munged_dial, /* B */
1610 &user_rid, /* d */
1611 &group_rid, /* d */
1612 &lm_pw_len, &lm_pw_ptr, /* B */
1613 &nt_pw_len, &nt_pw_ptr, /* B */
1614 &acct_ctrl, /* w */
1615 &remove_me, /* d */
1616 &logon_divs, /* w */
1617 &hours_len, /* d */
1618 &hourslen, &hours, /* B */
1619 &bad_password_count, /* w */
1620 &logon_count, /* w */
1621 &unknown_6); /* d */
1623 if (len == (uint32) -1) {
1624 ret = False;
1625 goto done;
1628 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1629 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1630 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1632 /* Change from V0 is addition of bad_password_time field. */
1633 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1634 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1635 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1636 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1638 pdb_set_username(sampass, username, PDB_SET);
1639 pdb_set_domain(sampass, domain, PDB_SET);
1640 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1641 pdb_set_fullname(sampass, fullname, PDB_SET);
1643 if (homedir) {
1644 pdb_set_homedir(sampass, homedir, PDB_SET);
1646 else {
1647 pdb_set_homedir(sampass,
1648 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1649 PDB_DEFAULT);
1652 if (dir_drive)
1653 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1654 else {
1655 pdb_set_dir_drive(sampass,
1656 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1657 PDB_DEFAULT);
1660 if (logon_script)
1661 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1662 else {
1663 pdb_set_logon_script(sampass,
1664 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1665 PDB_DEFAULT);
1668 if (profile_path) {
1669 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1670 } else {
1671 pdb_set_profile_path(sampass,
1672 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1673 PDB_DEFAULT);
1676 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1677 pdb_set_workstations(sampass, workstations, PDB_SET);
1678 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1680 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1681 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1682 ret = False;
1683 goto done;
1687 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1688 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1689 ret = False;
1690 goto done;
1694 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1696 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1697 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1698 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1699 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1700 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1701 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1702 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1703 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1704 pdb_set_hours(sampass, hours, PDB_SET);
1706 done:
1708 SAFE_FREE(username);
1709 SAFE_FREE(domain);
1710 SAFE_FREE(nt_username);
1711 SAFE_FREE(fullname);
1712 SAFE_FREE(homedir);
1713 SAFE_FREE(dir_drive);
1714 SAFE_FREE(logon_script);
1715 SAFE_FREE(profile_path);
1716 SAFE_FREE(acct_desc);
1717 SAFE_FREE(workstations);
1718 SAFE_FREE(munged_dial);
1719 SAFE_FREE(unknown_str);
1720 SAFE_FREE(lm_pw_ptr);
1721 SAFE_FREE(nt_pw_ptr);
1722 SAFE_FREE(hours);
1724 return ret;
1728 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1731 /* times are stored as 32bit integer
1732 take care on system with 64bit wide time_t
1733 --SSS */
1734 uint32 logon_time,
1735 logoff_time,
1736 kickoff_time,
1737 bad_password_time,
1738 pass_last_set_time,
1739 pass_can_change_time,
1740 pass_must_change_time;
1741 char *username;
1742 char *domain;
1743 char *nt_username;
1744 char *dir_drive;
1745 char *unknown_str;
1746 char *munged_dial;
1747 char *fullname;
1748 char *homedir;
1749 char *logon_script;
1750 char *profile_path;
1751 char *acct_desc;
1752 char *workstations;
1753 uint32 username_len, domain_len, nt_username_len,
1754 dir_drive_len, unknown_str_len, munged_dial_len,
1755 fullname_len, homedir_len, logon_script_len,
1756 profile_path_len, acct_desc_len, workstations_len;
1758 uint32 user_rid, group_rid, hours_len, unknown_6;
1759 uint16 acct_ctrl, logon_divs;
1760 uint16 bad_password_count, logon_count;
1761 uint8 *hours;
1762 uint8 *lm_pw_ptr, *nt_pw_ptr, *nt_pw_hist_ptr;
1763 uint32 len = 0;
1764 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1765 uint32 pwHistLen = 0;
1766 BOOL ret = True;
1767 fstring tmpstring;
1769 if(sampass == NULL || buf == NULL) {
1770 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1771 return False;
1774 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1776 /* unpack the buffer into variables */
1777 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1778 &logon_time, /* d */
1779 &logoff_time, /* d */
1780 &kickoff_time, /* d */
1781 &bad_password_time, /* d */
1782 &pass_last_set_time, /* d */
1783 &pass_can_change_time, /* d */
1784 &pass_must_change_time, /* d */
1785 &username_len, &username, /* B */
1786 &domain_len, &domain, /* B */
1787 &nt_username_len, &nt_username, /* B */
1788 &fullname_len, &fullname, /* B */
1789 &homedir_len, &homedir, /* B */
1790 &dir_drive_len, &dir_drive, /* B */
1791 &logon_script_len, &logon_script, /* B */
1792 &profile_path_len, &profile_path, /* B */
1793 &acct_desc_len, &acct_desc, /* B */
1794 &workstations_len, &workstations, /* B */
1795 &unknown_str_len, &unknown_str, /* B */
1796 &munged_dial_len, &munged_dial, /* B */
1797 &user_rid, /* d */
1798 &group_rid, /* d */
1799 &lm_pw_len, &lm_pw_ptr, /* B */
1800 &nt_pw_len, &nt_pw_ptr, /* B */
1801 /* Change from V1 is addition of password history field. */
1802 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1803 &acct_ctrl, /* w */
1804 /* Also "remove_me" field was removed. */
1805 &logon_divs, /* w */
1806 &hours_len, /* d */
1807 &hourslen, &hours, /* B */
1808 &bad_password_count, /* w */
1809 &logon_count, /* w */
1810 &unknown_6); /* d */
1812 if (len == (uint32) -1) {
1813 ret = False;
1814 goto done;
1817 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1818 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1819 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1820 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1821 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1822 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1823 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1825 pdb_set_username(sampass, username, PDB_SET);
1826 pdb_set_domain(sampass, domain, PDB_SET);
1827 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1828 pdb_set_fullname(sampass, fullname, PDB_SET);
1830 if (homedir) {
1831 fstrcpy( tmpstring, homedir );
1832 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1833 pdb_set_homedir(sampass, tmpstring, PDB_SET);
1835 else {
1836 pdb_set_homedir(sampass,
1837 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1838 PDB_DEFAULT);
1841 if (dir_drive)
1842 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1843 else
1844 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1846 if (logon_script) {
1847 fstrcpy( tmpstring, logon_script );
1848 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1849 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1851 else {
1852 pdb_set_logon_script(sampass,
1853 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1854 PDB_DEFAULT);
1857 if (profile_path) {
1858 fstrcpy( tmpstring, profile_path );
1859 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1860 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1862 else {
1863 pdb_set_profile_path(sampass,
1864 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1865 PDB_DEFAULT);
1868 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1869 pdb_set_workstations(sampass, workstations, PDB_SET);
1870 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1872 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1873 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1874 ret = False;
1875 goto done;
1879 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1880 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1881 ret = False;
1882 goto done;
1886 /* Change from V1 is addition of password history field. */
1887 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
1888 if (pwHistLen) {
1889 char *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1890 if (!pw_hist) {
1891 ret = False;
1892 goto done;
1894 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1895 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1896 int i;
1897 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1898 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1899 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1900 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1901 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1902 PW_HISTORY_ENTRY_LEN);
1905 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1906 SAFE_FREE(pw_hist);
1907 ret = False;
1908 goto done;
1910 SAFE_FREE(pw_hist);
1911 } else {
1912 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1915 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1916 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1917 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1918 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1919 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1920 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1921 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1922 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1923 pdb_set_hours(sampass, hours, PDB_SET);
1925 done:
1927 SAFE_FREE(username);
1928 SAFE_FREE(domain);
1929 SAFE_FREE(nt_username);
1930 SAFE_FREE(fullname);
1931 SAFE_FREE(homedir);
1932 SAFE_FREE(dir_drive);
1933 SAFE_FREE(logon_script);
1934 SAFE_FREE(profile_path);
1935 SAFE_FREE(acct_desc);
1936 SAFE_FREE(workstations);
1937 SAFE_FREE(munged_dial);
1938 SAFE_FREE(unknown_str);
1939 SAFE_FREE(lm_pw_ptr);
1940 SAFE_FREE(nt_pw_ptr);
1941 SAFE_FREE(nt_pw_hist_ptr);
1942 SAFE_FREE(hours);
1944 return ret;
1947 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1949 size_t len, buflen;
1951 /* times are stored as 32bit integer
1952 take care on system with 64bit wide time_t
1953 --SSS */
1954 uint32 logon_time,
1955 logoff_time,
1956 kickoff_time,
1957 bad_password_time,
1958 pass_last_set_time,
1959 pass_can_change_time,
1960 pass_must_change_time;
1962 uint32 user_rid, group_rid;
1964 const char *username;
1965 const char *domain;
1966 const char *nt_username;
1967 const char *dir_drive;
1968 const char *unknown_str;
1969 const char *munged_dial;
1970 const char *fullname;
1971 const char *homedir;
1972 const char *logon_script;
1973 const char *profile_path;
1974 const char *acct_desc;
1975 const char *workstations;
1976 uint32 username_len, domain_len, nt_username_len,
1977 dir_drive_len, unknown_str_len, munged_dial_len,
1978 fullname_len, homedir_len, logon_script_len,
1979 profile_path_len, acct_desc_len, workstations_len;
1981 const uint8 *lm_pw;
1982 const uint8 *nt_pw;
1983 const uint8 *nt_pw_hist;
1984 uint32 lm_pw_len = 16;
1985 uint32 nt_pw_len = 16;
1986 uint32 nt_pw_hist_len;
1987 uint32 pwHistLen = 0;
1989 /* do we have a valid SAM_ACCOUNT pointer? */
1990 if (sampass == NULL) {
1991 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
1992 return -1;
1995 *buf = NULL;
1996 buflen = 0;
1998 logon_time = (uint32)pdb_get_logon_time(sampass);
1999 logoff_time = (uint32)pdb_get_logoff_time(sampass);
2000 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
2001 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
2002 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
2003 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
2004 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
2006 user_rid = pdb_get_user_rid(sampass);
2007 group_rid = pdb_get_group_rid(sampass);
2009 username = pdb_get_username(sampass);
2010 if (username) {
2011 username_len = strlen(username) +1;
2012 } else {
2013 username_len = 0;
2016 domain = pdb_get_domain(sampass);
2017 if (domain) {
2018 domain_len = strlen(domain) +1;
2019 } else {
2020 domain_len = 0;
2023 nt_username = pdb_get_nt_username(sampass);
2024 if (nt_username) {
2025 nt_username_len = strlen(nt_username) +1;
2026 } else {
2027 nt_username_len = 0;
2030 fullname = pdb_get_fullname(sampass);
2031 if (fullname) {
2032 fullname_len = strlen(fullname) +1;
2033 } else {
2034 fullname_len = 0;
2038 * Only updates fields which have been set (not defaults from smb.conf)
2041 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
2042 dir_drive = pdb_get_dir_drive(sampass);
2043 } else {
2044 dir_drive = NULL;
2046 if (dir_drive) {
2047 dir_drive_len = strlen(dir_drive) +1;
2048 } else {
2049 dir_drive_len = 0;
2052 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2053 homedir = pdb_get_homedir(sampass);
2054 } else {
2055 homedir = NULL;
2057 if (homedir) {
2058 homedir_len = strlen(homedir) +1;
2059 } else {
2060 homedir_len = 0;
2063 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2064 logon_script = pdb_get_logon_script(sampass);
2065 } else {
2066 logon_script = NULL;
2068 if (logon_script) {
2069 logon_script_len = strlen(logon_script) +1;
2070 } else {
2071 logon_script_len = 0;
2074 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2075 profile_path = pdb_get_profile_path(sampass);
2076 } else {
2077 profile_path = NULL;
2079 if (profile_path) {
2080 profile_path_len = strlen(profile_path) +1;
2081 } else {
2082 profile_path_len = 0;
2085 lm_pw = pdb_get_lanman_passwd(sampass);
2086 if (!lm_pw) {
2087 lm_pw_len = 0;
2090 nt_pw = pdb_get_nt_passwd(sampass);
2091 if (!nt_pw) {
2092 nt_pw_len = 0;
2095 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
2096 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
2097 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2098 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
2099 } else {
2100 nt_pw_hist_len = 0;
2103 acct_desc = pdb_get_acct_desc(sampass);
2104 if (acct_desc) {
2105 acct_desc_len = strlen(acct_desc) +1;
2106 } else {
2107 acct_desc_len = 0;
2110 workstations = pdb_get_workstations(sampass);
2111 if (workstations) {
2112 workstations_len = strlen(workstations) +1;
2113 } else {
2114 workstations_len = 0;
2117 unknown_str = NULL;
2118 unknown_str_len = 0;
2120 munged_dial = pdb_get_munged_dial(sampass);
2121 if (munged_dial) {
2122 munged_dial_len = strlen(munged_dial) +1;
2123 } else {
2124 munged_dial_len = 0;
2127 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2129 /* one time to get the size needed */
2130 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
2131 logon_time, /* d */
2132 logoff_time, /* d */
2133 kickoff_time, /* d */
2134 bad_password_time, /* d */
2135 pass_last_set_time, /* d */
2136 pass_can_change_time, /* d */
2137 pass_must_change_time, /* d */
2138 username_len, username, /* B */
2139 domain_len, domain, /* B */
2140 nt_username_len, nt_username, /* B */
2141 fullname_len, fullname, /* B */
2142 homedir_len, homedir, /* B */
2143 dir_drive_len, dir_drive, /* B */
2144 logon_script_len, logon_script, /* B */
2145 profile_path_len, profile_path, /* B */
2146 acct_desc_len, acct_desc, /* B */
2147 workstations_len, workstations, /* B */
2148 unknown_str_len, unknown_str, /* B */
2149 munged_dial_len, munged_dial, /* B */
2150 user_rid, /* d */
2151 group_rid, /* d */
2152 lm_pw_len, lm_pw, /* B */
2153 nt_pw_len, nt_pw, /* B */
2154 nt_pw_hist_len, nt_pw_hist, /* B */
2155 pdb_get_acct_ctrl(sampass), /* w */
2156 pdb_get_logon_divs(sampass), /* w */
2157 pdb_get_hours_len(sampass), /* d */
2158 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2159 pdb_get_bad_password_count(sampass), /* w */
2160 pdb_get_logon_count(sampass), /* w */
2161 pdb_get_unknown_6(sampass)); /* d */
2163 if (size_only) {
2164 return buflen;
2167 /* malloc the space needed */
2168 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
2169 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2170 return (-1);
2173 /* now for the real call to tdb_pack() */
2174 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
2175 logon_time, /* d */
2176 logoff_time, /* d */
2177 kickoff_time, /* d */
2178 bad_password_time, /* d */
2179 pass_last_set_time, /* d */
2180 pass_can_change_time, /* d */
2181 pass_must_change_time, /* d */
2182 username_len, username, /* B */
2183 domain_len, domain, /* B */
2184 nt_username_len, nt_username, /* B */
2185 fullname_len, fullname, /* B */
2186 homedir_len, homedir, /* B */
2187 dir_drive_len, dir_drive, /* B */
2188 logon_script_len, logon_script, /* B */
2189 profile_path_len, profile_path, /* B */
2190 acct_desc_len, acct_desc, /* B */
2191 workstations_len, workstations, /* B */
2192 unknown_str_len, unknown_str, /* B */
2193 munged_dial_len, munged_dial, /* B */
2194 user_rid, /* d */
2195 group_rid, /* d */
2196 lm_pw_len, lm_pw, /* B */
2197 nt_pw_len, nt_pw, /* B */
2198 nt_pw_hist_len, nt_pw_hist, /* B */
2199 pdb_get_acct_ctrl(sampass), /* w */
2200 pdb_get_logon_divs(sampass), /* w */
2201 pdb_get_hours_len(sampass), /* d */
2202 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2203 pdb_get_bad_password_count(sampass), /* w */
2204 pdb_get_logon_count(sampass), /* w */
2205 pdb_get_unknown_6(sampass)); /* d */
2207 /* check to make sure we got it correct */
2208 if (buflen != len) {
2209 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2210 (unsigned long)buflen, (unsigned long)len));
2211 /* error */
2212 SAFE_FREE (*buf);
2213 return (-1);
2216 return (buflen);
2219 BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
2221 BOOL result;
2222 uint8 *buf;
2223 int len;
2225 if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
2226 return False;
2228 len = init_buffer_from_sam_v2(&buf, src, False);
2230 if (len == -1)
2231 return False;
2233 result = init_sam_from_buffer_v2(*dst, buf, len);
2234 (*dst)->methods = src->methods;
2236 free(buf);
2238 return result;
2241 /**********************************************************************
2242 **********************************************************************/
2244 static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2246 uid_t u_low, u_high;
2247 gid_t g_low, g_high;
2249 if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2250 return False;
2253 *low = (u_low < g_low) ? u_low : g_low;
2254 *high = (u_high < g_high) ? u_high : g_high;
2256 return True;
2259 /******************************************************************
2260 Get the the non-algorithmic RID range if idmap range are defined
2261 ******************************************************************/
2263 BOOL get_free_rid_range(uint32 *low, uint32 *high)
2265 uint32 id_low, id_high;
2267 if (!lp_enable_rid_algorithm()) {
2268 *low = BASE_RID;
2269 *high = (uint32)-1;
2272 if (!get_free_ugid_range(&id_low, &id_high)) {
2273 return False;
2276 *low = algorithmic_pdb_uid_to_user_rid(id_low);
2277 if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2278 *high = (uint32)-1;
2279 } else {
2280 *high = algorithmic_pdb_uid_to_user_rid(id_high);
2283 return True;
2286 /*********************************************************************
2287 Update the bad password count checking the AP_RESET_COUNT_TIME
2288 *********************************************************************/
2290 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2292 time_t LastBadPassword;
2293 uint16 BadPasswordCount;
2294 uint32 resettime;
2296 if (!sampass) return False;
2298 BadPasswordCount = pdb_get_bad_password_count(sampass);
2299 if (!BadPasswordCount) {
2300 DEBUG(9, ("No bad password attempts.\n"));
2301 return True;
2304 if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
2305 DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
2306 return False;
2309 /* First, check if there is a reset time to compare */
2310 if ((resettime == (uint32) -1) || (resettime == 0)) {
2311 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2312 return True;
2315 LastBadPassword = pdb_get_bad_password_time(sampass);
2316 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2317 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2318 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2319 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2320 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2321 if (updated) {
2322 *updated = True;
2326 return True;
2329 /*********************************************************************
2330 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2331 *********************************************************************/
2333 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2335 uint32 duration;
2336 time_t LastBadPassword;
2338 if (!sampass) return False;
2340 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2341 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2342 pdb_get_username(sampass)));
2343 return True;
2346 if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2347 DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
2348 return False;
2351 /* First, check if there is a duration to compare */
2352 if ((duration == (uint32) -1) || (duration == 0)) {
2353 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2354 return True;
2357 LastBadPassword = pdb_get_bad_password_time(sampass);
2358 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2359 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2361 if (LastBadPassword == (time_t)0) {
2362 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2363 bad password time. Leaving locked out.\n",
2364 pdb_get_username(sampass) ));
2365 return True;
2368 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2369 pdb_set_acct_ctrl(sampass,
2370 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2371 PDB_CHANGED);
2372 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2373 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2374 if (updated) {
2375 *updated = True;
2379 return True;
2382 /*********************************************************************
2383 Increment the bad_password_count
2384 *********************************************************************/
2386 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2388 uint32 account_policy_lockout;
2389 BOOL autolock_updated = False, badpw_updated = False;
2391 if (!sampass)
2392 return False;
2394 /* Retrieve the account lockout policy */
2395 if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
2396 &account_policy_lockout)) {
2397 DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
2398 return False;
2401 /* If there is no policy, we don't need to continue checking */
2402 if (!account_policy_lockout) {
2403 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2404 return True;
2407 /* Check if the autolock needs to be cleared */
2408 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2409 return False;
2411 /* Check if the badpw count needs to be reset */
2412 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2413 return False;
2416 Ok, now we can assume that any resetting that needs to be
2417 done has been done, and just get on with incrementing
2418 and autolocking if necessary
2421 pdb_set_bad_password_count(sampass,
2422 pdb_get_bad_password_count(sampass)+1,
2423 PDB_CHANGED);
2424 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2427 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2428 return True;
2430 if (!pdb_set_acct_ctrl(sampass,
2431 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2432 PDB_CHANGED)) {
2433 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2434 return False;
2437 return True;