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