Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header.
[kai/samba.git] / source3 / passdb / passdb.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Password and authentication handling
5    Copyright (C) Jeremy Allison                 1996-2001
6    Copyright (C) Luke Kenneth Casson Leighton   1996-1998
7    Copyright (C) Gerald (Jerry) Carter          2000-2001
8       
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 /*
27  * This is set on startup - it defines the SID for this
28  * machine, and therefore the SAM database for which it is
29  * responsible.
30  */
31
32 extern DOM_SID global_sam_sid;
33
34 struct passdb_ops *pdb_ops;
35
36 #if 0   /* JERRY */
37 static void* pdb_handle = NULL;
38 #endif
39
40 /***************************************************************
41  Initialize the password db operations.
42 ***************************************************************/
43
44 BOOL initialize_password_db(BOOL reload)
45 {       
46         /* 
47          * This function is unfinished right now, so just 
48          * ignore the details and always return True.  It 
49          * is here only as a placeholder          --jerry 
50          */
51         return True;
52         
53 }
54
55 /*************************************************************
56  Initialises a struct sam_disp_info.
57  **************************************************************/
58
59 static void pdb_init_dispinfo(struct sam_disp_info *user)
60 {
61         if (user == NULL) 
62                 return;
63         ZERO_STRUCTP(user);
64 }
65
66
67 /************************************************************
68  Fill the SAM_ACCOUNT with default values.
69  ***********************************************************/
70
71 static BOOL pdb_fill_default_sam(SAM_ACCOUNT *user)
72 {
73         if (user == NULL) {
74                 DEBUG(0,("pdb_fill_default_sam: SAM_ACCOUNT was NULL\n"));
75                 return False;
76         }
77         
78         ZERO_STRUCTP(user);
79         user->logon_time            = (time_t)0;
80         user->logoff_time           = (time_t)0;
81         user->kickoff_time          = (time_t)0;
82         user->pass_last_set_time    = (time_t)0;
83         user->pass_can_change_time  = (time_t)0;
84         user->pass_must_change_time = (time_t)0;
85
86         user->unknown_3 = 0x00ffffff;   /* don't know */
87         user->logon_divs = 168;         /* hours per week */
88         user->hours_len = 21;           /* 21 times 8 bits = 168 */
89         memset(user->hours, 0xff, user->hours_len); /* available at all hours */
90         user->unknown_5 = 0x00000000; /* don't know */
91         user->unknown_6 = 0x000004ec; /* don't know */
92         return True;
93 }       
94
95
96 /*************************************************************
97  Alloc memory and initialises a struct sam_passwd.
98  ************************************************************/
99
100 BOOL pdb_init_sam(SAM_ACCOUNT **user)
101 {
102         if (*user != NULL) {
103                 DEBUG(0,("pdb_init_sam: SAM_ACCOUNT was non NULL\n"));
104 #if 0
105                 smb_panic("NULL pointer passed to pdb_init_sam\n");
106 #endif
107                 return False;
108         }
109         
110         *user=(SAM_ACCOUNT *)malloc(sizeof(SAM_ACCOUNT));
111         
112         if (*user==NULL) {
113                 DEBUG(0,("pdb_init_sam: error while allocating memory\n"));
114                 return False;
115         }
116
117         pdb_fill_default_sam(*user);
118
119         return True;
120 }
121
122
123 /*************************************************************
124  Initialises a struct sam_passwd with sane values.
125  ************************************************************/
126
127 BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd)
128 {
129         if (!pwd) {
130                 new_sam_acct = NULL;
131                 return False;
132         }
133
134         if (!pdb_init_sam(new_sam_acct)) {
135                 new_sam_acct = NULL;
136                 return False;
137         }
138
139         pdb_set_username(*new_sam_acct, pwd->pw_name);
140         pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
141         pdb_set_uid(*new_sam_acct, pwd->pw_uid);
142         pdb_set_gid(*new_sam_acct, pwd->pw_gid);
143         pdb_set_pass_last_set_time(*new_sam_acct, time(NULL));
144         pdb_set_profile_path(*new_sam_acct, lp_logon_path());
145         pdb_set_homedir(*new_sam_acct, lp_logon_home());
146         pdb_set_dir_drive(*new_sam_acct, lp_logon_drive());
147         pdb_set_logon_script(*new_sam_acct, lp_logon_script());
148         return True;
149 }
150
151
152 /************************************************************
153  Free the NT/LM hashes only.
154  ***********************************************************/
155
156 static BOOL pdb_free_sam_contents(SAM_ACCOUNT *user)
157 {
158         if (user == NULL) {
159                 DEBUG(0,("pdb_free_sam_contents: SAM_ACCOUNT was NULL\n"));
160 #if 0
161                 smb_panic("NULL pointer passed to pdb_free_sam_contents\n");
162 #endif
163                 return False;
164         }
165
166         /* As we start mallocing more strings this is where  
167            we should free them. */
168
169         SAFE_FREE(user->nt_pw);
170         SAFE_FREE(user->lm_pw);
171         
172         return True;    
173 }
174
175
176 /************************************************************
177  Reset the SAM_ACCOUNT and free the NT/LM hashes.
178   - note: they are not zero'ed out however.
179  ***********************************************************/
180
181 BOOL pdb_reset_sam(SAM_ACCOUNT *user)
182 {
183         if (user == NULL) {
184                 DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
185 #if 0
186                 smb_panic("NULL pointer passed to pdb_free_sam\n");
187 #endif
188                 return False;
189         }
190         
191         if (!pdb_free_sam_contents(user)) {
192                 return False;
193         }
194
195         if (!pdb_fill_default_sam(user)) {
196                 return False;
197         }
198
199         return True;
200 }
201
202
203 /************************************************************
204  Free the SAM_ACCOUNT and the NT/LM hashes.
205  ***********************************************************/
206
207 BOOL pdb_free_sam(SAM_ACCOUNT **user)
208 {
209         if (*user == NULL) {
210                 DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
211 #if 0
212                 smb_panic("NULL pointer passed to pdb_free_sam\n");
213 #endif
214                 return False;
215         }
216
217         if (!pdb_free_sam_contents(*user)) {
218                 return False;
219         }
220
221         SAFE_FREE(*user);
222         
223         return True;    
224 }
225
226
227 /*************************************************************************
228  Routine to return the next entry in the sam passwd list.
229  *************************************************************************/
230
231 struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
232 {
233         static struct sam_disp_info disp_info;
234
235         if (user == NULL) 
236                 return NULL;
237
238         pdb_init_dispinfo(&disp_info);
239
240         disp_info.smb_name  = user->username;
241         disp_info.full_name = user->full_name;
242         disp_info.user_rid  = user->user_rid;
243
244         return &disp_info;
245 }
246
247 /**********************************************************
248  Encode the account control bits into a string.
249  length = length of string to encode into (including terminating
250  null). length *MUST BE MORE THAN 2* !
251  **********************************************************/
252
253 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
254 {
255         static fstring acct_str;
256         size_t i = 0;
257
258         acct_str[i++] = '[';
259
260         if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
261         if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
262         if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
263         if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
264         if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
265         if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
266         if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
267         if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
268         if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
269         if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
270         if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
271
272         for ( ; i < length - 2 ; i++ )
273                 acct_str[i] = ' ';
274
275         i = length - 2;
276         acct_str[i++] = ']';
277         acct_str[i++] = '\0';
278
279         return acct_str;
280 }     
281
282 /**********************************************************
283  Decode the account control bits from a string.
284  **********************************************************/
285
286 uint16 pdb_decode_acct_ctrl(const char *p)
287 {
288         uint16 acct_ctrl = 0;
289         BOOL finished = False;
290
291         /*
292          * Check if the account type bits have been encoded after the
293          * NT password (in the form [NDHTUWSLXI]).
294          */
295
296         if (*p != '[')
297                 return 0;
298
299         for (p++; *p && !finished; p++) {
300                 switch (*p) {
301                         case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
302                         case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
303                         case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
304                         case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
305                         case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
306                         case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
307                         case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
308                         case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
309                         case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
310                         case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
311                         case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
312             case ' ': { break; }
313                         case ':':
314                         case '\n':
315                         case '\0': 
316                         case ']':
317                         default:  { finished = True; }
318                 }
319         }
320
321         return acct_ctrl;
322 }
323
324 /*************************************************************
325  Routine to set 32 hex password characters from a 16 byte array.
326 **************************************************************/
327
328 void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
329 {
330         if (pwd != NULL) {
331                 int i;
332                 for (i = 0; i < 16; i++)
333                         slprintf(&p[i*2], 3, "%02X", pwd[i]);
334         } else {
335                 if (acct_ctrl & ACB_PWNOTREQ)
336                         safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
337                 else
338                         safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
339         }
340 }
341
342 /*************************************************************
343  Routine to get the 32 hex characters and turn them
344  into a 16 byte array.
345 **************************************************************/
346
347 BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
348 {
349         int i;
350         unsigned char   lonybble, hinybble;
351         char           *hexchars = "0123456789ABCDEF";
352         char           *p1, *p2;
353         
354         if (!p)
355                 return (False);
356         
357         for (i = 0; i < 32; i += 2) {
358                 hinybble = toupper(p[i]);
359                 lonybble = toupper(p[i + 1]);
360
361                 p1 = strchr(hexchars, hinybble);
362                 p2 = strchr(hexchars, lonybble);
363
364                 if (!p1 || !p2)
365                         return (False);
366
367                 hinybble = PTR_DIFF(p1, hexchars);
368                 lonybble = PTR_DIFF(p2, hexchars);
369
370                 pwd[i / 2] = (hinybble << 4) | lonybble;
371         }
372         return (True);
373 }
374
375 /*******************************************************************
376  Group and User RID username mapping function
377  ********************************************************************/
378
379 BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
380 {
381         struct passwd *pw = Get_Pwnam(user_name, False);
382
383         if (u_rid == NULL || g_rid == NULL || user_name == NULL)
384                 return False;
385
386         if (!pw) {
387                 DEBUG(1,("Username %s is invalid on this system\n", user_name));
388                 return False;
389         }
390
391         /* turn the unix UID into a Domain RID.  this is what the posix
392            sub-system does (adds 1000 to the uid) */
393         *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
394
395         /* absolutely no idea what to do about the unix GID to Domain RID mapping */
396         *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
397
398         return True;
399 }
400
401 /*******************************************************************
402  Converts NT user RID to a UNIX uid.
403  ********************************************************************/
404
405 uid_t pdb_user_rid_to_uid(uint32 user_rid)
406 {
407         return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
408 }
409
410 /*******************************************************************
411  Converts NT user RID to a UNIX gid.
412  ********************************************************************/
413
414 gid_t pdb_user_rid_to_gid(uint32 user_rid)
415 {
416         return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
417 }
418
419 /*******************************************************************
420  converts UNIX uid to an NT User RID.
421  ********************************************************************/
422
423 uint32 pdb_uid_to_user_rid(uid_t uid)
424 {
425         return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
426 }
427
428 /*******************************************************************
429  converts NT Group RID to a UNIX uid.
430  ********************************************************************/
431
432 uint32 pdb_gid_to_group_rid(gid_t gid)
433 {
434   return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
435 }
436
437 /*******************************************************************
438  Decides if a RID is a well known RID.
439  ********************************************************************/
440
441 static BOOL pdb_rid_is_well_known(uint32 rid)
442 {
443   return (rid < 1000);
444 }
445
446 /*******************************************************************
447  Decides if a RID is a user or group RID.
448  ********************************************************************/
449
450 BOOL pdb_rid_is_user(uint32 rid)
451 {
452   /* lkcl i understand that NT attaches an enumeration to a RID
453    * such that it can be identified as either a user, group etc
454    * type.  there are 5 such categories, and they are documented.
455    */
456    if(pdb_rid_is_well_known(rid)) {
457       /*
458        * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
459        * and DOMAIN_USER_RID_GUEST.
460        */
461      if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
462        return True;
463    } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
464      return True;
465    }
466    return False;
467 }
468
469 /*******************************************************************
470  Convert a rid into a name. Used in the lookup SID rpc.
471  ********************************************************************/
472
473 BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
474 {
475         BOOL is_user = pdb_rid_is_user(rid);
476
477         DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
478                         "group", (unsigned int)rid));
479
480         if(is_user) {
481                 if(rid == DOMAIN_USER_RID_ADMIN) {
482                         pstring admin_users;
483                         char *p = admin_users;
484                         if(!next_token(&p, name, NULL, sizeof(fstring)))
485                                 fstrcpy(name, "Administrator");
486                 } else if (rid == DOMAIN_USER_RID_GUEST) {
487                         pstring guest_users;
488                         char *p = guest_users;
489                         if(!next_token(&p, name, NULL, sizeof(fstring)))
490                                 fstrcpy(name, "Guest");
491                 } else {
492                         uid_t uid;
493                         struct passwd *pass;
494                         
495                         /*
496                          * Don't try to convert the rid to a name if 
497                          * running in appliance mode
498                          */
499                         if (lp_hide_local_users())
500                                 return False;
501                         
502                         uid = pdb_user_rid_to_uid(rid);
503                         pass = sys_getpwuid(uid);
504
505                         *psid_name_use = SID_NAME_USER;
506
507                         DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
508                                 pass ? "succeeded" : "failed" ));
509
510                         if(!pass) {
511                                 slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
512                                 return True;
513                         }
514
515                         fstrcpy(name, pass->pw_name);
516
517                         DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
518                                 (unsigned int)rid ));
519                 }
520
521         } else {
522                 gid_t gid;
523                 struct group *gr; 
524
525                 /* 
526                  * Don't try to convert the rid to a name if running
527                  * in appliance mode
528                  */
529                 
530                 if (lp_hide_local_users()) 
531                         return False;
532                 
533                 gid = pdb_user_rid_to_gid(rid);
534                 gr = getgrgid(gid);
535
536                 *psid_name_use = SID_NAME_ALIAS;
537
538                 DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
539                         gr ? "succeeded" : "failed" ));
540
541                 if(!gr) {
542                         slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
543                         return True;
544                 }
545
546                 fstrcpy( name, gr->gr_name);
547
548                 DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
549                         (unsigned int)rid ));
550         }
551
552         return True;
553 }
554
555 /*******************************************************************
556  Convert a name into a SID. Used in the lookup name rpc.
557  ********************************************************************/
558
559 BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
560 {
561         extern DOM_SID global_sid_World_Domain;
562         struct passwd *pass = NULL;
563         DOM_SID local_sid;
564         fstring user;
565         fstring domain;
566
567         /*
568          * domain and user may be quoted const strings, and map_username and
569          * friends can modify them. Make a modifiable copy. JRA.
570          */
571
572         fstrcpy(domain, c_domain);
573         fstrcpy(user, c_user);
574
575         sid_copy(&local_sid, &global_sam_sid);
576
577         /*
578          * Special case for MACHINE\Everyone. Map to the world_sid.
579          */
580
581         if(strequal(user, "Everyone")) {
582                 sid_copy( psid, &global_sid_World_Domain);
583                 sid_append_rid(psid, 0);
584                 *psid_name_use = SID_NAME_ALIAS;
585                 return True;
586         }
587
588         /* 
589          * Don't lookup local unix users if running in appliance mode
590          */
591         if (lp_hide_local_users()) 
592                 return False;
593
594         (void)map_username(user);
595
596         if((pass = Get_Pwnam(user, False))) {
597                 sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
598                 *psid_name_use = SID_NAME_USER;
599         } else {
600                 /*
601                  * Maybe it was a group ?
602                  */
603                 struct group *grp = getgrnam(user);
604
605                 if(!grp)
606                         return False;
607
608                 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
609                 *psid_name_use = SID_NAME_ALIAS;
610         }
611
612         sid_copy( psid, &local_sid);
613
614         return True;
615 }
616
617 /****************************************************************************
618  Convert a uid to SID - locally.
619 ****************************************************************************/
620
621 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
622 {
623         extern DOM_SID global_sam_sid;
624
625         sid_copy(psid, &global_sam_sid);
626         sid_append_rid(psid, pdb_uid_to_user_rid(uid));
627
628         return psid;
629 }
630
631 /****************************************************************************
632  Convert a SID to uid - locally.
633 ****************************************************************************/
634
635 BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
636 {
637         extern DOM_SID global_sam_sid;
638
639         DOM_SID dom_sid;
640         uint32 rid;
641         fstring str;
642         struct passwd *pass;
643
644         *name_type = SID_NAME_UNKNOWN;
645
646         sid_copy(&dom_sid, psid);
647         sid_split_rid(&dom_sid, &rid);
648
649         if (!pdb_rid_is_user(rid))
650                 return False;
651
652         /*
653          * We can only convert to a uid if this is our local
654          * Domain SID (ie. we are the controling authority).
655          */
656         if (!sid_equal(&global_sam_sid, &dom_sid))
657                 return False;
658
659         *puid = pdb_user_rid_to_uid(rid);
660
661         /*
662          * Ensure this uid really does exist.
663          */
664         if(!(pass = sys_getpwuid(*puid)))
665                 return False;
666
667         DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
668                 (unsigned int)*puid, pass->pw_name ));
669
670         return True;
671 }
672
673 /****************************************************************************
674  Convert a gid to SID - locally.
675 ****************************************************************************/
676
677 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
678 {
679     extern DOM_SID global_sam_sid;
680
681         sid_copy(psid, &global_sam_sid);
682         sid_append_rid(psid, pdb_gid_to_group_rid(gid));
683
684         return psid;
685 }
686
687 /****************************************************************************
688  Convert a SID to gid - locally.
689 ****************************************************************************/
690
691 BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
692 {
693     extern DOM_SID global_sam_sid;
694         DOM_SID dom_sid;
695         uint32 rid;
696         fstring str;
697         struct group *grp;
698
699         *name_type = SID_NAME_UNKNOWN;
700
701         sid_copy(&dom_sid, psid);
702         sid_split_rid(&dom_sid, &rid);
703
704         /*
705          * We can only convert to a gid if this is our local
706          * Domain SID (ie. we are the controling authority).
707          */
708
709         if (!sid_equal(&global_sam_sid, &dom_sid))
710                 return False;
711
712         if (pdb_rid_is_user(rid))
713                 return False;
714
715         *pgid = pdb_user_rid_to_gid(rid);
716
717         /*
718          * Ensure this gid really does exist.
719          */
720
721         if(!(grp = getgrgid(*pgid)))
722                 return False;
723
724         DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid),
725                 (unsigned int)*pgid, grp->gr_name ));
726
727         return True;
728 }
729
730 static void select_name(pstring string, const UNISTR2 *from)
731 {
732         if (from->buffer != 0)
733                 unistr2_to_ascii(string, from, sizeof(pstring));
734 }
735
736 /*************************************************************
737  Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
738  **************************************************************/
739
740 void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
741 {
742
743         if (from == NULL || to == NULL) 
744                 return;
745
746         to->logon_time = nt_time_to_unix(&from->logon_time);
747         to->logoff_time = nt_time_to_unix(&from->logoff_time);
748         to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
749         to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
750         to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
751         to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
752
753         select_name(to->username    , &from->uni_user_name   );
754         select_name(to->full_name   , &from->uni_full_name   );
755         select_name(to->home_dir    , &from->uni_home_dir    );
756         select_name(to->dir_drive   , &from->uni_dir_drive   );
757         select_name(to->logon_script, &from->uni_logon_script);
758         select_name(to->profile_path, &from->uni_profile_path);
759         select_name(to->acct_desc   , &from->uni_acct_desc   );
760         select_name(to->workstations, &from->uni_workstations);
761         select_name(to->unknown_str , &from->uni_unknown_str );
762         select_name(to->munged_dial , &from->uni_munged_dial );
763
764         to->user_rid = from->user_rid;
765         to->group_rid = from->group_rid;
766
767         to->acct_ctrl = from->acb_info;
768         to->unknown_3 = from->unknown_3;
769
770         to->logon_divs = from->logon_divs;
771         to->hours_len = from->logon_hrs.len;
772         memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
773
774         to->unknown_5 = from->unknown_5;
775         to->unknown_6 = from->unknown_6;
776 }
777
778 /*************************************************************
779  Copies a sam passwd.
780  **************************************************************/
781
782 void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
783 {
784         if (from == NULL || to == NULL) 
785                 return;
786
787         to->logon_time = nt_time_to_unix(&from->logon_time);
788         to->logoff_time = nt_time_to_unix(&from->logoff_time);
789         to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
790         to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
791         to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
792         to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
793
794         select_name(to->username    , &from->uni_user_name   );
795         select_name(to->full_name   , &from->uni_full_name   );
796         select_name(to->home_dir    , &from->uni_home_dir    );
797         select_name(to->dir_drive   , &from->uni_dir_drive   );
798         select_name(to->logon_script, &from->uni_logon_script);
799         select_name(to->profile_path, &from->uni_profile_path);
800         select_name(to->acct_desc   , &from->uni_acct_desc   );
801         select_name(to->workstations, &from->uni_workstations);
802         select_name(to->unknown_str , &from->uni_unknown_str );
803         select_name(to->munged_dial , &from->uni_munged_dial );
804
805         to->user_rid = from->user_rid;
806         to->group_rid = from->group_rid;
807         
808         /* FIXME!!  Do we need to copy the passwords here as well?
809            I don't know.  Need to figure this out   --jerry */
810
811         to->acct_ctrl = from->acb_info;
812         to->unknown_3 = from->unknown_3;
813
814         to->logon_divs = from->logon_divs;
815         to->hours_len = from->logon_hrs.len;
816         memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
817
818         to->unknown_5 = from->unknown_5;
819         to->unknown_6 = from->unknown_6;
820 }
821
822 /*************************************************************
823  Copies a SAM_ACCOUNT.
824  **************************************************************/
825
826 void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
827 {
828         if (!from || !to)
829                 return;
830
831         memcpy(to, from, sizeof(SAM_ACCOUNT));
832 }
833
834 /*************************************************************
835  Change a password entry in the local smbpasswd file.
836
837  FIXME!!  The function needs to be abstracted into the
838  passdb interface or something.  It is currently being called
839  by _api_samr_create_user() in rpc_server/srv_samr.c,
840  in SWAT and by smbpasswd/pdbedit.
841  
842  --jerry
843  *************************************************************/
844
845 BOOL local_password_change(char *user_name, int local_flags,
846                            char *new_passwd, 
847                            char *err_str, size_t err_str_len,
848                            char *msg_str, size_t msg_str_len)
849 {
850         struct passwd  *pwd = NULL;
851         SAM_ACCOUNT     *sam_pass=NULL;
852
853         *err_str = '\0';
854         *msg_str = '\0';
855
856         /* Get the smb passwd entry for this user */
857         pdb_init_sam(&sam_pass);
858         if(!pdb_getsampwnam(sam_pass, user_name)) {
859                 pdb_free_sam(&sam_pass);
860                 
861                 if (local_flags & LOCAL_ADD_USER) {
862                         /*
863                          * Check for a local account - if we're adding only.
864                          */
865                         
866                         if(!(pwd = sys_getpwnam(user_name))) {
867                                 slprintf(err_str, err_str_len - 1, "User %s does not \
868 exist in system password file (usually /etc/passwd). Cannot add \
869 account without a valid local system user.\n", user_name);
870                                 return False;
871                         }
872                 } else {
873                         slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
874                         return False;
875                 }
876
877                 if (!pdb_init_sam_pw(&sam_pass, pwd)) {
878                         slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
879                         return False;
880                 }
881
882                 /* set account flags */
883                 if (!pdb_set_acct_ctrl(sam_pass,((local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL) )) {
884                         slprintf(err_str, err_str_len-1, "Failed to set 'trust account' flags for user %s.\n", user_name);
885                         pdb_free_sam(&sam_pass);
886                         return False;
887                 }
888         } else {
889                 /* the entry already existed */
890                 local_flags &= ~LOCAL_ADD_USER;
891         }
892
893         /*
894          * We are root - just write the new password
895          * and the valid last change time.
896          */
897
898         if (local_flags & LOCAL_DISABLE_USER) {
899                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED)) {
900                         slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
901                         pdb_free_sam(&sam_pass);
902                         return False;
903                 }
904         } else if (local_flags & LOCAL_ENABLE_USER) {
905                 if (pdb_get_lanman_passwd(sam_pass) == NULL) {
906                         if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
907                                 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
908                                 pdb_free_sam(&sam_pass);
909                                 return False;
910                         }
911                 }
912                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED))) {
913                         slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
914                         pdb_free_sam(&sam_pass);
915                         return False;
916                 }
917         }
918         
919         if (local_flags & LOCAL_SET_NO_PASSWORD) {
920                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ)) {
921                         slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
922                         pdb_free_sam(&sam_pass);
923                         return False;
924                 }
925                 
926                 /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
927                 if (!pdb_set_lanman_passwd (sam_pass, NULL)) {
928                         slprintf(err_str, err_str_len-1, "Failed to set NULL lanman password for user %s.\n", user_name);
929                         pdb_free_sam(&sam_pass);
930                         return False;
931                 }
932                 if (!pdb_set_nt_passwd (sam_pass, NULL)) {
933                         slprintf(err_str, err_str_len-1, "Failed to set NULL NT password for user %s.\n", user_name);
934                         pdb_free_sam(&sam_pass);
935                         return False;
936                 }
937         } else {
938                 /*
939                  * If we're dealing with setting a completely empty user account
940                  * ie. One with a password of 'XXXX', but not set disabled (like
941                  * an account created from scratch) then if the old password was
942                  * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
943                  * We remove that as we're giving this user their first password
944                  * and the decision hasn't really been made to disable them (ie.
945                  * don't create them disabled). JRA.
946                  */
947                 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
948                         if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED))) {
949                                 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
950                                 pdb_free_sam(&sam_pass);
951                                 return False;
952                         }
953                 }
954                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ))) {
955                         slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
956                         pdb_free_sam(&sam_pass);
957                         return False;
958                 }
959                 
960                 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
961                         slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
962                         pdb_free_sam(&sam_pass);
963                         return False;
964                 }
965         }       
966
967         if (local_flags & LOCAL_ADD_USER) {
968                 if (pdb_add_sam_account(sam_pass)) {
969                         slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
970                         pdb_free_sam(&sam_pass);
971                         return True;
972                 } else {
973                         slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
974                         pdb_free_sam(&sam_pass);
975                         return False;
976                 }
977         } else if (local_flags & LOCAL_DELETE_USER) {
978                 if (!pdb_delete_sam_account(user_name)) {
979                         slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
980                         pdb_free_sam(&sam_pass);
981                         return False;
982                 }
983                 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
984         } else {
985                 if(!pdb_update_sam_account(sam_pass, True)) {
986                         slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
987                         pdb_free_sam(&sam_pass);
988                         return False;
989                 }
990                 if(local_flags & LOCAL_DISABLE_USER)
991                         slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
992                 else if (local_flags & LOCAL_ENABLE_USER)
993                         slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
994                 else if (local_flags & LOCAL_SET_NO_PASSWORD)
995                         slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
996         }
997
998         pdb_free_sam(&sam_pass);
999         return True;
1000 }
1001
1002 /*********************************************************************
1003  Collection of get...() functions for SAM_ACCOUNT_INFO.
1004  ********************************************************************/
1005
1006 uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass)
1007 {
1008         if (sampass)
1009                 return (sampass->acct_ctrl);
1010         else
1011                 return (ACB_DISABLED);
1012 }
1013
1014 time_t pdb_get_logon_time (SAM_ACCOUNT *sampass)
1015 {
1016         if (sampass)
1017                 return (sampass->logon_time);
1018         else
1019                 return (0);
1020 }
1021
1022 time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass)
1023 {
1024         if (sampass)
1025                 return (sampass->logoff_time);
1026         else
1027                 return (-1);
1028 }
1029
1030 time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass)
1031 {
1032         if (sampass)
1033                 return (sampass->kickoff_time);
1034         else
1035                 return (-1);
1036 }
1037
1038 time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass)
1039 {
1040         if (sampass)
1041                 return (sampass->pass_last_set_time);
1042         else
1043                 return (-1);
1044 }
1045
1046 time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass)
1047 {
1048         if (sampass)
1049                 return (sampass->pass_can_change_time);
1050         else
1051                 return (-1);
1052 }
1053
1054 time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass)
1055 {
1056         if (sampass)
1057                 return (sampass->pass_must_change_time);
1058         else
1059                 return (-1);
1060 }
1061
1062 uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass)
1063 {
1064         if (sampass)
1065                 return (sampass->logon_divs);
1066         else
1067                 return (-1);
1068 }
1069
1070 uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass)
1071 {
1072         if (sampass)
1073                 return (sampass->hours_len);
1074         else
1075                 return (-1);
1076 }
1077
1078 uint8* pdb_get_hours (SAM_ACCOUNT *sampass)
1079 {
1080         if (sampass)
1081                 return (sampass->hours);
1082         else
1083                 return (NULL);
1084 }
1085
1086 uint8* pdb_get_nt_passwd (SAM_ACCOUNT *sampass)
1087 {
1088         if (sampass)
1089                 return (sampass->nt_pw);
1090         else
1091                 return (NULL);
1092 }
1093
1094 uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass)
1095 {
1096         if (sampass)
1097                 return (sampass->lm_pw);
1098         else
1099                 return (NULL);
1100 }
1101
1102 uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass)
1103 {
1104         if (sampass)
1105                 return (sampass->user_rid);
1106         else
1107                 return (-1);
1108 }
1109
1110 uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass)
1111 {
1112         if (sampass)
1113                 return (sampass->group_rid);
1114         else
1115                 return (-1);
1116 }
1117
1118 uid_t pdb_get_uid (SAM_ACCOUNT *sampass)
1119 {
1120         if (sampass)
1121                 return (sampass->uid);
1122         else
1123                 return ((uid_t)-1);
1124 }
1125
1126 gid_t pdb_get_gid (SAM_ACCOUNT *sampass)
1127 {
1128         if (sampass)
1129                 return (sampass->gid);
1130         else
1131                 return ((gid_t)-1);
1132 }
1133
1134 char* pdb_get_username (SAM_ACCOUNT *sampass)
1135 {
1136         if (sampass)
1137                 return (sampass->username);
1138         else
1139                 return (NULL);
1140 }
1141
1142 char* pdb_get_domain (SAM_ACCOUNT *sampass)
1143 {
1144         if (sampass)
1145                 return (sampass->domain);
1146         else
1147                 return (NULL);
1148 }
1149
1150 char* pdb_get_nt_username (SAM_ACCOUNT *sampass)
1151 {
1152         if (sampass)
1153                 return (sampass->nt_username);
1154         else
1155                 return (NULL);
1156 }
1157
1158 char* pdb_get_fullname (SAM_ACCOUNT *sampass)
1159 {
1160         if (sampass)
1161                 return (sampass->full_name);
1162         else
1163                 return (NULL);
1164 }
1165
1166 char* pdb_get_homedir (SAM_ACCOUNT *sampass)
1167 {
1168         if (sampass)
1169                 return (sampass->home_dir);
1170         else
1171                 return (NULL);
1172 }
1173
1174 char* pdb_get_dirdrive (SAM_ACCOUNT *sampass)
1175 {
1176         if (sampass)
1177                 return (sampass->dir_drive);
1178         else
1179                 return (NULL);
1180 }
1181
1182 char* pdb_get_logon_script (SAM_ACCOUNT *sampass)
1183 {
1184         if (sampass)
1185                 return (sampass->logon_script);
1186         else
1187                 return (NULL);
1188 }
1189
1190 char* pdb_get_profile_path (SAM_ACCOUNT *sampass)
1191 {
1192         if (sampass)
1193                 return (sampass->profile_path);
1194         else
1195                 return (NULL);
1196 }
1197
1198 char* pdb_get_acct_desc (SAM_ACCOUNT *sampass)
1199 {
1200         if (sampass)
1201                 return (sampass->acct_desc);
1202         else
1203                 return (NULL);
1204 }
1205
1206 char* pdb_get_workstations (SAM_ACCOUNT *sampass)
1207 {
1208         if (sampass)
1209                 return (sampass->workstations);
1210         else
1211                 return (NULL);
1212 }
1213
1214 char* pdb_get_munged_dial (SAM_ACCOUNT *sampass)
1215 {
1216         if (sampass)
1217                 return (sampass->munged_dial);
1218         else
1219                 return (NULL);
1220 }
1221
1222 uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass)
1223 {
1224         if (sampass)
1225                 return (sampass->unknown_3);
1226         else
1227                 return (-1);
1228 }
1229
1230 uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass)
1231 {
1232         if (sampass)
1233                 return (sampass->unknown_5);
1234         else
1235                 return (-1);
1236 }
1237
1238 uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass)
1239 {
1240         if (sampass)
1241                 return (sampass->unknown_6);
1242         else
1243                 return (-1);
1244 }
1245
1246 /*********************************************************************
1247  Collection of set...() functions for SAM_ACCOUNT_INFO.
1248  ********************************************************************/
1249
1250 BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags)
1251 {
1252         if (!sampass)
1253                 return False;
1254                 
1255         if (sampass) {
1256                 sampass->acct_ctrl = flags;
1257                 return True;
1258         }
1259         
1260         return False;
1261 }
1262
1263 BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime)
1264 {
1265         if (!sampass)
1266                 return False;
1267
1268         sampass->logon_time = mytime;
1269         return True;
1270 }
1271
1272 BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime)
1273 {
1274         if (!sampass)
1275                 return False;
1276
1277         sampass->logoff_time = mytime;
1278         return True;
1279 }
1280
1281 BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime)
1282 {
1283         if (!sampass)
1284                 return False;
1285
1286         sampass->kickoff_time = mytime;
1287         return True;
1288 }
1289
1290 BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime)
1291 {
1292         if (!sampass)
1293                 return False;
1294
1295         sampass->pass_can_change_time = mytime;
1296         return True;
1297 }
1298
1299 BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime)
1300 {
1301         if (!sampass)
1302                 return False;
1303
1304         sampass->pass_must_change_time = mytime;
1305         return True;
1306 }
1307
1308 BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime)
1309 {
1310         if (!sampass)
1311                 return False;
1312
1313         sampass->pass_last_set_time = mytime;
1314         return True;
1315 }
1316
1317 BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len)
1318 {
1319         if (!sampass)
1320                 return False;
1321
1322         sampass->hours_len = len;
1323         return True;
1324 }
1325
1326 BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
1327 {
1328         if (!sampass)
1329                 return False;
1330
1331         sampass->logon_divs = hours;
1332         return True;
1333 }
1334
1335 BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
1336 {
1337         if (!sampass)
1338                 return False;
1339
1340         sampass->uid = uid;
1341         return True;
1342 }
1343
1344 BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
1345 {
1346         if (!sampass)
1347                 return False;
1348
1349         sampass->gid = gid;
1350         return True;
1351 }
1352
1353 BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
1354 {
1355         if (!sampass)
1356                 return False;
1357
1358         sampass->user_rid = rid;
1359         return True;
1360 }
1361
1362 BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
1363 {
1364         if (!sampass)
1365                 return False;
1366
1367         sampass->group_rid = grid;
1368         return True;
1369 }
1370
1371 /*********************************************************************
1372  Set the user's UNIX name.
1373  ********************************************************************/
1374
1375 BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username)
1376 {       
1377         if (!sampass)
1378                 return False;
1379         *sampass->username = '\0';
1380         if (!username)
1381                 return False;
1382
1383         StrnCpy (sampass->username, username, strlen(username));
1384
1385         return True;
1386 }
1387
1388 /*********************************************************************
1389  Set the domain name.
1390  ********************************************************************/
1391
1392 BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain)
1393 {       
1394         if (!sampass)
1395                 return False;
1396         *sampass->domain = '\0';
1397         if (!domain)
1398                 return False;
1399
1400         StrnCpy (sampass->domain, domain, strlen(domain));
1401
1402         return True;
1403 }
1404
1405 /*********************************************************************
1406  Set the user's NT name.
1407  ********************************************************************/
1408
1409 BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username)
1410 {
1411         if (!sampass)
1412                 return False;
1413         *sampass->nt_username = '\0';
1414         if (!nt_username)
1415                 return False;
1416
1417         StrnCpy (sampass->nt_username, nt_username, strlen(nt_username));
1418
1419         return True;
1420 }
1421
1422 /*********************************************************************
1423  Set the user's full name.
1424  ********************************************************************/
1425
1426 BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
1427 {
1428         if (!sampass)
1429                 return False;
1430         *sampass->full_name = '\0';
1431         if (!fullname)
1432                 return False;
1433
1434         StrnCpy (sampass->full_name, fullname, strlen(fullname));
1435
1436         return True;
1437 }
1438
1439 /*********************************************************************
1440  Set the user's logon script.
1441  ********************************************************************/
1442
1443 BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
1444 {
1445         if (!sampass)
1446                 return False;
1447         *sampass->logon_script = '\0';
1448         if (!logon_script)
1449                 return False;
1450
1451         StrnCpy (sampass->logon_script, logon_script, strlen(logon_script));
1452
1453         return True;
1454 }
1455
1456 /*********************************************************************
1457  Set the user's profile path.
1458  ********************************************************************/
1459
1460 BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
1461 {
1462         if (!sampass)
1463                 return False;
1464         *sampass->profile_path = '\0';
1465         if (!profile_path)
1466                 return False;
1467         
1468         StrnCpy (sampass->profile_path, profile_path, strlen(profile_path));
1469         
1470         return True;
1471 }
1472
1473 /*********************************************************************
1474  Set the user's directory drive.
1475  ********************************************************************/
1476
1477 BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
1478 {
1479         if (!sampass)
1480                 return False;
1481         *sampass->dir_drive = '\0';
1482         if (!dir_drive)
1483                 return False;
1484
1485         StrnCpy (sampass->dir_drive, dir_drive, strlen(dir_drive));
1486
1487         return True;
1488 }
1489
1490 /*********************************************************************
1491  Set the user's home directory.
1492  ********************************************************************/
1493
1494 BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
1495 {
1496         if (!sampass)
1497                 return False;
1498         *sampass->home_dir = '\0';
1499         if (!homedir)
1500                 return False;
1501         
1502         StrnCpy (sampass->home_dir, homedir, strlen(homedir));
1503
1504         return True;
1505 }
1506
1507 /*********************************************************************
1508  Set the user's account description.
1509  ********************************************************************/
1510
1511 BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
1512 {
1513         if (!sampass)
1514                 return False;
1515         *sampass->acct_desc = '\0';
1516         if (!acct_desc)
1517                 return False;
1518         
1519         StrnCpy (sampass->acct_desc, acct_desc, strlen(acct_desc));
1520
1521         return True;
1522 }
1523
1524 /*********************************************************************
1525  Set the user's workstation allowed list.
1526  ********************************************************************/
1527
1528 BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
1529 {
1530         if (!sampass)
1531                 return False;
1532         *sampass->workstations = '\0';
1533         if (!workstations)
1534                 return False;
1535
1536         StrnCpy (sampass->workstations, workstations, strlen(workstations));
1537
1538         return True;
1539 }
1540
1541 /*********************************************************************
1542  Set the user's dial string.
1543  ********************************************************************/
1544
1545 BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
1546 {
1547         if (!sampass)
1548                 return False;
1549         *sampass->munged_dial = '\0';
1550         if (!munged_dial)
1551                 return False;
1552
1553         StrnCpy (sampass->munged_dial, munged_dial, strlen(munged_dial));
1554
1555         return True;
1556 }
1557
1558 /*********************************************************************
1559  Set the user's NT hash.
1560  ********************************************************************/
1561
1562 BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
1563 {
1564         if (!sampass)
1565                 return False;
1566         
1567         if (!pwd) {
1568                 /* Allow setting to NULL */
1569                 SAFE_FREE(sampass->nt_pw);
1570                 return True;
1571         }
1572
1573         if (sampass->nt_pw!=NULL)
1574                 DEBUG(4,("pdb_set_nt_passwd: NT hash non NULL overwritting ?\n"));
1575         else
1576                 sampass->nt_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
1577         
1578         if (sampass->nt_pw==NULL)
1579                 return False;
1580
1581         memcpy (sampass->nt_pw, pwd, 16);
1582
1583         return True;
1584 }
1585
1586 /*********************************************************************
1587  Set the user's LM hash.
1588  ********************************************************************/
1589
1590 BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
1591 {
1592         if (!sampass)
1593                 return False;
1594         
1595         if (!pwd) {
1596                 /* Allow setting to NULL */
1597                 SAFE_FREE(sampass->lm_pw);
1598                 return True;
1599         }
1600
1601         if (sampass->lm_pw!=NULL)
1602                 DEBUG(4,("pdb_set_lanman_passwd: LM hash non NULL overwritting ?\n"));
1603         else
1604                 sampass->lm_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
1605         
1606         if (sampass->lm_pw==NULL)
1607                 return False;
1608
1609         memcpy (sampass->lm_pw, pwd, 16);
1610
1611         return True;
1612 }
1613
1614 /*********************************************************************
1615  Set the user's PLAINTEXT password.  Used as an interface to the above.
1616  ********************************************************************/
1617
1618 BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, char *plaintext)
1619 {
1620         uchar new_lanman_p16[16];
1621         uchar new_nt_p16[16];
1622
1623         if (!sampass || !plaintext)
1624                 return False;
1625         
1626         nt_lm_owf_gen (plaintext, new_nt_p16, new_lanman_p16);
1627
1628         if (!pdb_set_nt_passwd (sampass, new_nt_p16)) 
1629                 return False;
1630
1631         if (!pdb_set_lanman_passwd (sampass, new_lanman_p16)) 
1632                 return False;
1633
1634         return True;
1635 }
1636
1637 BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn)
1638 {
1639         if (!sampass)
1640                 return False;
1641
1642         sampass->unknown_3 = unkn;
1643         return True;
1644 }
1645
1646 BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn)
1647 {
1648         if (!sampass)
1649                 return False;
1650
1651         sampass->unknown_5 = unkn;
1652         return True;
1653 }
1654
1655 BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn)
1656 {
1657         if (!sampass)
1658                 return False;
1659
1660         sampass->unknown_6 = unkn;
1661         return True;
1662 }
1663
1664 BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours)
1665 {
1666         if (!sampass)
1667                 return False;
1668
1669         if (!hours) {
1670                 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
1671                 return True;
1672         }
1673         
1674         memcpy (sampass->hours, hours, MAX_HOURS_LEN);
1675
1676         return True;
1677 }