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