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