r1643: syncing all changes from 3.0 and hopefully get 3.0.6rc2 out tomorrow
[Samba.git] / source / passdb / passdb.c
blob2f9742e17da90e9c7021db606f9a2f6770473d7d
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=(SAM_ACCOUNT *)talloc(mem_ctx, sizeof(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, fallback_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 = fallback_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 int algorithmic_rid_base(void)
588 static int rid_offset = 0;
590 if (rid_offset != 0)
591 return rid_offset;
593 rid_offset = lp_algorithmic_rid_base();
595 if (rid_offset < BASE_RID) {
596 /* Try to prevent admin foot-shooting, we can't put algorithmic
597 rids below 1000, that's the 'well known RIDs' on NT */
598 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
599 rid_offset = BASE_RID;
601 if (rid_offset & 1) {
602 DEBUG(0, ("algorithmic rid base must be even\n"));
603 rid_offset += 1;
605 return rid_offset;
608 /*******************************************************************
609 Converts NT user RID to a UNIX uid.
610 ********************************************************************/
612 uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid)
614 int rid_offset = algorithmic_rid_base();
615 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
618 /*******************************************************************
619 converts UNIX uid to an NT User RID.
620 ********************************************************************/
622 uint32 fallback_pdb_uid_to_user_rid(uid_t uid)
624 int rid_offset = algorithmic_rid_base();
625 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
628 /*******************************************************************
629 Converts NT group RID to a UNIX gid.
630 ********************************************************************/
632 gid_t pdb_group_rid_to_gid(uint32 group_rid)
634 int rid_offset = algorithmic_rid_base();
635 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
638 /*******************************************************************
639 converts NT Group RID to a UNIX uid.
641 warning: you must not call that function only
642 you must do a call to the group mapping first.
643 there is not anymore a direct link between the gid and the rid.
644 ********************************************************************/
646 uint32 pdb_gid_to_group_rid(gid_t gid)
648 int rid_offset = algorithmic_rid_base();
649 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
652 /*******************************************************************
653 Decides if a RID is a well known RID.
654 ********************************************************************/
656 static BOOL pdb_rid_is_well_known(uint32 rid)
658 /* Not using rid_offset here, because this is the actual
659 NT fixed value (1000) */
661 return (rid < BASE_RID);
664 /*******************************************************************
665 Decides if a RID is a user or group RID.
666 ********************************************************************/
668 BOOL fallback_pdb_rid_is_user(uint32 rid)
670 /* lkcl i understand that NT attaches an enumeration to a RID
671 * such that it can be identified as either a user, group etc
672 * type. there are 5 such categories, and they are documented.
674 /* However, they are not in the RID, just somthing you can query
675 seperatly. Sorry luke :-) */
677 if(pdb_rid_is_well_known(rid)) {
679 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
680 * and DOMAIN_USER_RID_GUEST.
682 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
683 return True;
684 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
685 return True;
687 return False;
690 /*******************************************************************
691 Convert a rid into a name. Used in the lookup SID rpc.
692 ********************************************************************/
694 BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
696 uint32 rid;
697 SAM_ACCOUNT *sam_account = NULL;
698 GROUP_MAP map;
699 BOOL ret;
701 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
702 DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
703 sid_string_static(&map.sid)));
704 return False;
706 *psid_name_use = SID_NAME_UNKNOWN;
708 DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
710 if (rid == DOMAIN_USER_RID_ADMIN) {
711 const char **admin_list = lp_admin_users(-1);
712 *psid_name_use = SID_NAME_USER;
713 if (admin_list) {
714 const char *p = *admin_list;
715 if(!next_token(&p, name, NULL, sizeof(fstring)))
716 fstrcpy(name, "Administrator");
717 } else {
718 fstrcpy(name, "Administrator");
720 return True;
723 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
724 return False;
727 /* see if the passdb can help us with the name of the user */
729 /* BEING ROOT BLLOCK */
730 become_root();
731 if (pdb_getsampwsid(sam_account, sid)) {
732 unbecome_root(); /* -----> EXIT BECOME_ROOT() */
733 fstrcpy(name, pdb_get_username(sam_account));
734 *psid_name_use = SID_NAME_USER;
736 pdb_free_sam(&sam_account);
738 return True;
740 pdb_free_sam(&sam_account);
742 ret = pdb_getgrsid(&map, *sid);
743 unbecome_root();
744 /* END BECOME_ROOT BLOCK */
746 if ( ret ) {
747 if (map.gid!=(gid_t)-1) {
748 DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
749 } else {
750 DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
753 fstrcpy(name, map.nt_name);
754 *psid_name_use = map.sid_name_use;
755 return True;
758 if (fallback_pdb_rid_is_user(rid)) {
759 uid_t uid;
760 struct passwd *pw = NULL;
762 DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
764 uid = fallback_pdb_user_rid_to_uid(rid);
765 pw = sys_getpwuid( uid );
767 DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
768 pw ? "succeeded" : "failed" ));
770 if ( !pw )
771 fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
772 else
773 fstrcpy( name, pw->pw_name );
775 DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
776 (unsigned int)rid ));
778 *psid_name_use = SID_NAME_USER;
780 return ( pw != NULL );
781 } else {
782 gid_t gid;
783 struct group *gr;
785 DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
787 gid = pdb_group_rid_to_gid(rid);
788 gr = getgrgid(gid);
790 *psid_name_use = SID_NAME_ALIAS;
792 DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
793 gr ? "succeeded" : "failed" ));
795 if( !gr )
796 fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
797 else
798 fstrcpy( name, gr->gr_name);
800 DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
801 (unsigned int)rid ));
803 /* assume fallback groups aer domain global groups */
805 *psid_name_use = SID_NAME_DOM_GRP;
807 return ( gr != NULL );
811 /*******************************************************************
812 Convert a name into a SID. Used in the lookup name rpc.
813 ********************************************************************/
815 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
817 DOM_SID local_sid;
818 DOM_SID sid;
819 fstring user;
820 SAM_ACCOUNT *sam_account = NULL;
821 struct group *grp;
822 GROUP_MAP map;
824 *psid_name_use = SID_NAME_UNKNOWN;
827 * user may be quoted a const string, and map_username and
828 * friends can modify it. Make a modifiable copy. JRA.
831 fstrcpy(user, c_user);
833 sid_copy(&local_sid, get_global_sam_sid());
835 if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
836 fstring sid_str;
837 sid_copy( psid, &sid);
838 sid_to_string(sid_str, &sid);
839 DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
840 (unsigned int)*psid_name_use ));
841 return True;
844 (void)map_username(user);
846 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
847 return False;
850 /* BEGIN ROOT BLOCK */
852 become_root();
853 if (pdb_getsampwnam(sam_account, user)) {
854 unbecome_root();
855 sid_copy(psid, pdb_get_user_sid(sam_account));
856 *psid_name_use = SID_NAME_USER;
858 pdb_free_sam(&sam_account);
859 return True;
862 pdb_free_sam(&sam_account);
865 * Maybe it was a group ?
868 /* check if it's a mapped group */
869 if (pdb_getgrnam(&map, user)) {
870 /* yes it's a mapped group */
871 sid_copy(&local_sid, &map.sid);
872 *psid_name_use = map.sid_name_use;
873 } else {
874 /* it's not a mapped group */
875 grp = getgrnam(user);
876 if(!grp) {
877 unbecome_root(); /* ---> exit form block */
878 return False;
882 *check if it's mapped, if it is reply it doesn't exist
884 * that's to prevent this case:
886 * unix group ug is mapped to nt group ng
887 * someone does a lookup on ug
888 * we must not reply as it doesn't "exist" anymore
889 * for NT. For NT only ng exists.
890 * JFM, 30/11/2001
893 if (pdb_getgrgid(&map, grp->gr_gid)){
894 unbecome_root(); /* ---> exit form block */
895 return False;
898 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
899 *psid_name_use = SID_NAME_ALIAS;
901 unbecome_root();
902 /* END ROOT BLOCK */
904 sid_copy( psid, &local_sid);
906 return True;
909 /*************************************************************
910 Change a password entry in the local smbpasswd file.
911 *************************************************************/
913 BOOL local_password_change(const char *user_name, int local_flags,
914 const char *new_passwd,
915 char *err_str, size_t err_str_len,
916 char *msg_str, size_t msg_str_len)
918 SAM_ACCOUNT *sam_pass=NULL;
919 uint16 other_acb;
921 *err_str = '\0';
922 *msg_str = '\0';
924 /* Get the smb passwd entry for this user */
925 pdb_init_sam(&sam_pass);
927 become_root();
928 if(!pdb_getsampwnam(sam_pass, user_name)) {
929 unbecome_root();
930 pdb_free_sam(&sam_pass);
932 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
933 /* Might not exist in /etc/passwd. Use rid algorithm here */
934 if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
935 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);
936 return False;
938 } else {
939 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
940 return False;
942 } else {
943 unbecome_root();
944 /* the entry already existed */
945 local_flags &= ~LOCAL_ADD_USER;
948 /* the 'other' acb bits not being changed here */
949 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
950 if (local_flags & LOCAL_TRUST_ACCOUNT) {
951 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
952 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
953 pdb_free_sam(&sam_pass);
954 return False;
956 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
957 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
958 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
959 pdb_free_sam(&sam_pass);
960 return False;
962 } else {
963 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
964 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
965 pdb_free_sam(&sam_pass);
966 return False;
971 * We are root - just write the new password
972 * and the valid last change time.
975 if (local_flags & LOCAL_DISABLE_USER) {
976 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
977 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
978 pdb_free_sam(&sam_pass);
979 return False;
981 } else if (local_flags & LOCAL_ENABLE_USER) {
982 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
983 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
984 pdb_free_sam(&sam_pass);
985 return False;
989 if (local_flags & LOCAL_SET_NO_PASSWORD) {
990 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
991 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
992 pdb_free_sam(&sam_pass);
993 return False;
995 } else if (local_flags & LOCAL_SET_PASSWORD) {
997 * If we're dealing with setting a completely empty user account
998 * ie. One with a password of 'XXXX', but not set disabled (like
999 * an account created from scratch) then if the old password was
1000 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1001 * We remove that as we're giving this user their first password
1002 * and the decision hasn't really been made to disable them (ie.
1003 * don't create them disabled). JRA.
1005 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1006 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1007 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1008 pdb_free_sam(&sam_pass);
1009 return False;
1012 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1013 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1014 pdb_free_sam(&sam_pass);
1015 return False;
1018 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1019 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1020 pdb_free_sam(&sam_pass);
1021 return False;
1025 if (local_flags & LOCAL_ADD_USER) {
1026 if (pdb_add_sam_account(sam_pass)) {
1027 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1028 pdb_free_sam(&sam_pass);
1029 return True;
1030 } else {
1031 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1032 pdb_free_sam(&sam_pass);
1033 return False;
1035 } else if (local_flags & LOCAL_DELETE_USER) {
1036 if (!pdb_delete_sam_account(sam_pass)) {
1037 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1038 pdb_free_sam(&sam_pass);
1039 return False;
1041 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1042 } else {
1043 if(!pdb_update_sam_account(sam_pass)) {
1044 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1045 pdb_free_sam(&sam_pass);
1046 return False;
1048 if(local_flags & LOCAL_DISABLE_USER)
1049 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1050 else if (local_flags & LOCAL_ENABLE_USER)
1051 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1052 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1053 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1056 pdb_free_sam(&sam_pass);
1057 return True;
1060 /****************************************************************************
1061 Convert a uid to SID - algorithmic.
1062 ****************************************************************************/
1064 DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1066 if ( !lp_enable_rid_algorithm() )
1067 return NULL;
1069 DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1070 sid_copy( psid, get_global_sam_sid() );
1071 sid_append_rid( psid, fallback_pdb_uid_to_user_rid(uid) );
1072 DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
1073 (unsigned int)uid, sid_string_static(psid) ));
1075 return psid;
1078 /****************************************************************************
1079 Convert a uid to SID - locally.
1080 ****************************************************************************/
1082 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1084 SAM_ACCOUNT *sampw = NULL;
1085 struct passwd *unix_pw;
1086 BOOL ret;
1088 unix_pw = sys_getpwuid( uid );
1090 if ( !unix_pw ) {
1091 DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1092 return algorithmic_uid_to_sid( psid, uid);
1095 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1096 DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1097 return NULL;
1100 become_root();
1101 ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1102 unbecome_root();
1104 if ( ret )
1105 sid_copy( psid, pdb_get_user_sid(sampw) );
1106 else {
1107 DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1108 unix_pw->pw_name, (unsigned long)uid));
1110 return algorithmic_uid_to_sid( psid, uid);
1113 DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
1114 (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1116 return psid;
1119 /****************************************************************************
1120 Convert a SID to uid - locally.
1121 ****************************************************************************/
1123 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1125 SAM_ACCOUNT *sampw = NULL;
1126 struct passwd *unix_pw;
1127 const char *user_name;
1129 *name_type = SID_NAME_UNKNOWN;
1132 * We can only convert to a uid if this is our local
1133 * Domain SID (ie. we are the controling authority).
1135 if (!sid_check_is_in_our_domain(psid) ) {
1136 DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1137 return False;
1140 /* lookup the user account */
1142 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1143 DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1144 return False;
1147 become_root();
1148 if ( !pdb_getsampwsid(sampw, psid) ) {
1149 unbecome_root();
1150 DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1151 sid_string_static(psid)));
1152 return False;
1154 unbecome_root();
1156 user_name = pdb_get_username(sampw);
1158 unix_pw = sys_getpwnam( user_name );
1160 if ( !unix_pw ) {
1161 DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1162 user_name));
1163 pdb_free_sam( &sampw );
1164 return False;
1167 *puid = unix_pw->pw_uid;
1169 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1170 (unsigned int)*puid, user_name ));
1172 *name_type = SID_NAME_USER;
1174 return True;
1177 /****************************************************************************
1178 Convert a gid to SID - algorithmic.
1179 ****************************************************************************/
1181 DOM_SID *algorithmic_gid_to_sid(DOM_SID *psid, uid_t gid)
1183 if ( !lp_enable_rid_algorithm() )
1184 return NULL;
1186 DEBUG(8,("algorithmic_gid_to_sid: falling back to RID algorithm\n"));
1187 sid_copy( psid, get_global_sam_sid() );
1188 sid_append_rid( psid, pdb_gid_to_group_rid(gid) );
1189 DEBUG(10,("algorithmic_gid_to_sid: gid (%d) -> SID %s.\n",
1190 (unsigned int)gid, sid_string_static(psid) ));
1192 return psid;
1195 /****************************************************************************
1196 Convert a gid to SID - locally.
1197 ****************************************************************************/
1199 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1201 GROUP_MAP group;
1202 BOOL ret;
1204 /* we don't need to disable winbindd since the gid is stored in
1205 the GROUP_MAP object */
1207 /* done as root since ldap backend requires root to open a connection */
1209 become_root();
1210 ret = pdb_getgrgid( &group, gid );
1211 unbecome_root();
1213 if ( !ret ) {
1215 /* fallback to rid mapping if enabled */
1217 if ( lp_enable_rid_algorithm() ) {
1219 DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1220 (unsigned int)gid, sid_string_static(psid)));
1222 return algorithmic_gid_to_sid(psid, gid);
1224 else
1225 return NULL;
1228 sid_copy( psid, &group.sid );
1230 DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
1231 (unsigned int)gid, sid_string_static(psid)));
1233 return psid;
1236 /****************************************************************************
1237 Convert a SID to gid - locally.
1238 ****************************************************************************/
1240 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1242 uint32 rid;
1243 GROUP_MAP group;
1244 BOOL ret;
1246 *name_type = SID_NAME_UNKNOWN;
1248 /* This call can enumerate group mappings for foreign sids as well.
1249 So don't check for a match against our domain SID */
1251 /* we don't need to disable winbindd since the gid is stored in
1252 the GROUP_MAP object */
1254 become_root();
1255 ret = pdb_getgrsid(&group, *psid);
1256 unbecome_root();
1258 if ( !ret ) {
1260 /* fallback to rid mapping if enabled */
1262 if ( lp_enable_rid_algorithm() ) {
1264 if (!sid_check_is_in_our_domain(psid) ) {
1265 DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1266 return False;
1269 if (!sid_peek_rid(psid, &rid)) {
1270 DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1271 return False;
1274 DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1276 if (fallback_pdb_rid_is_user(rid)) {
1277 DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1278 return False;
1279 } else {
1280 *pgid = pdb_group_rid_to_gid(rid);
1281 DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1282 return True;
1286 return False;
1289 *pgid = group.gid;
1290 *name_type = group.sid_name_use;
1292 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1293 (unsigned int)*pgid));
1295 return True;
1298 /**********************************************************************
1299 Marshall/unmarshall SAM_ACCOUNT structs.
1300 *********************************************************************/
1302 #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1303 #define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1304 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1306 /**********************************************************************
1307 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1308 *********************************************************************/
1310 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1312 return(init_sam_from_buffer_v2(sampass, buf, buflen));
1315 /**********************************************************************
1316 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1317 *********************************************************************/
1319 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1321 return(init_buffer_from_sam_v2(buf, sampass, size_only));
1325 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1328 /* times are stored as 32bit integer
1329 take care on system with 64bit wide time_t
1330 --SSS */
1331 uint32 logon_time,
1332 logoff_time,
1333 kickoff_time,
1334 pass_last_set_time,
1335 pass_can_change_time,
1336 pass_must_change_time;
1337 char *username;
1338 char *domain;
1339 char *nt_username;
1340 char *dir_drive;
1341 char *unknown_str;
1342 char *munged_dial;
1343 char *fullname;
1344 char *homedir;
1345 char *logon_script;
1346 char *profile_path;
1347 char *acct_desc;
1348 char *workstations;
1349 uint32 username_len, domain_len, nt_username_len,
1350 dir_drive_len, unknown_str_len, munged_dial_len,
1351 fullname_len, homedir_len, logon_script_len,
1352 profile_path_len, acct_desc_len, workstations_len;
1354 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1355 uint16 acct_ctrl, logon_divs;
1356 uint16 bad_password_count, logon_count;
1357 uint8 *hours;
1358 uint8 *lm_pw_ptr, *nt_pw_ptr;
1359 uint32 len = 0;
1360 uint32 lm_pw_len, nt_pw_len, hourslen;
1361 BOOL ret = True;
1363 if(sampass == NULL || buf == NULL) {
1364 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1365 return False;
1368 /* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1370 /* unpack the buffer into variables */
1371 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1372 &logon_time, /* d */
1373 &logoff_time, /* d */
1374 &kickoff_time, /* d */
1375 &pass_last_set_time, /* d */
1376 &pass_can_change_time, /* d */
1377 &pass_must_change_time, /* d */
1378 &username_len, &username, /* B */
1379 &domain_len, &domain, /* B */
1380 &nt_username_len, &nt_username, /* B */
1381 &fullname_len, &fullname, /* B */
1382 &homedir_len, &homedir, /* B */
1383 &dir_drive_len, &dir_drive, /* B */
1384 &logon_script_len, &logon_script, /* B */
1385 &profile_path_len, &profile_path, /* B */
1386 &acct_desc_len, &acct_desc, /* B */
1387 &workstations_len, &workstations, /* B */
1388 &unknown_str_len, &unknown_str, /* B */
1389 &munged_dial_len, &munged_dial, /* B */
1390 &user_rid, /* d */
1391 &group_rid, /* d */
1392 &lm_pw_len, &lm_pw_ptr, /* B */
1393 &nt_pw_len, &nt_pw_ptr, /* B */
1394 &acct_ctrl, /* w */
1395 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1396 &logon_divs, /* w */
1397 &hours_len, /* d */
1398 &hourslen, &hours, /* B */
1399 &bad_password_count, /* w */
1400 &logon_count, /* w */
1401 &unknown_6); /* d */
1403 if (len == (uint32) -1) {
1404 ret = False;
1405 goto done;
1408 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1409 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1410 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1411 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1412 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1413 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1415 pdb_set_username(sampass, username, PDB_SET);
1416 pdb_set_domain(sampass, domain, PDB_SET);
1417 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1418 pdb_set_fullname(sampass, fullname, PDB_SET);
1420 if (homedir) {
1421 pdb_set_homedir(sampass, homedir, PDB_SET);
1423 else {
1424 pdb_set_homedir(sampass,
1425 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1426 PDB_DEFAULT);
1429 if (dir_drive)
1430 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1431 else {
1432 pdb_set_dir_drive(sampass,
1433 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1434 PDB_DEFAULT);
1437 if (logon_script)
1438 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1439 else {
1440 pdb_set_logon_script(sampass,
1441 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1442 PDB_DEFAULT);
1445 if (profile_path) {
1446 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1447 } else {
1448 pdb_set_profile_path(sampass,
1449 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1450 PDB_DEFAULT);
1453 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1454 pdb_set_workstations(sampass, workstations, PDB_SET);
1455 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1457 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1458 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1459 ret = False;
1460 goto done;
1464 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1465 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1466 ret = False;
1467 goto done;
1471 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1472 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1473 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1474 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1475 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1476 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1477 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1478 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1479 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1480 pdb_set_hours(sampass, hours, PDB_SET);
1482 done:
1484 SAFE_FREE(username);
1485 SAFE_FREE(domain);
1486 SAFE_FREE(nt_username);
1487 SAFE_FREE(fullname);
1488 SAFE_FREE(homedir);
1489 SAFE_FREE(dir_drive);
1490 SAFE_FREE(logon_script);
1491 SAFE_FREE(profile_path);
1492 SAFE_FREE(acct_desc);
1493 SAFE_FREE(workstations);
1494 SAFE_FREE(munged_dial);
1495 SAFE_FREE(unknown_str);
1496 SAFE_FREE(lm_pw_ptr);
1497 SAFE_FREE(nt_pw_ptr);
1498 SAFE_FREE(hours);
1500 return ret;
1503 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1506 /* times are stored as 32bit integer
1507 take care on system with 64bit wide time_t
1508 --SSS */
1509 uint32 logon_time,
1510 logoff_time,
1511 kickoff_time,
1512 bad_password_time,
1513 pass_last_set_time,
1514 pass_can_change_time,
1515 pass_must_change_time;
1516 char *username;
1517 char *domain;
1518 char *nt_username;
1519 char *dir_drive;
1520 char *unknown_str;
1521 char *munged_dial;
1522 char *fullname;
1523 char *homedir;
1524 char *logon_script;
1525 char *profile_path;
1526 char *acct_desc;
1527 char *workstations;
1528 uint32 username_len, domain_len, nt_username_len,
1529 dir_drive_len, unknown_str_len, munged_dial_len,
1530 fullname_len, homedir_len, logon_script_len,
1531 profile_path_len, acct_desc_len, workstations_len;
1533 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1534 uint16 acct_ctrl, logon_divs;
1535 uint16 bad_password_count, logon_count;
1536 uint8 *hours;
1537 uint8 *lm_pw_ptr, *nt_pw_ptr;
1538 uint32 len = 0;
1539 uint32 lm_pw_len, nt_pw_len, hourslen;
1540 BOOL ret = True;
1542 if(sampass == NULL || buf == NULL) {
1543 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1544 return False;
1547 /* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1549 /* unpack the buffer into variables */
1550 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1551 &logon_time, /* d */
1552 &logoff_time, /* d */
1553 &kickoff_time, /* d */
1554 /* Change from V0 is addition of bad_password_time field. */
1555 &bad_password_time, /* d */
1556 &pass_last_set_time, /* d */
1557 &pass_can_change_time, /* d */
1558 &pass_must_change_time, /* d */
1559 &username_len, &username, /* B */
1560 &domain_len, &domain, /* B */
1561 &nt_username_len, &nt_username, /* B */
1562 &fullname_len, &fullname, /* B */
1563 &homedir_len, &homedir, /* B */
1564 &dir_drive_len, &dir_drive, /* B */
1565 &logon_script_len, &logon_script, /* B */
1566 &profile_path_len, &profile_path, /* B */
1567 &acct_desc_len, &acct_desc, /* B */
1568 &workstations_len, &workstations, /* B */
1569 &unknown_str_len, &unknown_str, /* B */
1570 &munged_dial_len, &munged_dial, /* B */
1571 &user_rid, /* d */
1572 &group_rid, /* d */
1573 &lm_pw_len, &lm_pw_ptr, /* B */
1574 &nt_pw_len, &nt_pw_ptr, /* B */
1575 &acct_ctrl, /* w */
1576 &remove_me, /* d */
1577 &logon_divs, /* w */
1578 &hours_len, /* d */
1579 &hourslen, &hours, /* B */
1580 &bad_password_count, /* w */
1581 &logon_count, /* w */
1582 &unknown_6); /* d */
1584 if (len == (uint32) -1) {
1585 ret = False;
1586 goto done;
1589 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1590 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1591 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1593 /* Change from V0 is addition of bad_password_time field. */
1594 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1595 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1596 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1597 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1599 pdb_set_username(sampass, username, PDB_SET);
1600 pdb_set_domain(sampass, domain, PDB_SET);
1601 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1602 pdb_set_fullname(sampass, fullname, PDB_SET);
1604 if (homedir) {
1605 pdb_set_homedir(sampass, homedir, PDB_SET);
1607 else {
1608 pdb_set_homedir(sampass,
1609 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1610 PDB_DEFAULT);
1613 if (dir_drive)
1614 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1615 else {
1616 pdb_set_dir_drive(sampass,
1617 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1618 PDB_DEFAULT);
1621 if (logon_script)
1622 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1623 else {
1624 pdb_set_logon_script(sampass,
1625 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1626 PDB_DEFAULT);
1629 if (profile_path) {
1630 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1631 } else {
1632 pdb_set_profile_path(sampass,
1633 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1634 PDB_DEFAULT);
1637 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1638 pdb_set_workstations(sampass, workstations, PDB_SET);
1639 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1641 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1642 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1643 ret = False;
1644 goto done;
1648 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1649 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1650 ret = False;
1651 goto done;
1655 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1657 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1658 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1659 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1660 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1661 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1662 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1663 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1664 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1665 pdb_set_hours(sampass, hours, PDB_SET);
1667 done:
1669 SAFE_FREE(username);
1670 SAFE_FREE(domain);
1671 SAFE_FREE(nt_username);
1672 SAFE_FREE(fullname);
1673 SAFE_FREE(homedir);
1674 SAFE_FREE(dir_drive);
1675 SAFE_FREE(logon_script);
1676 SAFE_FREE(profile_path);
1677 SAFE_FREE(acct_desc);
1678 SAFE_FREE(workstations);
1679 SAFE_FREE(munged_dial);
1680 SAFE_FREE(unknown_str);
1681 SAFE_FREE(lm_pw_ptr);
1682 SAFE_FREE(nt_pw_ptr);
1683 SAFE_FREE(hours);
1685 return ret;
1689 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1692 /* times are stored as 32bit integer
1693 take care on system with 64bit wide time_t
1694 --SSS */
1695 uint32 logon_time,
1696 logoff_time,
1697 kickoff_time,
1698 bad_password_time,
1699 pass_last_set_time,
1700 pass_can_change_time,
1701 pass_must_change_time;
1702 char *username;
1703 char *domain;
1704 char *nt_username;
1705 char *dir_drive;
1706 char *unknown_str;
1707 char *munged_dial;
1708 char *fullname;
1709 char *homedir;
1710 char *logon_script;
1711 char *profile_path;
1712 char *acct_desc;
1713 char *workstations;
1714 uint32 username_len, domain_len, nt_username_len,
1715 dir_drive_len, unknown_str_len, munged_dial_len,
1716 fullname_len, homedir_len, logon_script_len,
1717 profile_path_len, acct_desc_len, workstations_len;
1719 uint32 user_rid, group_rid, hours_len, unknown_6;
1720 uint16 acct_ctrl, logon_divs;
1721 uint16 bad_password_count, logon_count;
1722 uint8 *hours;
1723 uint8 *lm_pw_ptr, *nt_pw_ptr, *nt_pw_hist_ptr;
1724 uint32 len = 0;
1725 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1726 uint32 pwHistLen = 0;
1727 BOOL ret = True;
1729 if(sampass == NULL || buf == NULL) {
1730 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1731 return False;
1734 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1736 /* unpack the buffer into variables */
1737 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1738 &logon_time, /* d */
1739 &logoff_time, /* d */
1740 &kickoff_time, /* d */
1741 &bad_password_time, /* d */
1742 &pass_last_set_time, /* d */
1743 &pass_can_change_time, /* d */
1744 &pass_must_change_time, /* d */
1745 &username_len, &username, /* B */
1746 &domain_len, &domain, /* B */
1747 &nt_username_len, &nt_username, /* B */
1748 &fullname_len, &fullname, /* B */
1749 &homedir_len, &homedir, /* B */
1750 &dir_drive_len, &dir_drive, /* B */
1751 &logon_script_len, &logon_script, /* B */
1752 &profile_path_len, &profile_path, /* B */
1753 &acct_desc_len, &acct_desc, /* B */
1754 &workstations_len, &workstations, /* B */
1755 &unknown_str_len, &unknown_str, /* B */
1756 &munged_dial_len, &munged_dial, /* B */
1757 &user_rid, /* d */
1758 &group_rid, /* d */
1759 &lm_pw_len, &lm_pw_ptr, /* B */
1760 &nt_pw_len, &nt_pw_ptr, /* B */
1761 /* Change from V1 is addition of password history field. */
1762 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1763 &acct_ctrl, /* w */
1764 /* Also "remove_me" field was removed. */
1765 &logon_divs, /* w */
1766 &hours_len, /* d */
1767 &hourslen, &hours, /* B */
1768 &bad_password_count, /* w */
1769 &logon_count, /* w */
1770 &unknown_6); /* d */
1772 if (len == (uint32) -1) {
1773 ret = False;
1774 goto done;
1777 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1778 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1779 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1780 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1781 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1782 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1783 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1785 pdb_set_username(sampass, username, PDB_SET);
1786 pdb_set_domain(sampass, domain, PDB_SET);
1787 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1788 pdb_set_fullname(sampass, fullname, PDB_SET);
1790 if (homedir) {
1791 pdb_set_homedir(sampass, homedir, PDB_SET);
1793 else {
1794 pdb_set_homedir(sampass,
1795 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1796 PDB_DEFAULT);
1799 if (dir_drive)
1800 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1801 else {
1802 pdb_set_dir_drive(sampass,
1803 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1804 PDB_DEFAULT);
1807 if (logon_script)
1808 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1809 else {
1810 pdb_set_logon_script(sampass,
1811 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1812 PDB_DEFAULT);
1815 if (profile_path) {
1816 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1817 } else {
1818 pdb_set_profile_path(sampass,
1819 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1820 PDB_DEFAULT);
1823 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1824 pdb_set_workstations(sampass, workstations, PDB_SET);
1825 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1827 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1828 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1829 ret = False;
1830 goto done;
1834 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1835 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1836 ret = False;
1837 goto done;
1841 /* Change from V1 is addition of password history field. */
1842 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
1843 if (pwHistLen) {
1844 char *pw_hist = malloc(pwHistLen * NT_HASH_LEN);
1845 if (!pw_hist) {
1846 ret = False;
1847 goto done;
1849 memset(pw_hist, '\0', pwHistLen * NT_HASH_LEN);
1850 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1851 int i;
1852 SMB_ASSERT((nt_pw_hist_len % NT_HASH_LEN) == 0);
1853 nt_pw_hist_len /= NT_HASH_LEN;
1854 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1855 memcpy(&pw_hist[i*NT_HASH_LEN], &nt_pw_hist_ptr[i*NT_HASH_LEN], NT_HASH_LEN);
1858 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1859 SAFE_FREE(pw_hist);
1860 ret = False;
1861 goto done;
1863 SAFE_FREE(pw_hist);
1864 } else {
1865 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1868 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1869 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1870 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1871 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1872 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1873 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1874 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1875 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1876 pdb_set_hours(sampass, hours, PDB_SET);
1878 done:
1880 SAFE_FREE(username);
1881 SAFE_FREE(domain);
1882 SAFE_FREE(nt_username);
1883 SAFE_FREE(fullname);
1884 SAFE_FREE(homedir);
1885 SAFE_FREE(dir_drive);
1886 SAFE_FREE(logon_script);
1887 SAFE_FREE(profile_path);
1888 SAFE_FREE(acct_desc);
1889 SAFE_FREE(workstations);
1890 SAFE_FREE(munged_dial);
1891 SAFE_FREE(unknown_str);
1892 SAFE_FREE(lm_pw_ptr);
1893 SAFE_FREE(nt_pw_ptr);
1894 SAFE_FREE(nt_pw_hist_ptr);
1895 SAFE_FREE(hours);
1897 return ret;
1900 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1902 size_t len, buflen;
1904 /* times are stored as 32bit integer
1905 take care on system with 64bit wide time_t
1906 --SSS */
1907 uint32 logon_time,
1908 logoff_time,
1909 kickoff_time,
1910 bad_password_time,
1911 pass_last_set_time,
1912 pass_can_change_time,
1913 pass_must_change_time;
1915 uint32 user_rid, group_rid;
1917 const char *username;
1918 const char *domain;
1919 const char *nt_username;
1920 const char *dir_drive;
1921 const char *unknown_str;
1922 const char *munged_dial;
1923 const char *fullname;
1924 const char *homedir;
1925 const char *logon_script;
1926 const char *profile_path;
1927 const char *acct_desc;
1928 const char *workstations;
1929 uint32 username_len, domain_len, nt_username_len,
1930 dir_drive_len, unknown_str_len, munged_dial_len,
1931 fullname_len, homedir_len, logon_script_len,
1932 profile_path_len, acct_desc_len, workstations_len;
1934 const uint8 *lm_pw;
1935 const uint8 *nt_pw;
1936 const uint8 *nt_pw_hist;
1937 uint32 lm_pw_len = 16;
1938 uint32 nt_pw_len = 16;
1939 uint32 nt_pw_hist_len;
1940 uint32 pwHistLen = 0;
1942 /* do we have a valid SAM_ACCOUNT pointer? */
1943 if (sampass == NULL) {
1944 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
1945 return -1;
1948 *buf = NULL;
1949 buflen = 0;
1951 logon_time = (uint32)pdb_get_logon_time(sampass);
1952 logoff_time = (uint32)pdb_get_logoff_time(sampass);
1953 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
1954 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
1955 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
1956 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
1957 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
1959 user_rid = pdb_get_user_rid(sampass);
1960 group_rid = pdb_get_group_rid(sampass);
1962 username = pdb_get_username(sampass);
1963 if (username) {
1964 username_len = strlen(username) +1;
1965 } else {
1966 username_len = 0;
1969 domain = pdb_get_domain(sampass);
1970 if (domain) {
1971 domain_len = strlen(domain) +1;
1972 } else {
1973 domain_len = 0;
1976 nt_username = pdb_get_nt_username(sampass);
1977 if (nt_username) {
1978 nt_username_len = strlen(nt_username) +1;
1979 } else {
1980 nt_username_len = 0;
1983 fullname = pdb_get_fullname(sampass);
1984 if (fullname) {
1985 fullname_len = strlen(fullname) +1;
1986 } else {
1987 fullname_len = 0;
1991 * Only updates fields which have been set (not defaults from smb.conf)
1994 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1995 dir_drive = pdb_get_dir_drive(sampass);
1996 } else {
1997 dir_drive = NULL;
1999 if (dir_drive) {
2000 dir_drive_len = strlen(dir_drive) +1;
2001 } else {
2002 dir_drive_len = 0;
2005 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2006 homedir = pdb_get_homedir(sampass);
2007 } else {
2008 homedir = NULL;
2010 if (homedir) {
2011 homedir_len = strlen(homedir) +1;
2012 } else {
2013 homedir_len = 0;
2016 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2017 logon_script = pdb_get_logon_script(sampass);
2018 } else {
2019 logon_script = NULL;
2021 if (logon_script) {
2022 logon_script_len = strlen(logon_script) +1;
2023 } else {
2024 logon_script_len = 0;
2027 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2028 profile_path = pdb_get_profile_path(sampass);
2029 } else {
2030 profile_path = NULL;
2032 if (profile_path) {
2033 profile_path_len = strlen(profile_path) +1;
2034 } else {
2035 profile_path_len = 0;
2038 lm_pw = pdb_get_lanman_passwd(sampass);
2039 if (!lm_pw) {
2040 lm_pw_len = 0;
2043 nt_pw = pdb_get_nt_passwd(sampass);
2044 if (!nt_pw) {
2045 nt_pw_len = 0;
2048 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
2049 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
2050 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2051 nt_pw_hist_len *= NT_HASH_LEN;
2052 } else {
2053 nt_pw_hist_len = 0;
2056 acct_desc = pdb_get_acct_desc(sampass);
2057 if (acct_desc) {
2058 acct_desc_len = strlen(acct_desc) +1;
2059 } else {
2060 acct_desc_len = 0;
2063 workstations = pdb_get_workstations(sampass);
2064 if (workstations) {
2065 workstations_len = strlen(workstations) +1;
2066 } else {
2067 workstations_len = 0;
2070 unknown_str = NULL;
2071 unknown_str_len = 0;
2073 munged_dial = pdb_get_munged_dial(sampass);
2074 if (munged_dial) {
2075 munged_dial_len = strlen(munged_dial) +1;
2076 } else {
2077 munged_dial_len = 0;
2080 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2082 /* one time to get the size needed */
2083 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
2084 logon_time, /* d */
2085 logoff_time, /* d */
2086 kickoff_time, /* d */
2087 bad_password_time, /* d */
2088 pass_last_set_time, /* d */
2089 pass_can_change_time, /* d */
2090 pass_must_change_time, /* d */
2091 username_len, username, /* B */
2092 domain_len, domain, /* B */
2093 nt_username_len, nt_username, /* B */
2094 fullname_len, fullname, /* B */
2095 homedir_len, homedir, /* B */
2096 dir_drive_len, dir_drive, /* B */
2097 logon_script_len, logon_script, /* B */
2098 profile_path_len, profile_path, /* B */
2099 acct_desc_len, acct_desc, /* B */
2100 workstations_len, workstations, /* B */
2101 unknown_str_len, unknown_str, /* B */
2102 munged_dial_len, munged_dial, /* B */
2103 user_rid, /* d */
2104 group_rid, /* d */
2105 lm_pw_len, lm_pw, /* B */
2106 nt_pw_len, nt_pw, /* B */
2107 nt_pw_hist_len, nt_pw_hist, /* B */
2108 pdb_get_acct_ctrl(sampass), /* w */
2109 pdb_get_logon_divs(sampass), /* w */
2110 pdb_get_hours_len(sampass), /* d */
2111 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2112 pdb_get_bad_password_count(sampass), /* w */
2113 pdb_get_logon_count(sampass), /* w */
2114 pdb_get_unknown_6(sampass)); /* d */
2116 if (size_only) {
2117 return buflen;
2120 /* malloc the space needed */
2121 if ( (*buf=(uint8*)malloc(len)) == NULL) {
2122 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2123 return (-1);
2126 /* now for the real call to tdb_pack() */
2127 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
2128 logon_time, /* d */
2129 logoff_time, /* d */
2130 kickoff_time, /* d */
2131 bad_password_time, /* d */
2132 pass_last_set_time, /* d */
2133 pass_can_change_time, /* d */
2134 pass_must_change_time, /* d */
2135 username_len, username, /* B */
2136 domain_len, domain, /* B */
2137 nt_username_len, nt_username, /* B */
2138 fullname_len, fullname, /* B */
2139 homedir_len, homedir, /* B */
2140 dir_drive_len, dir_drive, /* B */
2141 logon_script_len, logon_script, /* B */
2142 profile_path_len, profile_path, /* B */
2143 acct_desc_len, acct_desc, /* B */
2144 workstations_len, workstations, /* B */
2145 unknown_str_len, unknown_str, /* B */
2146 munged_dial_len, munged_dial, /* B */
2147 user_rid, /* d */
2148 group_rid, /* d */
2149 lm_pw_len, lm_pw, /* B */
2150 nt_pw_len, nt_pw, /* B */
2151 nt_pw_hist_len, nt_pw_hist, /* B */
2152 pdb_get_acct_ctrl(sampass), /* w */
2153 pdb_get_logon_divs(sampass), /* w */
2154 pdb_get_hours_len(sampass), /* d */
2155 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2156 pdb_get_bad_password_count(sampass), /* w */
2157 pdb_get_logon_count(sampass), /* w */
2158 pdb_get_unknown_6(sampass)); /* d */
2160 /* check to make sure we got it correct */
2161 if (buflen != len) {
2162 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2163 (unsigned long)buflen, (unsigned long)len));
2164 /* error */
2165 SAFE_FREE (*buf);
2166 return (-1);
2169 return (buflen);
2172 /**********************************************************************
2173 **********************************************************************/
2175 static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2177 uid_t u_low, u_high;
2178 gid_t g_low, g_high;
2180 if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2181 return False;
2184 *low = (u_low < g_low) ? u_low : g_low;
2185 *high = (u_high < g_high) ? u_high : g_high;
2187 return True;
2190 /******************************************************************
2191 Get the the non-algorithmic RID range if idmap range are defined
2192 ******************************************************************/
2194 BOOL get_free_rid_range(uint32 *low, uint32 *high)
2196 uint32 id_low, id_high;
2198 if (!lp_enable_rid_algorithm()) {
2199 *low = BASE_RID;
2200 *high = (uint32)-1;
2203 if (!get_free_ugid_range(&id_low, &id_high)) {
2204 return False;
2207 *low = fallback_pdb_uid_to_user_rid(id_low);
2208 if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2209 *high = (uint32)-1;
2210 } else {
2211 *high = fallback_pdb_uid_to_user_rid(id_high);
2214 return True;
2217 /*********************************************************************
2218 Update the bad password count checking the AP_RESET_COUNT_TIME
2219 *********************************************************************/
2221 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2223 time_t LastBadPassword;
2224 uint16 BadPasswordCount;
2225 uint32 resettime;
2227 if (!sampass) return False;
2229 BadPasswordCount = pdb_get_bad_password_count(sampass);
2230 if (!BadPasswordCount) {
2231 DEBUG(9, ("No bad password attempts.\n"));
2232 return True;
2235 if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
2236 DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
2237 return False;
2240 /* First, check if there is a reset time to compare */
2241 if ((resettime == (uint32) -1) || (resettime == 0)) {
2242 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2243 return True;
2246 LastBadPassword = pdb_get_bad_password_time(sampass);
2247 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2248 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2249 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2250 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2251 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2252 if (updated) {
2253 *updated = True;
2257 return True;
2260 /*********************************************************************
2261 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2262 *********************************************************************/
2264 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2266 uint32 duration;
2267 time_t LastBadPassword;
2269 if (!sampass) return False;
2271 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2272 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2273 pdb_get_username(sampass)));
2274 return True;
2277 if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2278 DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
2279 return False;
2282 /* First, check if there is a duration to compare */
2283 if ((duration == (uint32) -1) || (duration == 0)) {
2284 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2285 return True;
2288 LastBadPassword = pdb_get_bad_password_time(sampass);
2289 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2290 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2292 if (LastBadPassword == (time_t)0) {
2293 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2294 bad password time. Leaving locked out.\n",
2295 pdb_get_username(sampass) ));
2296 return True;
2299 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2300 pdb_set_acct_ctrl(sampass,
2301 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2302 PDB_CHANGED);
2303 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2304 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2305 if (updated) {
2306 *updated = True;
2310 return True;
2313 /*********************************************************************
2314 Increment the bad_password_count
2315 *********************************************************************/
2317 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2319 uint32 account_policy_lockout;
2320 BOOL autolock_updated = False, badpw_updated = False;
2322 if (!sampass)
2323 return False;
2325 /* Retrieve the account lockout policy */
2326 if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
2327 &account_policy_lockout)) {
2328 DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
2329 return False;
2332 /* If there is no policy, we don't need to continue checking */
2333 if (!account_policy_lockout) {
2334 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2335 return True;
2338 /* Check if the autolock needs to be cleared */
2339 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2340 return False;
2342 /* Check if the badpw count needs to be reset */
2343 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2344 return False;
2347 Ok, now we can assume that any resetting that needs to be
2348 done has been done, and just get on with incrementing
2349 and autolocking if necessary
2352 pdb_set_bad_password_count(sampass,
2353 pdb_get_bad_password_count(sampass)+1,
2354 PDB_CHANGED);
2355 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2358 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2359 return True;
2361 if (!pdb_set_acct_ctrl(sampass,
2362 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2363 PDB_CHANGED)) {
2364 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2365 return False;
2368 return True;