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