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