r13494: Merge the stuff I've done in head the last days.
[ira/wip.git] / source3 / passdb / passdb.c
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
9    Copyright (C) Volker Lendecke                2006
10       
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_PASSDB
30
31 /******************************************************************
32  get the default domain/netbios name to be used when 
33  testing authentication.  For example, if you connect
34  to a Windows member server using a bogus domain name, the
35  Windows box will map the BOGUS\user to DOMAIN\user.  A 
36  standalone box will map to WKS\user.
37 ******************************************************************/
38
39 const char *get_default_sam_name(void)
40 {
41         /* standalone servers can only use the local netbios name */
42         if ( lp_server_role() == ROLE_STANDALONE )
43                 return global_myname();
44
45         /* Windows domain members default to the DOMAIN
46            name when not specified */
47         return lp_workgroup();
48 }
49
50 /************************************************************
51  Fill the SAM_ACCOUNT with default values.
52  ***********************************************************/
53
54 void pdb_fill_default_sam(SAM_ACCOUNT *user)
55 {
56         ZERO_STRUCT(user->private_u); /* Don't touch the talloc context */
57
58         /* no initial methods */
59         user->methods = NULL;
60
61         /* Don't change these timestamp settings without a good reason.
62            They are important for NT member server compatibility. */
63
64         user->private_u.logon_time            = (time_t)0;
65         user->private_u.pass_last_set_time    = (time_t)0;
66         user->private_u.pass_can_change_time  = (time_t)0;
67         user->private_u.logoff_time           = 
68         user->private_u.kickoff_time          = 
69         user->private_u.pass_must_change_time = get_time_t_max();
70         user->private_u.fields_present        = 0x00ffffff;
71         user->private_u.logon_divs = 168;       /* hours per week */
72         user->private_u.hours_len = 21;                 /* 21 times 8 bits = 168 */
73         memset(user->private_u.hours, 0xff, user->private_u.hours_len); /* available at all hours */
74         user->private_u.bad_password_count = 0;
75         user->private_u.logon_count = 0;
76         user->private_u.unknown_6 = 0x000004ec; /* don't know */
77
78         /* Some parts of samba strlen their pdb_get...() returns, 
79            so this keeps the interface unchanged for now. */
80            
81         user->private_u.username = "";
82         user->private_u.domain = "";
83         user->private_u.nt_username = "";
84         user->private_u.full_name = "";
85         user->private_u.home_dir = "";
86         user->private_u.logon_script = "";
87         user->private_u.profile_path = "";
88         user->private_u.acct_desc = "";
89         user->private_u.workstations = "";
90         user->private_u.unknown_str = "";
91         user->private_u.munged_dial = "";
92
93         user->private_u.plaintext_pw = NULL;
94
95         /* 
96            Unless we know otherwise have a Account Control Bit
97            value of 'normal user'.  This helps User Manager, which
98            asks for a filtered list of users.
99         */
100
101         user->private_u.acct_ctrl = ACB_NORMAL;
102 }       
103
104 static void destroy_pdb_talloc(SAM_ACCOUNT **user) 
105 {
106         if (*user) {
107                 data_blob_clear_free(&((*user)->private_u.lm_pw));
108                 data_blob_clear_free(&((*user)->private_u.nt_pw));
109
110                 if((*user)->private_u.plaintext_pw!=NULL)
111                         memset((*user)->private_u.plaintext_pw,'\0',strlen((*user)->private_u.plaintext_pw));
112                 talloc_destroy((*user)->mem_ctx);
113                 *user = NULL;
114         }
115 }
116
117
118 /**********************************************************************
119  Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.
120 ***********************************************************************/
121
122 NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
123 {
124         if (*user != NULL) {
125                 DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
126 #if 0
127                 smb_panic("non-NULL pointer passed to pdb_init_sam\n");
128 #endif
129                 return NT_STATUS_UNSUCCESSFUL;
130         }
131
132         if (!mem_ctx) {
133                 DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
134                 return NT_STATUS_UNSUCCESSFUL;
135         }
136
137         *user=TALLOC_P(mem_ctx, SAM_ACCOUNT);
138
139         if (*user==NULL) {
140                 DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
141                 return NT_STATUS_NO_MEMORY;
142         }
143
144         (*user)->mem_ctx = mem_ctx;
145
146         (*user)->free_fn = NULL;
147
148         pdb_fill_default_sam(*user);
149         
150         return NT_STATUS_OK;
151 }
152
153
154 /*************************************************************
155  Allocates memory and initialises a struct sam_passwd.
156  ************************************************************/
157
158 NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
159 {
160         TALLOC_CTX *mem_ctx;
161         NTSTATUS nt_status;
162         
163         mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");
164
165         if (!mem_ctx) {
166                 DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
167                 return NT_STATUS_NO_MEMORY;
168         }
169
170         if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
171                 talloc_destroy(mem_ctx);
172                 return nt_status;
173         }
174         
175         (*user)->free_fn = destroy_pdb_talloc;
176
177         return NT_STATUS_OK;
178 }
179
180 /**************************************************************************
181  * This function will take care of all the steps needed to correctly
182  * allocate and set the user SID, please do use this function to create new
183  * users, messing with SIDs is not good.
184  *
185  * account_data must be provided initialized, pwd may be null.
186  *                                                                      SSS
187  ***************************************************************************/
188
189 static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
190 {
191         const char *guest_account = lp_guestaccount();
192         GROUP_MAP map;
193         BOOL ret;
194         
195         if (!account_data || !pwd) {
196                 return NT_STATUS_INVALID_PARAMETER;
197         }
198
199         /* this is a hack this thing should not be set
200            this way --SSS */
201         if (!(guest_account && *guest_account)) {
202                 DEBUG(1, ("NULL guest account!?!?\n"));
203                 return NT_STATUS_UNSUCCESSFUL;
204         } else {
205                 /* Ensure this *must* be set right */
206                 if (strcmp(pwd->pw_name, guest_account) == 0) {
207                         if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
208                                 return NT_STATUS_UNSUCCESSFUL;
209                         }
210                         
211                         /* by default the guest account is a member of of the domain users group
212                            as well as the domain guests group.  Verified against Windows NT - 2003 */
213                            
214                         if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT)) {
215                                 return NT_STATUS_UNSUCCESSFUL;
216                         }
217                         return NT_STATUS_OK;
218                 }
219         }
220
221         if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
222                 DEBUG(0,("Can't set User SID from RID!\n"));
223                 return NT_STATUS_INVALID_PARAMETER;
224         }
225         
226         /* call the mapping code here */
227         become_root();
228         ret = pdb_getgrgid(&map, pwd->pw_gid);
229         unbecome_root();
230         
231         if( ret ) {
232                 if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
233                         DEBUG(0,("Can't set Group SID!\n"));
234                         return NT_STATUS_INVALID_PARAMETER;
235                 }
236         } 
237         else {
238                 if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
239                         DEBUG(0,("Can't set Group SID\n"));
240                         return NT_STATUS_INVALID_PARAMETER;
241                 }
242         }
243
244         return NT_STATUS_OK;
245 }
246
247 /*************************************************************
248  Initialises a struct sam_passwd with sane values.
249  ************************************************************/
250
251 NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
252 {
253         NTSTATUS ret;
254
255         if (!pwd) {
256                 return NT_STATUS_UNSUCCESSFUL;
257         }
258
259         pdb_fill_default_sam(sam_account);
260
261         pdb_set_username(sam_account, pwd->pw_name, PDB_SET);
262         pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);
263
264         pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);
265
266         pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);
267         
268         /* When we get a proper uid -> SID and SID -> uid allocation
269            mechinism, we should call it here.  
270            
271            We can't just set this to 0 or allow it only to be filled
272            in when added to the backend, because the user's SID 
273            may already be in security descriptors etc.
274            
275            -- abartlet 11-May-02
276         */
277
278         ret = pdb_set_sam_sids(sam_account, pwd);
279         if (!NT_STATUS_IS_OK(ret)) return ret;
280
281         /* check if this is a user account or a machine account */
282         if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
283         {
284                 pdb_set_profile_path(sam_account, 
285                                      talloc_sub_specified((sam_account)->mem_ctx, 
286                                                             lp_logon_path(), 
287                                                             pwd->pw_name, global_myname(), 
288                                                             pwd->pw_uid, pwd->pw_gid), 
289                                      PDB_DEFAULT);
290                 
291                 pdb_set_homedir(sam_account, 
292                                 talloc_sub_specified((sam_account)->mem_ctx, 
293                                                        lp_logon_home(),
294                                                        pwd->pw_name, global_myname(), 
295                                                        pwd->pw_uid, pwd->pw_gid),
296                                 PDB_DEFAULT);
297                 
298                 pdb_set_dir_drive(sam_account, 
299                                   talloc_sub_specified((sam_account)->mem_ctx, 
300                                                          lp_logon_drive(),
301                                                          pwd->pw_name, global_myname(), 
302                                                          pwd->pw_uid, pwd->pw_gid),
303                                   PDB_DEFAULT);
304                 
305                 pdb_set_logon_script(sam_account, 
306                                      talloc_sub_specified((sam_account)->mem_ctx, 
307                                                             lp_logon_script(),
308                                                             pwd->pw_name, global_myname(), 
309                                                             pwd->pw_uid, pwd->pw_gid), 
310                                      PDB_DEFAULT);
311                 if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {
312                         DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
313                         return NT_STATUS_UNSUCCESSFUL;
314                 }
315         } else {
316                 if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {
317                         DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
318                         return NT_STATUS_UNSUCCESSFUL;
319                 }
320         }
321         return NT_STATUS_OK;
322 }
323
324
325 /*************************************************************
326  Initialises a struct sam_passwd with sane values.
327  ************************************************************/
328
329 NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
330 {
331         NTSTATUS nt_status;
332
333         if (!pwd) {
334                 new_sam_acct = NULL;
335                 return NT_STATUS_INVALID_PARAMETER;
336         }
337
338         if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
339                 new_sam_acct = NULL;
340                 return nt_status;
341         }
342
343         if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
344                 pdb_free_sam(new_sam_acct);
345                 new_sam_acct = NULL;
346                 return nt_status;
347         }
348
349         return NT_STATUS_OK;
350 }
351
352
353 /*************************************************************
354  Initialises a SAM_ACCOUNT ready to add a new account, based
355  on the UNIX user.  Pass in a RID if you have one
356  ************************************************************/
357
358 NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username)
359 {
360         NTSTATUS        result;
361         struct passwd   *pwd;
362         uint32 user_rid;
363         DOM_SID user_sid, group_sid;
364         TALLOC_CTX *mem_ctx;
365         enum SID_NAME_USE type;
366
367         mem_ctx = talloc_new(NULL);
368         if (mem_ctx == NULL) {
369                 DEBUG(0, ("talloc_new failed\n"));
370                 return NT_STATUS_NO_MEMORY;
371         }
372         
373         pwd = Get_Pwnam_alloc(mem_ctx, username);
374
375         if (pwd == NULL) {
376                 DEBUG(10, ("Could not find user %s\n", username));
377                 result = NT_STATUS_NO_SUCH_USER;
378                 goto done;
379         }
380
381         result = pdb_init_sam_pw(new_sam_acct, pwd);
382         if (!NT_STATUS_IS_OK(result)) {
383                 DEBUG(10, ("pdb_init_sam_pw failed: %s\n", nt_errstr(result)));
384                 goto done;
385         }
386                 
387         if (pdb_rid_algorithm()) {
388                 if (!pdb_set_user_sid_from_rid(
389                             *new_sam_acct,
390                             algorithmic_pdb_uid_to_user_rid(pwd->pw_uid),
391                             PDB_SET)) {
392                         result = NT_STATUS_INTERNAL_ERROR;
393                         goto done;
394                 }
395                 if (!pdb_set_group_sid_from_rid(
396                             *new_sam_acct, pdb_gid_to_group_rid(pwd->pw_gid),
397                             PDB_SET)) {
398                         result = NT_STATUS_INTERNAL_ERROR;
399                         goto done;
400                 }
401                 result = NT_STATUS_OK;
402                 goto done;
403         }
404
405         /* No algorithmic mapping, meaning that we have to figure out the
406          * primary group SID according to group mapping and the user SID must
407          * be a newly allocated one */
408
409         if (!pdb_gid_to_sid(pwd->pw_gid, &group_sid)) {
410                 struct group *grp;
411                 GROUP_MAP map;
412
413                 grp = getgrgid(pwd->pw_gid);
414                 if (grp == NULL) {
415                         DEBUG(1, ("Primary group %d of user %s does not "
416                                   "exist.\n", pwd->pw_gid, username));
417                         result = NT_STATUS_INVALID_PRIMARY_GROUP;
418                         goto done;
419                 }
420
421                 DEBUG(5, ("Primary group %s of user %s is not mapped to "
422                           "a domain group, auto-mapping it\n",
423                           grp->gr_name, username));
424                 result = map_unix_group(grp, &map);
425                 if (!NT_STATUS_IS_OK(result)) {
426                         DEBUG(1, ("Failed to map group %s\n", grp->gr_name));
427                         goto done;
428                 }
429                 sid_copy(&group_sid, &map.sid);
430                 DEBUG(5, ("Mapped unix group %s to SID %s\n",
431                           grp->gr_name, sid_string_static(&group_sid)));
432         }
433
434         /* Now check that it's actually a domain group and not something
435          * else */
436
437         if (!lookup_sid(mem_ctx, &group_sid, NULL, NULL, &type)) {
438                 DEBUG(3, ("Could not lookup %s's primary group sid %s\n",
439                           username, sid_string_static(&group_sid)));
440                 result = NT_STATUS_INVALID_PRIMARY_GROUP;
441                 goto done;
442         }
443
444         if (type != SID_NAME_DOM_GRP) {
445                 DEBUG(3, ("Primary group for user %s is a %s and not a domain "
446                           "group\n", username, sid_type_lookup(type)));
447                 result = NT_STATUS_INVALID_PRIMARY_GROUP;
448                 goto done;
449         }
450
451         if (!pdb_set_group_sid(*new_sam_acct, &group_sid, PDB_SET)) {
452                 DEBUG(3, ("Could not set group SID\n"));
453                 result = NT_STATUS_INTERNAL_ERROR;
454                 goto done;
455         }
456
457         if (!pdb_new_rid(&user_rid)) {
458                 DEBUG(3, ("Could not allocate a new RID\n"));
459                 result = NT_STATUS_ACCESS_DENIED;
460                 goto done;
461         }
462
463         sid_copy(&user_sid, get_global_sam_sid());
464         sid_append_rid(&user_sid, user_rid);
465
466         if (!pdb_set_user_sid(*new_sam_acct, &user_sid, PDB_SET)) {
467                 DEBUG(3, ("pdb_set_user_sid failed\n"));
468                 result = NT_STATUS_INTERNAL_ERROR;
469                 goto done;
470         }
471
472         result = NT_STATUS_OK;
473
474  done:
475         if (!NT_STATUS_IS_OK(result) && (*new_sam_acct != NULL)) {
476                 pdb_free_sam(new_sam_acct);
477         }
478
479         talloc_free(mem_ctx);
480         return result;
481 }
482
483
484 /**
485  * Free the contets of the SAM_ACCOUNT, but not the structure.
486  *
487  * Also wipes the LM and NT hashes and plaintext password from 
488  * memory.
489  *
490  * @param user SAM_ACCOUNT to free members of.
491  **/
492
493 static void pdb_free_sam_contents(SAM_ACCOUNT *user)
494 {
495
496         /* Kill off sensitive data.  Free()ed by the
497            talloc mechinism */
498
499         data_blob_clear_free(&(user->private_u.lm_pw));
500         data_blob_clear_free(&(user->private_u.nt_pw));
501         if (user->private_u.plaintext_pw!=NULL)
502                 memset(user->private_u.plaintext_pw,'\0',strlen(user->private_u.plaintext_pw));
503
504         if (user->private_u.backend_private_data && user->private_u.backend_private_data_free_fn) {
505                 user->private_u.backend_private_data_free_fn(&user->private_u.backend_private_data);
506         }
507 }
508
509
510 /************************************************************
511  Reset the SAM_ACCOUNT and free the NT/LM hashes.
512  ***********************************************************/
513
514 NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
515 {
516         if (user == NULL) {
517                 DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
518 #if 0
519                 smb_panic("NULL pointer passed to pdb_free_sam\n");
520 #endif
521                 return NT_STATUS_UNSUCCESSFUL;
522         }
523         
524         pdb_free_sam_contents(user);
525
526         pdb_fill_default_sam(user);
527
528         return NT_STATUS_OK;
529 }
530
531
532 /************************************************************
533  Free the SAM_ACCOUNT and the member pointers.
534  ***********************************************************/
535
536 NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
537 {
538         if (*user == NULL) {
539                 DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
540 #if 0
541                 smb_panic("NULL pointer passed to pdb_free_sam\n");
542 #endif
543                 return NT_STATUS_UNSUCCESSFUL;
544         }
545
546         pdb_free_sam_contents(*user);
547         
548         if ((*user)->free_fn) {
549                 (*user)->free_fn(user);
550         }
551
552         return NT_STATUS_OK;    
553 }
554
555 /**********************************************************
556  Encode the account control bits into a string.
557  length = length of string to encode into (including terminating
558  null). length *MUST BE MORE THAN 2* !
559  **********************************************************/
560
561 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
562 {
563         static fstring acct_str;
564
565         size_t i = 0;
566
567         SMB_ASSERT(length <= sizeof(acct_str));
568
569         acct_str[i++] = '[';
570
571         if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
572         if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
573         if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
574         if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
575         if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
576         if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
577         if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
578         if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
579         if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
580         if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
581         if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
582
583         for ( ; i < length - 2 ; i++ )
584                 acct_str[i] = ' ';
585
586         i = length - 2;
587         acct_str[i++] = ']';
588         acct_str[i++] = '\0';
589
590         return acct_str;
591 }     
592
593 /**********************************************************
594  Decode the account control bits from a string.
595  **********************************************************/
596
597 uint16 pdb_decode_acct_ctrl(const char *p)
598 {
599         uint16 acct_ctrl = 0;
600         BOOL finished = False;
601
602         /*
603          * Check if the account type bits have been encoded after the
604          * NT password (in the form [NDHTUWSLXI]).
605          */
606
607         if (*p != '[')
608                 return 0;
609
610         for (p++; *p && !finished; p++) {
611                 switch (*p) {
612                         case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
613                         case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
614                         case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
615                         case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
616                         case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
617                         case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
618                         case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
619                         case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
620                         case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
621                         case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
622                         case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
623             case ' ': { break; }
624                         case ':':
625                         case '\n':
626                         case '\0': 
627                         case ']':
628                         default:  { finished = True; }
629                 }
630         }
631
632         return acct_ctrl;
633 }
634
635 /*************************************************************
636  Routine to set 32 hex password characters from a 16 byte array.
637 **************************************************************/
638
639 void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
640 {
641         if (pwd != NULL) {
642                 int i;
643                 for (i = 0; i < 16; i++)
644                         slprintf(&p[i*2], 3, "%02X", pwd[i]);
645         } else {
646                 if (acct_ctrl & ACB_PWNOTREQ)
647                         safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
648                 else
649                         safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
650         }
651 }
652
653 /*************************************************************
654  Routine to get the 32 hex characters and turn them
655  into a 16 byte array.
656 **************************************************************/
657
658 BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
659 {
660         int i;
661         unsigned char   lonybble, hinybble;
662         const char      *hexchars = "0123456789ABCDEF";
663         char           *p1, *p2;
664         
665         if (!p)
666                 return (False);
667         
668         for (i = 0; i < 32; i += 2) {
669                 hinybble = toupper_ascii(p[i]);
670                 lonybble = toupper_ascii(p[i + 1]);
671
672                 p1 = strchr(hexchars, hinybble);
673                 p2 = strchr(hexchars, lonybble);
674
675                 if (!p1 || !p2)
676                         return (False);
677
678                 hinybble = PTR_DIFF(p1, hexchars);
679                 lonybble = PTR_DIFF(p2, hexchars);
680
681                 pwd[i / 2] = (hinybble << 4) | lonybble;
682         }
683         return (True);
684 }
685
686 /*************************************************************
687  Routine to set 42 hex hours characters from a 21 byte array.
688 **************************************************************/
689
690 void pdb_sethexhours(char *p, const unsigned char *hours)
691 {
692         if (hours != NULL) {
693                 int i;
694                 for (i = 0; i < 21; i++) {
695                         slprintf(&p[i*2], 3, "%02X", hours[i]);
696                 }
697         } else {
698                 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
699         }
700 }
701
702 /*************************************************************
703  Routine to get the 42 hex characters and turn them
704  into a 21 byte array.
705 **************************************************************/
706
707 BOOL pdb_gethexhours(const char *p, unsigned char *hours)
708 {
709         int i;
710         unsigned char   lonybble, hinybble;
711         const char      *hexchars = "0123456789ABCDEF";
712         char           *p1, *p2;
713
714         if (!p) {
715                 return (False);
716         }
717
718         for (i = 0; i < 42; i += 2) {
719                 hinybble = toupper_ascii(p[i]);
720                 lonybble = toupper_ascii(p[i + 1]);
721
722                 p1 = strchr(hexchars, hinybble);
723                 p2 = strchr(hexchars, lonybble);
724
725                 if (!p1 || !p2) {
726                         return (False);
727                 }
728
729                 hinybble = PTR_DIFF(p1, hexchars);
730                 lonybble = PTR_DIFF(p2, hexchars);
731
732                 hours[i / 2] = (hinybble << 4) | lonybble;
733         }
734         return (True);
735 }
736
737 int algorithmic_rid_base(void)
738 {
739         static int rid_offset = 0;
740
741         if (rid_offset != 0)
742                 return rid_offset;
743
744         rid_offset = lp_algorithmic_rid_base();
745
746         if (rid_offset < BASE_RID) {  
747                 /* Try to prevent admin foot-shooting, we can't put algorithmic
748                    rids below 1000, that's the 'well known RIDs' on NT */
749                 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
750                 rid_offset = BASE_RID;
751         }
752         if (rid_offset & 1) {
753                 DEBUG(0, ("algorithmic rid base must be even\n"));
754                 rid_offset += 1;
755         }
756         return rid_offset;
757 }
758
759 /*******************************************************************
760  Converts NT user RID to a UNIX uid.
761  ********************************************************************/
762
763 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
764 {
765         int rid_offset = algorithmic_rid_base();
766         return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
767 }
768
769 uid_t max_algorithmic_uid(void)
770 {
771         return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
772 }
773
774 /*******************************************************************
775  converts UNIX uid to an NT User RID.
776  ********************************************************************/
777
778 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
779 {
780         int rid_offset = algorithmic_rid_base();
781         return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
782 }
783
784 /*******************************************************************
785  Converts NT group RID to a UNIX gid.
786  ********************************************************************/
787
788 gid_t pdb_group_rid_to_gid(uint32 group_rid)
789 {
790         int rid_offset = algorithmic_rid_base();
791         return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
792 }
793
794 gid_t max_algorithmic_gid(void)
795 {
796         return pdb_group_rid_to_gid(0xffffffff);
797 }
798
799 /*******************************************************************
800  converts NT Group RID to a UNIX uid.
801  
802  warning: you must not call that function only
803  you must do a call to the group mapping first.
804  there is not anymore a direct link between the gid and the rid.
805  ********************************************************************/
806
807 uint32 pdb_gid_to_group_rid(gid_t gid)
808 {
809         int rid_offset = algorithmic_rid_base();
810         return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
811 }
812
813 /*******************************************************************
814  Decides if a RID is a well known RID.
815  ********************************************************************/
816
817 static BOOL pdb_rid_is_well_known(uint32 rid)
818 {
819         /* Not using rid_offset here, because this is the actual
820            NT fixed value (1000) */
821
822         return (rid < BASE_RID);
823 }
824
825 /*******************************************************************
826  Decides if a RID is a user or group RID.
827  ********************************************************************/
828
829 BOOL algorithmic_pdb_rid_is_user(uint32 rid)
830 {
831         if(pdb_rid_is_well_known(rid)) {
832                 /*
833                  * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
834                  * and DOMAIN_USER_RID_GUEST.
835                  */
836                 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
837                         return True;
838         } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
839                 return True;
840         }
841         return False;
842 }
843
844 /*******************************************************************
845  Convert a name into a SID. Used in the lookup name rpc.
846  ********************************************************************/
847
848 BOOL lookup_global_sam_name(const char *user, int flags, uint32_t *rid,
849                             enum SID_NAME_USE *type)
850 {
851         GROUP_MAP map;
852         BOOL ret;
853
854         /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
855          * correctly in the case where foo also exists as a user. If the flag
856          * is set, don't look for users at all. */
857
858         if ((flags & LOOKUP_NAME_GROUP) == 0) {
859                 SAM_ACCOUNT *sam_account = NULL;
860                 DOM_SID user_sid;
861
862                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
863                         return False;
864                 }
865         
866                 become_root();
867                 ret =  pdb_getsampwnam(sam_account, user);
868                 unbecome_root();
869
870                 if (ret) {
871                         sid_copy(&user_sid, pdb_get_user_sid(sam_account));
872                 }
873                 
874                 pdb_free_sam(&sam_account);
875
876                 if (ret) {
877                         if (!sid_check_is_in_our_domain(&user_sid)) {
878                                 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
879                                           user, sid_string_static(&user_sid)));
880                                 return False;
881                         }
882
883                         sid_peek_rid(&user_sid, rid);
884                         *type = SID_NAME_USER;
885                         return True;
886                 }
887         }
888
889         /*
890          * Maybe it is a group ?
891          */
892
893         become_root();
894         ret = pdb_getgrnam(&map, user);
895         unbecome_root();
896
897         if (!ret) {
898                 return False;
899         }
900
901         /* BUILTIN groups are looked up elsewhere */
902         if (!sid_check_is_in_our_domain(&map.sid)) {
903                 DEBUG(10, ("Found group %s (%s) not in our domain -- "
904                            "ignoring.", user,
905                            sid_string_static(&map.sid)));
906                 return False;
907         }
908
909         /* yes it's a mapped group */
910         sid_peek_rid(&map.sid, rid);
911         *type = map.sid_name_use;
912         return True;
913 }
914
915 /*************************************************************
916  Change a password entry in the local smbpasswd file.
917  *************************************************************/
918
919 NTSTATUS local_password_change(const char *user_name, int local_flags,
920                            const char *new_passwd, 
921                            char *err_str, size_t err_str_len,
922                            char *msg_str, size_t msg_str_len)
923 {
924         SAM_ACCOUNT     *sam_pass=NULL;
925         uint16 other_acb;
926         NTSTATUS result;
927
928         *err_str = '\0';
929         *msg_str = '\0';
930
931         /* Get the smb passwd entry for this user */
932         pdb_init_sam(&sam_pass);
933
934         become_root();
935         if(!pdb_getsampwnam(sam_pass, user_name)) {
936                 unbecome_root();
937                 pdb_free_sam(&sam_pass);
938                 
939                 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
940                         int tmp_debug = DEBUGLEVEL;
941
942                         /* Might not exist in /etc/passwd. */
943
944                         if (tmp_debug < 1) {
945                                 DEBUGLEVEL = 1;
946                         }
947
948                         result = pdb_init_sam_new(&sam_pass, user_name);
949                         DEBUGLEVEL = tmp_debug;
950                         if (NT_STATUS_EQUAL(result,
951                                             NT_STATUS_INVALID_PRIMARY_GROUP)) {
952                                 return result;
953                         }
954
955                         if (!NT_STATUS_IS_OK(result)) {
956                                 slprintf(err_str, err_str_len-1, "Failed to "
957                                          "initialize account for user %s: %s\n",
958                                          user_name, nt_errstr(result));
959                                 return result;
960                         }
961                 } else {
962                         slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
963                         return NT_STATUS_NO_SUCH_USER;
964                 }
965         } else {
966                 unbecome_root();
967                 /* the entry already existed */
968                 local_flags &= ~LOCAL_ADD_USER;
969         }
970
971         /* the 'other' acb bits not being changed here */
972         other_acb =  (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
973         if (local_flags & LOCAL_TRUST_ACCOUNT) {
974                 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
975                         slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
976                         pdb_free_sam(&sam_pass);
977                         return NT_STATUS_UNSUCCESSFUL;
978                 }
979         } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
980                 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
981                         slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
982                         pdb_free_sam(&sam_pass);
983                         return NT_STATUS_UNSUCCESSFUL;
984                 }
985         } else {
986                 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
987                         slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
988                         pdb_free_sam(&sam_pass);
989                         return NT_STATUS_UNSUCCESSFUL;
990                 }
991         }
992
993         /*
994          * We are root - just write the new password
995          * and the valid last change time.
996          */
997
998         if (local_flags & LOCAL_DISABLE_USER) {
999                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1000                         slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1001                         pdb_free_sam(&sam_pass);
1002                         return NT_STATUS_UNSUCCESSFUL;
1003                 }
1004         } else if (local_flags & LOCAL_ENABLE_USER) {
1005                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1006                         slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1007                         pdb_free_sam(&sam_pass);
1008                         return NT_STATUS_UNSUCCESSFUL;
1009                 }
1010         }
1011         
1012         if (local_flags & LOCAL_SET_NO_PASSWORD) {
1013                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1014                         slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1015                         pdb_free_sam(&sam_pass);
1016                         return NT_STATUS_UNSUCCESSFUL;
1017                 }
1018         } else if (local_flags & LOCAL_SET_PASSWORD) {
1019                 /*
1020                  * If we're dealing with setting a completely empty user account
1021                  * ie. One with a password of 'XXXX', but not set disabled (like
1022                  * an account created from scratch) then if the old password was
1023                  * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1024                  * We remove that as we're giving this user their first password
1025                  * and the decision hasn't really been made to disable them (ie.
1026                  * don't create them disabled). JRA.
1027                  */
1028                 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1029                         if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1030                                 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1031                                 pdb_free_sam(&sam_pass);
1032                                 return NT_STATUS_UNSUCCESSFUL;
1033                         }
1034                 }
1035                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1036                         slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1037                         pdb_free_sam(&sam_pass);
1038                         return NT_STATUS_UNSUCCESSFUL;
1039                 }
1040                 
1041                 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1042                         slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1043                         pdb_free_sam(&sam_pass);
1044                         return NT_STATUS_UNSUCCESSFUL;
1045                 }
1046         }       
1047
1048         if (local_flags & LOCAL_ADD_USER) {
1049                 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
1050                         slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1051                         pdb_free_sam(&sam_pass);
1052                         return NT_STATUS_OK;
1053                 } else {
1054                         slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1055                         pdb_free_sam(&sam_pass);
1056                         return NT_STATUS_UNSUCCESSFUL;
1057                 }
1058         } else if (local_flags & LOCAL_DELETE_USER) {
1059                 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
1060                         slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1061                         pdb_free_sam(&sam_pass);
1062                         return NT_STATUS_UNSUCCESSFUL;
1063                 }
1064                 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1065         } else {
1066                 result = pdb_update_sam_account(sam_pass);
1067                 if(!NT_STATUS_IS_OK(result)) {
1068                         slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1069                         pdb_free_sam(&sam_pass);
1070                         return result;
1071                 }
1072                 if(local_flags & LOCAL_DISABLE_USER)
1073                         slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1074                 else if (local_flags & LOCAL_ENABLE_USER)
1075                         slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1076                 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1077                         slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1078         }
1079
1080         pdb_free_sam(&sam_pass);
1081         return NT_STATUS_OK;
1082 }
1083
1084 /**********************************************************************
1085  Marshall/unmarshall SAM_ACCOUNT structs.
1086  *********************************************************************/
1087
1088 #define TDB_FORMAT_STRING_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1089 #define TDB_FORMAT_STRING_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1090 #define TDB_FORMAT_STRING_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1091
1092 /**********************************************************************
1093  Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1094  *********************************************************************/
1095
1096 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1097 {
1098         return(init_sam_from_buffer_v2(sampass, buf, buflen));
1099 }
1100
1101 /**********************************************************************
1102  Intialize a BYTE buffer from a SAM_ACCOUNT struct
1103  *********************************************************************/
1104
1105 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1106 {
1107         return(init_buffer_from_sam_v2(buf, sampass, size_only));
1108 }
1109
1110
1111 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1112 {
1113
1114         /* times are stored as 32bit integer
1115            take care on system with 64bit wide time_t
1116            --SSS */
1117         uint32  logon_time,
1118                 logoff_time,
1119                 kickoff_time,
1120                 pass_last_set_time,
1121                 pass_can_change_time,
1122                 pass_must_change_time;
1123         char *username = NULL;
1124         char *domain = NULL;
1125         char *nt_username = NULL;
1126         char *dir_drive = NULL;
1127         char *unknown_str = NULL;
1128         char *munged_dial = NULL;
1129         char *fullname = NULL;
1130         char *homedir = NULL;
1131         char *logon_script = NULL;
1132         char *profile_path = NULL;
1133         char *acct_desc = NULL;
1134         char *workstations = NULL;
1135         uint32  username_len, domain_len, nt_username_len,
1136                 dir_drive_len, unknown_str_len, munged_dial_len,
1137                 fullname_len, homedir_len, logon_script_len,
1138                 profile_path_len, acct_desc_len, workstations_len;
1139                 
1140         uint32  user_rid, group_rid, remove_me, hours_len, unknown_6;
1141         uint16  acct_ctrl, logon_divs;
1142         uint16  bad_password_count, logon_count;
1143         uint8   *hours = NULL;
1144         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1145         uint32          len = 0;
1146         uint32          lm_pw_len, nt_pw_len, hourslen;
1147         BOOL ret = True;
1148         
1149         if(sampass == NULL || buf == NULL) {
1150                 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1151                 return False;
1152         }
1153
1154 /* TDB_FORMAT_STRING_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1155
1156         /* unpack the buffer into variables */
1157         len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1158                 &logon_time,                                            /* d */
1159                 &logoff_time,                                           /* d */
1160                 &kickoff_time,                                          /* d */
1161                 &pass_last_set_time,                                    /* d */
1162                 &pass_can_change_time,                                  /* d */
1163                 &pass_must_change_time,                                 /* d */
1164                 &username_len, &username,                               /* B */
1165                 &domain_len, &domain,                                   /* B */
1166                 &nt_username_len, &nt_username,                         /* B */
1167                 &fullname_len, &fullname,                               /* B */
1168                 &homedir_len, &homedir,                                 /* B */
1169                 &dir_drive_len, &dir_drive,                             /* B */
1170                 &logon_script_len, &logon_script,                       /* B */
1171                 &profile_path_len, &profile_path,                       /* B */
1172                 &acct_desc_len, &acct_desc,                             /* B */
1173                 &workstations_len, &workstations,                       /* B */
1174                 &unknown_str_len, &unknown_str,                         /* B */
1175                 &munged_dial_len, &munged_dial,                         /* B */
1176                 &user_rid,                                              /* d */
1177                 &group_rid,                                             /* d */
1178                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
1179                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
1180                 &acct_ctrl,                                             /* w */
1181                 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1182                 &logon_divs,                                            /* w */
1183                 &hours_len,                                             /* d */
1184                 &hourslen, &hours,                                      /* B */
1185                 &bad_password_count,                                    /* w */
1186                 &logon_count,                                           /* w */
1187                 &unknown_6);                                            /* d */
1188                 
1189         if (len == (uint32) -1)  {
1190                 ret = False;
1191                 goto done;
1192         }
1193
1194         pdb_set_logon_time(sampass, logon_time, PDB_SET);
1195         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1196         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1197         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1198         pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1199         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1200
1201         pdb_set_username(sampass, username, PDB_SET); 
1202         pdb_set_domain(sampass, domain, PDB_SET);
1203         pdb_set_nt_username(sampass, nt_username, PDB_SET);
1204         pdb_set_fullname(sampass, fullname, PDB_SET);
1205
1206         if (homedir) {
1207                 pdb_set_homedir(sampass, homedir, PDB_SET);
1208         }
1209         else {
1210                 pdb_set_homedir(sampass, 
1211                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1212                         PDB_DEFAULT);
1213         }
1214
1215         if (dir_drive)  
1216                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1217         else {
1218                 pdb_set_dir_drive(sampass, 
1219                         talloc_sub_basic(sampass->mem_ctx,  username, lp_logon_drive()),
1220                         PDB_DEFAULT);
1221         }
1222
1223         if (logon_script) 
1224                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1225         else {
1226                 pdb_set_logon_script(sampass, 
1227                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1228                         PDB_DEFAULT);
1229         }
1230         
1231         if (profile_path) {     
1232                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1233         } else {
1234                 pdb_set_profile_path(sampass, 
1235                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1236                         PDB_DEFAULT);
1237         }
1238
1239         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1240         pdb_set_workstations(sampass, workstations, PDB_SET);
1241         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1242
1243         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1244                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1245                         ret = False;
1246                         goto done;
1247                 }
1248         }
1249
1250         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1251                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1252                         ret = False;
1253                         goto done;
1254                 }
1255         }
1256
1257         pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1258         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1259         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1260         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1261         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1262         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1263         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1264         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1265         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1266         pdb_set_hours(sampass, hours, PDB_SET);
1267
1268 done:
1269
1270         SAFE_FREE(username);
1271         SAFE_FREE(domain);
1272         SAFE_FREE(nt_username);
1273         SAFE_FREE(fullname);
1274         SAFE_FREE(homedir);
1275         SAFE_FREE(dir_drive);
1276         SAFE_FREE(logon_script);
1277         SAFE_FREE(profile_path);
1278         SAFE_FREE(acct_desc);
1279         SAFE_FREE(workstations);
1280         SAFE_FREE(munged_dial);
1281         SAFE_FREE(unknown_str);
1282         SAFE_FREE(lm_pw_ptr);
1283         SAFE_FREE(nt_pw_ptr);
1284         SAFE_FREE(hours);
1285
1286         return ret;
1287 }
1288
1289 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1290 {
1291
1292         /* times are stored as 32bit integer
1293            take care on system with 64bit wide time_t
1294            --SSS */
1295         uint32  logon_time,
1296                 logoff_time,
1297                 kickoff_time,
1298                 bad_password_time,
1299                 pass_last_set_time,
1300                 pass_can_change_time,
1301                 pass_must_change_time;
1302         char *username = NULL;
1303         char *domain = NULL;
1304         char *nt_username = NULL;
1305         char *dir_drive = NULL;
1306         char *unknown_str = NULL;
1307         char *munged_dial = NULL;
1308         char *fullname = NULL;
1309         char *homedir = NULL;
1310         char *logon_script = NULL;
1311         char *profile_path = NULL;
1312         char *acct_desc = NULL;
1313         char *workstations = NULL;
1314         uint32  username_len, domain_len, nt_username_len,
1315                 dir_drive_len, unknown_str_len, munged_dial_len,
1316                 fullname_len, homedir_len, logon_script_len,
1317                 profile_path_len, acct_desc_len, workstations_len;
1318                 
1319         uint32  user_rid, group_rid, remove_me, hours_len, unknown_6;
1320         uint16  acct_ctrl, logon_divs;
1321         uint16  bad_password_count, logon_count;
1322         uint8   *hours = NULL;
1323         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1324         uint32          len = 0;
1325         uint32          lm_pw_len, nt_pw_len, hourslen;
1326         BOOL ret = True;
1327         
1328         if(sampass == NULL || buf == NULL) {
1329                 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1330                 return False;
1331         }
1332
1333 /* TDB_FORMAT_STRING_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1334
1335         /* unpack the buffer into variables */
1336         len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1337                 &logon_time,                                            /* d */
1338                 &logoff_time,                                           /* d */
1339                 &kickoff_time,                                          /* d */
1340                 /* Change from V0 is addition of bad_password_time field. */
1341                 &bad_password_time,                                     /* d */
1342                 &pass_last_set_time,                                    /* d */
1343                 &pass_can_change_time,                                  /* d */
1344                 &pass_must_change_time,                                 /* d */
1345                 &username_len, &username,                               /* B */
1346                 &domain_len, &domain,                                   /* B */
1347                 &nt_username_len, &nt_username,                         /* B */
1348                 &fullname_len, &fullname,                               /* B */
1349                 &homedir_len, &homedir,                                 /* B */
1350                 &dir_drive_len, &dir_drive,                             /* B */
1351                 &logon_script_len, &logon_script,                       /* B */
1352                 &profile_path_len, &profile_path,                       /* B */
1353                 &acct_desc_len, &acct_desc,                             /* B */
1354                 &workstations_len, &workstations,                       /* B */
1355                 &unknown_str_len, &unknown_str,                         /* B */
1356                 &munged_dial_len, &munged_dial,                         /* B */
1357                 &user_rid,                                              /* d */
1358                 &group_rid,                                             /* d */
1359                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
1360                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
1361                 &acct_ctrl,                                             /* w */
1362                 &remove_me,                                             /* d */
1363                 &logon_divs,                                            /* w */
1364                 &hours_len,                                             /* d */
1365                 &hourslen, &hours,                                      /* B */
1366                 &bad_password_count,                                    /* w */
1367                 &logon_count,                                           /* w */
1368                 &unknown_6);                                            /* d */
1369                 
1370         if (len == (uint32) -1)  {
1371                 ret = False;
1372                 goto done;
1373         }
1374
1375         pdb_set_logon_time(sampass, logon_time, PDB_SET);
1376         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1377         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1378
1379         /* Change from V0 is addition of bad_password_time field. */
1380         pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1381         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1382         pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1383         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1384
1385         pdb_set_username(sampass, username, PDB_SET); 
1386         pdb_set_domain(sampass, domain, PDB_SET);
1387         pdb_set_nt_username(sampass, nt_username, PDB_SET);
1388         pdb_set_fullname(sampass, fullname, PDB_SET);
1389
1390         if (homedir) {
1391                 pdb_set_homedir(sampass, homedir, PDB_SET);
1392         }
1393         else {
1394                 pdb_set_homedir(sampass, 
1395                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1396                         PDB_DEFAULT);
1397         }
1398
1399         if (dir_drive)  
1400                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1401         else {
1402                 pdb_set_dir_drive(sampass, 
1403                         talloc_sub_basic(sampass->mem_ctx,  username, lp_logon_drive()),
1404                         PDB_DEFAULT);
1405         }
1406
1407         if (logon_script) 
1408                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1409         else {
1410                 pdb_set_logon_script(sampass, 
1411                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1412                         PDB_DEFAULT);
1413         }
1414         
1415         if (profile_path) {     
1416                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1417         } else {
1418                 pdb_set_profile_path(sampass, 
1419                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1420                         PDB_DEFAULT);
1421         }
1422
1423         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1424         pdb_set_workstations(sampass, workstations, PDB_SET);
1425         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1426
1427         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1428                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1429                         ret = False;
1430                         goto done;
1431                 }
1432         }
1433
1434         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1435                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1436                         ret = False;
1437                         goto done;
1438                 }
1439         }
1440
1441         pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1442
1443         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1444         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1445         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1446         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1447         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1448         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1449         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1450         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1451         pdb_set_hours(sampass, hours, PDB_SET);
1452
1453 done:
1454
1455         SAFE_FREE(username);
1456         SAFE_FREE(domain);
1457         SAFE_FREE(nt_username);
1458         SAFE_FREE(fullname);
1459         SAFE_FREE(homedir);
1460         SAFE_FREE(dir_drive);
1461         SAFE_FREE(logon_script);
1462         SAFE_FREE(profile_path);
1463         SAFE_FREE(acct_desc);
1464         SAFE_FREE(workstations);
1465         SAFE_FREE(munged_dial);
1466         SAFE_FREE(unknown_str);
1467         SAFE_FREE(lm_pw_ptr);
1468         SAFE_FREE(nt_pw_ptr);
1469         SAFE_FREE(hours);
1470
1471         return ret;
1472 }
1473
1474
1475 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1476 {
1477
1478         /* times are stored as 32bit integer
1479            take care on system with 64bit wide time_t
1480            --SSS */
1481         uint32  logon_time,
1482                 logoff_time,
1483                 kickoff_time,
1484                 bad_password_time,
1485                 pass_last_set_time,
1486                 pass_can_change_time,
1487                 pass_must_change_time;
1488         char *username = NULL;
1489         char *domain = NULL;
1490         char *nt_username = NULL;
1491         char *dir_drive = NULL;
1492         char *unknown_str = NULL;
1493         char *munged_dial = NULL;
1494         char *fullname = NULL;
1495         char *homedir = NULL;
1496         char *logon_script = NULL;
1497         char *profile_path = NULL;
1498         char *acct_desc = NULL;
1499         char *workstations = NULL;
1500         uint32  username_len, domain_len, nt_username_len,
1501                 dir_drive_len, unknown_str_len, munged_dial_len,
1502                 fullname_len, homedir_len, logon_script_len,
1503                 profile_path_len, acct_desc_len, workstations_len;
1504                 
1505         uint32  user_rid, group_rid, hours_len, unknown_6;
1506         uint16  acct_ctrl, logon_divs;
1507         uint16  bad_password_count, logon_count;
1508         uint8   *hours = NULL;
1509         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1510         uint32          len = 0;
1511         uint32          lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1512         uint32 pwHistLen = 0;
1513         BOOL ret = True;
1514         fstring tmpstring;
1515         BOOL expand_explicit = lp_passdb_expand_explicit();
1516         
1517         if(sampass == NULL || buf == NULL) {
1518                 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1519                 return False;
1520         }
1521                                                                         
1522 /* TDB_FORMAT_STRING_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1523
1524         /* unpack the buffer into variables */
1525         len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1526                 &logon_time,                                            /* d */
1527                 &logoff_time,                                           /* d */
1528                 &kickoff_time,                                          /* d */
1529                 &bad_password_time,                                     /* d */
1530                 &pass_last_set_time,                                    /* d */
1531                 &pass_can_change_time,                                  /* d */
1532                 &pass_must_change_time,                                 /* d */
1533                 &username_len, &username,                               /* B */
1534                 &domain_len, &domain,                                   /* B */
1535                 &nt_username_len, &nt_username,                         /* B */
1536                 &fullname_len, &fullname,                               /* B */
1537                 &homedir_len, &homedir,                                 /* B */
1538                 &dir_drive_len, &dir_drive,                             /* B */
1539                 &logon_script_len, &logon_script,                       /* B */
1540                 &profile_path_len, &profile_path,                       /* B */
1541                 &acct_desc_len, &acct_desc,                             /* B */
1542                 &workstations_len, &workstations,                       /* B */
1543                 &unknown_str_len, &unknown_str,                         /* B */
1544                 &munged_dial_len, &munged_dial,                         /* B */
1545                 &user_rid,                                              /* d */
1546                 &group_rid,                                             /* d */
1547                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
1548                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
1549                 /* Change from V1 is addition of password history field. */
1550                 &nt_pw_hist_len, &nt_pw_hist_ptr,                       /* B */
1551                 &acct_ctrl,                                             /* w */
1552                 /* Also "remove_me" field was removed. */
1553                 &logon_divs,                                            /* w */
1554                 &hours_len,                                             /* d */
1555                 &hourslen, &hours,                                      /* B */
1556                 &bad_password_count,                                    /* w */
1557                 &logon_count,                                           /* w */
1558                 &unknown_6);                                            /* d */
1559                 
1560         if (len == (uint32) -1)  {
1561                 ret = False;
1562                 goto done;
1563         }
1564
1565         pdb_set_logon_time(sampass, logon_time, PDB_SET);
1566         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1567         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1568         pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1569         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1570         pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1571         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1572
1573         pdb_set_username(sampass, username, PDB_SET); 
1574         pdb_set_domain(sampass, domain, PDB_SET);
1575         pdb_set_nt_username(sampass, nt_username, PDB_SET);
1576         pdb_set_fullname(sampass, fullname, PDB_SET);
1577
1578         if (homedir) {
1579                 fstrcpy( tmpstring, homedir );
1580                 if (expand_explicit) {
1581                         standard_sub_basic( username, tmpstring,
1582                                             sizeof(tmpstring) );
1583                 }
1584                 pdb_set_homedir(sampass, tmpstring, PDB_SET);
1585         }
1586         else {
1587                 pdb_set_homedir(sampass, 
1588                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1589                         PDB_DEFAULT);
1590         }
1591
1592         if (dir_drive)  
1593                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1594         else
1595                 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1596
1597         if (logon_script) {
1598                 fstrcpy( tmpstring, logon_script );
1599                 if (expand_explicit) {
1600                         standard_sub_basic( username, tmpstring,
1601                                             sizeof(tmpstring) );
1602                 }
1603                 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1604         }
1605         else {
1606                 pdb_set_logon_script(sampass, 
1607                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1608                         PDB_DEFAULT);
1609         }
1610         
1611         if (profile_path) {     
1612                 fstrcpy( tmpstring, profile_path );
1613                 if (expand_explicit) {
1614                         standard_sub_basic( username, tmpstring,
1615                                             sizeof(tmpstring) );
1616                 }
1617                 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1618         } 
1619         else {
1620                 pdb_set_profile_path(sampass, 
1621                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1622                         PDB_DEFAULT);
1623         }
1624
1625         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1626         pdb_set_workstations(sampass, workstations, PDB_SET);
1627         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1628
1629         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1630                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1631                         ret = False;
1632                         goto done;
1633                 }
1634         }
1635
1636         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1637                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1638                         ret = False;
1639                         goto done;
1640                 }
1641         }
1642
1643         /* Change from V1 is addition of password history field. */
1644         pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1645         if (pwHistLen) {
1646                 uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1647                 if (!pw_hist) {
1648                         ret = False;
1649                         goto done;
1650                 }
1651                 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1652                 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1653                         int i;
1654                         SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1655                         nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1656                         for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1657                                 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1658                                         &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1659                                         PW_HISTORY_ENTRY_LEN);
1660                         }
1661                 }
1662                 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1663                         SAFE_FREE(pw_hist);
1664                         ret = False;
1665                         goto done;
1666                 }
1667                 SAFE_FREE(pw_hist);
1668         } else {
1669                 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1670         }
1671
1672         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1673         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1674         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1675         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1676         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1677         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1678         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1679         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1680         pdb_set_hours(sampass, hours, PDB_SET);
1681
1682 done:
1683
1684         SAFE_FREE(username);
1685         SAFE_FREE(domain);
1686         SAFE_FREE(nt_username);
1687         SAFE_FREE(fullname);
1688         SAFE_FREE(homedir);
1689         SAFE_FREE(dir_drive);
1690         SAFE_FREE(logon_script);
1691         SAFE_FREE(profile_path);
1692         SAFE_FREE(acct_desc);
1693         SAFE_FREE(workstations);
1694         SAFE_FREE(munged_dial);
1695         SAFE_FREE(unknown_str);
1696         SAFE_FREE(lm_pw_ptr);
1697         SAFE_FREE(nt_pw_ptr);
1698         SAFE_FREE(nt_pw_hist_ptr);
1699         SAFE_FREE(hours);
1700
1701         return ret;
1702 }
1703
1704 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1705 {
1706         size_t len, buflen;
1707
1708         /* times are stored as 32bit integer
1709            take care on system with 64bit wide time_t
1710            --SSS */
1711         uint32  logon_time,
1712                 logoff_time,
1713                 kickoff_time,
1714                 bad_password_time,
1715                 pass_last_set_time,
1716                 pass_can_change_time,
1717                 pass_must_change_time;
1718
1719         uint32  user_rid, group_rid;
1720
1721         const char *username;
1722         const char *domain;
1723         const char *nt_username;
1724         const char *dir_drive;
1725         const char *unknown_str;
1726         const char *munged_dial;
1727         const char *fullname;
1728         const char *homedir;
1729         const char *logon_script;
1730         const char *profile_path;
1731         const char *acct_desc;
1732         const char *workstations;
1733         uint32  username_len, domain_len, nt_username_len,
1734                 dir_drive_len, unknown_str_len, munged_dial_len,
1735                 fullname_len, homedir_len, logon_script_len,
1736                 profile_path_len, acct_desc_len, workstations_len;
1737
1738         const uint8 *lm_pw;
1739         const uint8 *nt_pw;
1740         const uint8 *nt_pw_hist;
1741         uint32  lm_pw_len = 16;
1742         uint32  nt_pw_len = 16;
1743         uint32  nt_pw_hist_len;
1744         uint32 pwHistLen = 0;
1745
1746         /* do we have a valid SAM_ACCOUNT pointer? */
1747         if (sampass == NULL) {
1748                 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
1749                 return -1;
1750         }
1751         
1752         *buf = NULL;
1753         buflen = 0;
1754
1755         logon_time = (uint32)pdb_get_logon_time(sampass);
1756         logoff_time = (uint32)pdb_get_logoff_time(sampass);
1757         kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
1758         bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
1759         pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
1760         pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
1761         pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
1762
1763         user_rid = pdb_get_user_rid(sampass);
1764         group_rid = pdb_get_group_rid(sampass);
1765
1766         username = pdb_get_username(sampass);
1767         if (username) {
1768                 username_len = strlen(username) +1;
1769         } else {
1770                 username_len = 0;
1771         }
1772
1773         domain = pdb_get_domain(sampass);
1774         if (domain) {
1775                 domain_len = strlen(domain) +1;
1776         } else {
1777                 domain_len = 0;
1778         }
1779
1780         nt_username = pdb_get_nt_username(sampass);
1781         if (nt_username) {
1782                 nt_username_len = strlen(nt_username) +1;
1783         } else {
1784                 nt_username_len = 0;
1785         }
1786
1787         fullname = pdb_get_fullname(sampass);
1788         if (fullname) {
1789                 fullname_len = strlen(fullname) +1;
1790         } else {
1791                 fullname_len = 0;
1792         }
1793
1794         /*
1795          * Only updates fields which have been set (not defaults from smb.conf)
1796          */
1797
1798         if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1799                 dir_drive = pdb_get_dir_drive(sampass);
1800         } else {
1801                 dir_drive = NULL;
1802         }
1803         if (dir_drive) {
1804                 dir_drive_len = strlen(dir_drive) +1;
1805         } else {
1806                 dir_drive_len = 0;
1807         }
1808
1809         if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1810                 homedir = pdb_get_homedir(sampass);
1811         } else {
1812                 homedir = NULL;
1813         }
1814         if (homedir) {
1815                 homedir_len = strlen(homedir) +1;
1816         } else {
1817                 homedir_len = 0;
1818         }
1819
1820         if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1821                 logon_script = pdb_get_logon_script(sampass);
1822         } else {
1823                 logon_script = NULL;
1824         }
1825         if (logon_script) {
1826                 logon_script_len = strlen(logon_script) +1;
1827         } else {
1828                 logon_script_len = 0;
1829         }
1830
1831         if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1832                 profile_path = pdb_get_profile_path(sampass);
1833         } else {
1834                 profile_path = NULL;
1835         }
1836         if (profile_path) {
1837                 profile_path_len = strlen(profile_path) +1;
1838         } else {
1839                 profile_path_len = 0;
1840         }
1841         
1842         lm_pw = pdb_get_lanman_passwd(sampass);
1843         if (!lm_pw) {
1844                 lm_pw_len = 0;
1845         }
1846         
1847         nt_pw = pdb_get_nt_passwd(sampass);
1848         if (!nt_pw) {
1849                 nt_pw_len = 0;
1850         }
1851
1852         pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1853         nt_pw_hist =  pdb_get_pw_history(sampass, &nt_pw_hist_len);
1854         if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1855                 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1856         } else {
1857                 nt_pw_hist_len = 0;
1858         }
1859
1860         acct_desc = pdb_get_acct_desc(sampass);
1861         if (acct_desc) {
1862                 acct_desc_len = strlen(acct_desc) +1;
1863         } else {
1864                 acct_desc_len = 0;
1865         }
1866
1867         workstations = pdb_get_workstations(sampass);
1868         if (workstations) {
1869                 workstations_len = strlen(workstations) +1;
1870         } else {
1871                 workstations_len = 0;
1872         }
1873
1874         unknown_str = NULL;
1875         unknown_str_len = 0;
1876
1877         munged_dial = pdb_get_munged_dial(sampass);
1878         if (munged_dial) {
1879                 munged_dial_len = strlen(munged_dial) +1;
1880         } else {
1881                 munged_dial_len = 0;    
1882         }
1883
1884 /* TDB_FORMAT_STRING_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1885
1886         /* one time to get the size needed */
1887         len = tdb_pack(NULL, 0,  TDB_FORMAT_STRING_V2,
1888                 logon_time,                             /* d */
1889                 logoff_time,                            /* d */
1890                 kickoff_time,                           /* d */
1891                 bad_password_time,                      /* d */
1892                 pass_last_set_time,                     /* d */
1893                 pass_can_change_time,                   /* d */
1894                 pass_must_change_time,                  /* d */
1895                 username_len, username,                 /* B */
1896                 domain_len, domain,                     /* B */
1897                 nt_username_len, nt_username,           /* B */
1898                 fullname_len, fullname,                 /* B */
1899                 homedir_len, homedir,                   /* B */
1900                 dir_drive_len, dir_drive,               /* B */
1901                 logon_script_len, logon_script,         /* B */
1902                 profile_path_len, profile_path,         /* B */
1903                 acct_desc_len, acct_desc,               /* B */
1904                 workstations_len, workstations,         /* B */
1905                 unknown_str_len, unknown_str,           /* B */
1906                 munged_dial_len, munged_dial,           /* B */
1907                 user_rid,                               /* d */
1908                 group_rid,                              /* d */
1909                 lm_pw_len, lm_pw,                       /* B */
1910                 nt_pw_len, nt_pw,                       /* B */
1911                 nt_pw_hist_len, nt_pw_hist,             /* B */
1912                 pdb_get_acct_ctrl(sampass),             /* w */
1913                 pdb_get_logon_divs(sampass),            /* w */
1914                 pdb_get_hours_len(sampass),             /* d */
1915                 MAX_HOURS_LEN, pdb_get_hours(sampass),  /* B */
1916                 pdb_get_bad_password_count(sampass),    /* w */
1917                 pdb_get_logon_count(sampass),           /* w */
1918                 pdb_get_unknown_6(sampass));            /* d */
1919
1920         if (size_only) {
1921                 return buflen;
1922         }
1923
1924         /* malloc the space needed */
1925         if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
1926                 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
1927                 return (-1);
1928         }
1929         
1930         /* now for the real call to tdb_pack() */
1931         buflen = tdb_pack((char *)*buf, len,  TDB_FORMAT_STRING_V2,
1932                 logon_time,                             /* d */
1933                 logoff_time,                            /* d */
1934                 kickoff_time,                           /* d */
1935                 bad_password_time,                      /* d */
1936                 pass_last_set_time,                     /* d */
1937                 pass_can_change_time,                   /* d */
1938                 pass_must_change_time,                  /* d */
1939                 username_len, username,                 /* B */
1940                 domain_len, domain,                     /* B */
1941                 nt_username_len, nt_username,           /* B */
1942                 fullname_len, fullname,                 /* B */
1943                 homedir_len, homedir,                   /* B */
1944                 dir_drive_len, dir_drive,               /* B */
1945                 logon_script_len, logon_script,         /* B */
1946                 profile_path_len, profile_path,         /* B */
1947                 acct_desc_len, acct_desc,               /* B */
1948                 workstations_len, workstations,         /* B */
1949                 unknown_str_len, unknown_str,           /* B */
1950                 munged_dial_len, munged_dial,           /* B */
1951                 user_rid,                               /* d */
1952                 group_rid,                              /* d */
1953                 lm_pw_len, lm_pw,                       /* B */
1954                 nt_pw_len, nt_pw,                       /* B */
1955                 nt_pw_hist_len, nt_pw_hist,             /* B */
1956                 pdb_get_acct_ctrl(sampass),             /* w */
1957                 pdb_get_logon_divs(sampass),            /* w */
1958                 pdb_get_hours_len(sampass),             /* d */
1959                 MAX_HOURS_LEN, pdb_get_hours(sampass),  /* B */
1960                 pdb_get_bad_password_count(sampass),    /* w */
1961                 pdb_get_logon_count(sampass),           /* w */
1962                 pdb_get_unknown_6(sampass));            /* d */
1963         
1964         /* check to make sure we got it correct */
1965         if (buflen != len) {
1966                 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", 
1967                           (unsigned long)buflen, (unsigned long)len));  
1968                 /* error */
1969                 SAFE_FREE (*buf);
1970                 return (-1);
1971         }
1972
1973         return (buflen);
1974 }
1975
1976 BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
1977 {
1978         BOOL result;
1979         uint8 *buf;
1980         int len;
1981
1982         if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
1983                 return False;
1984
1985         len = init_buffer_from_sam_v2(&buf, src, False);
1986
1987         if (len == -1)
1988                 return False;
1989
1990         result = init_sam_from_buffer_v2(*dst, buf, len);
1991         (*dst)->methods = src->methods;
1992
1993         free(buf);
1994
1995         return result;
1996 }
1997
1998 /*********************************************************************
1999  Update the bad password count checking the AP_RESET_COUNT_TIME 
2000 *********************************************************************/
2001
2002 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2003 {
2004         time_t LastBadPassword;
2005         uint16 BadPasswordCount;
2006         uint32 resettime; 
2007
2008         if (!sampass) return False;
2009         
2010         BadPasswordCount = pdb_get_bad_password_count(sampass);
2011         if (!BadPasswordCount) {
2012                 DEBUG(9, ("No bad password attempts.\n"));
2013                 return True;
2014         }
2015
2016         if (!pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime)) {
2017                 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2018                 return False;
2019         }
2020
2021         /* First, check if there is a reset time to compare */
2022         if ((resettime == (uint32) -1) || (resettime == 0)) {
2023                 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2024                 return True;
2025         }
2026
2027         LastBadPassword = pdb_get_bad_password_time(sampass);
2028         DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n", 
2029                    (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2030         if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2031                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2032                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2033                 if (updated) {
2034                         *updated = True;
2035                 }
2036         }
2037
2038         return True;
2039 }
2040
2041 /*********************************************************************
2042  Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION 
2043 *********************************************************************/
2044
2045 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2046 {
2047         uint32 duration;
2048         time_t LastBadPassword;
2049
2050         if (!sampass) return False;
2051  
2052         if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2053                 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2054                         pdb_get_username(sampass)));
2055                 return True;
2056         }
2057
2058         if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2059                 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2060                 return False;
2061         }
2062
2063         /* First, check if there is a duration to compare */
2064         if ((duration == (uint32) -1)  || (duration == 0)) {
2065                 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2066                 return True;
2067         }
2068                       
2069         LastBadPassword = pdb_get_bad_password_time(sampass);
2070         DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2071                   pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2072
2073         if (LastBadPassword == (time_t)0) {
2074                 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2075 bad password time. Leaving locked out.\n",
2076                         pdb_get_username(sampass) ));
2077                         return True;
2078         }
2079
2080         if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2081                 pdb_set_acct_ctrl(sampass,
2082                                   pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2083                                   PDB_CHANGED);
2084                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2085                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2086                 if (updated) {
2087                         *updated = True;
2088                 }
2089         }
2090         
2091         return True;
2092 }
2093
2094 /*********************************************************************
2095  Increment the bad_password_count 
2096 *********************************************************************/
2097
2098 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2099 {
2100         uint32 account_policy_lockout;
2101         BOOL autolock_updated = False, badpw_updated = False;
2102         BOOL ret;
2103
2104         if (!sampass)
2105                 return False;
2106
2107         /* Retrieve the account lockout policy */
2108         become_root();
2109         ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2110         unbecome_root();
2111         if ( !ret ) {
2112                 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2113                 return False;
2114         }
2115
2116         /* If there is no policy, we don't need to continue checking */
2117         if (!account_policy_lockout) {
2118                 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2119                 return True;
2120         }
2121
2122         /* Check if the autolock needs to be cleared */
2123         if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2124                 return False;
2125
2126         /* Check if the badpw count needs to be reset */
2127         if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2128                 return False;
2129
2130         /*
2131           Ok, now we can assume that any resetting that needs to be 
2132           done has been done, and just get on with incrementing
2133           and autolocking if necessary
2134         */
2135
2136         pdb_set_bad_password_count(sampass, 
2137                                    pdb_get_bad_password_count(sampass)+1,
2138                                    PDB_CHANGED);
2139         pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2140
2141
2142         if (pdb_get_bad_password_count(sampass) < account_policy_lockout) 
2143                 return True;
2144
2145         if (!pdb_set_acct_ctrl(sampass,
2146                                pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2147                                PDB_CHANGED)) {
2148                 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); 
2149                 return False;
2150         }
2151
2152         return True;
2153 }