a9c6f0729bd0e60627c5880b461c4de7e03c24bb
[kai/samba.git] / source3 / passdb / passdb.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Jeremy Allison                 1996-2001
5    Copyright (C) Luke Kenneth Casson Leighton   1996-1998
6    Copyright (C) Gerald (Jerry) Carter          2000-2001
7    Copyright (C) Andrew Bartlett                2001-2002
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 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_PASSDB
28
29 /*
30  * This is set on startup - it defines the SID for this
31  * machine, and therefore the SAM database for which it is
32  * responsible.
33  */
34
35 extern pstring global_myname;
36
37 /************************************************************
38  Fill the SAM_ACCOUNT with default values.
39  ***********************************************************/
40
41 static void pdb_fill_default_sam(SAM_ACCOUNT *user)
42 {
43         ZERO_STRUCT(user->private); /* Don't touch the talloc context */
44
45         /* Don't change these timestamp settings without a good reason.
46            They are important for NT member server compatibility. */
47
48         user->private.init_flag             = FLAG_SAM_UNINIT;
49         user->private.uid = user->private.gid       = -1;
50
51         user->private.logon_time            = (time_t)0;
52         user->private.pass_last_set_time    = (time_t)0;
53         user->private.pass_can_change_time  = (time_t)0;
54         user->private.logoff_time           = 
55         user->private.kickoff_time          = 
56         user->private.pass_must_change_time = get_time_t_max();
57         user->private.unknown_3 = 0x00ffffff;   /* don't know */
58         user->private.logon_divs = 168;         /* hours per week */
59         user->private.hours_len = 21;           /* 21 times 8 bits = 168 */
60         memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
61         user->private.unknown_5 = 0x00000000; /* don't know */
62         user->private.unknown_6 = 0x000004ec; /* don't know */
63
64         /* Some parts of samba strlen their pdb_get...() returns, 
65            so this keeps the interface unchanged for now. */
66            
67         user->private.username = "";
68         user->private.domain = "";
69         user->private.nt_username = "";
70         user->private.full_name = "";
71         user->private.home_dir = "";
72         user->private.logon_script = "";
73         user->private.profile_path = "";
74         user->private.acct_desc = "";
75         user->private.workstations = "";
76         user->private.unknown_str = "";
77         user->private.munged_dial = "";
78 }       
79
80 static void destroy_pdb_talloc(SAM_ACCOUNT **user) 
81 {
82         if (*user) {
83                 talloc_destroy((*user)->mem_ctx);
84                 *user = NULL;
85         }
86 }
87
88
89 /**********************************************************************
90  Alloc memory and initialises a struct sam_passwd on supplied mem_ctx.
91 ***********************************************************************/
92
93 NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
94 {
95         if (*user != NULL) {
96                 DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
97 #if 0
98                 smb_panic("non-NULL pointer passed to pdb_init_sam\n");
99 #endif
100                 return NT_STATUS_UNSUCCESSFUL;
101         }
102
103         if (!mem_ctx) {
104                 DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
105                 return NT_STATUS_UNSUCCESSFUL;
106         }
107
108         *user=(SAM_ACCOUNT *)talloc(mem_ctx, sizeof(SAM_ACCOUNT));
109
110         if (*user==NULL) {
111                 DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
112                 return NT_STATUS_NO_MEMORY;
113         }
114
115         (*user)->mem_ctx = mem_ctx;
116
117         (*user)->free_fn = NULL;
118
119         pdb_fill_default_sam(*user);
120         
121         return NT_STATUS_OK;
122 }
123
124
125 /*************************************************************
126  Alloc memory and initialises a struct sam_passwd.
127  ************************************************************/
128
129 NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
130 {
131         TALLOC_CTX *mem_ctx;
132         NTSTATUS nt_status;
133         
134         mem_ctx = talloc_init_named("passdb internal SAM_ACCOUNT allocation");
135
136         if (!mem_ctx) {
137                 DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
138                 return NT_STATUS_NO_MEMORY;
139         }
140
141         if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
142                 talloc_destroy(mem_ctx);
143                 return nt_status;
144         }
145         
146         (*user)->free_fn = destroy_pdb_talloc;
147
148         return NT_STATUS_OK;
149 }
150
151
152 /*************************************************************
153  Initialises a struct sam_passwd with sane values.
154  ************************************************************/
155
156 NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
157 {
158         GROUP_MAP map;
159
160         const char *guest_account = lp_guestaccount();
161         if (!(guest_account && *guest_account)) {
162                 DEBUG(1, ("NULL guest account!?!?\n"));
163                 return NT_STATUS_UNSUCCESSFUL;
164         }
165
166         if (!pwd) {
167                 return NT_STATUS_UNSUCCESSFUL;
168         }
169
170         pdb_fill_default_sam(sam_account);
171
172         pdb_set_username(sam_account, pwd->pw_name);
173         pdb_set_fullname(sam_account, pwd->pw_gecos);
174
175         pdb_set_unix_homedir(sam_account, pwd->pw_dir);
176
177         pdb_set_domain (sam_account, lp_workgroup());
178
179         pdb_set_uid(sam_account, pwd->pw_uid);
180         pdb_set_gid(sam_account, pwd->pw_gid);
181         
182         /* When we get a proper uid -> SID and SID -> uid allocation
183            mechinism, we should call it here.  
184            
185            We can't just set this to 0 or allow it only to be filled
186            in when added to the backend, becouse the user's SID 
187            may already be in security descriptors etc.
188            
189            -- abartlet 11-May-02
190         */
191
192
193         /* Ensure this *must* be set right */
194         if (strcmp(pwd->pw_name, guest_account) == 0) {
195                 if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST)) {
196                         return NT_STATUS_UNSUCCESSFUL;
197                 }
198                 if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS)) {
199                         return NT_STATUS_UNSUCCESSFUL;
200                 }
201         } else {
202
203                 if (!pdb_set_user_sid_from_rid(sam_account, 
204                                                fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
205                         DEBUG(0,("Can't set User SID from RID!\n"));
206                         return NT_STATUS_INVALID_PARAMETER;
207                 }
208                 
209                 /* call the mapping code here */
210                 if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
211                         if (!pdb_set_group_sid(sam_account,&map.sid)){
212                                 DEBUG(0,("Can't set Group SID!\n"));
213                                 return NT_STATUS_INVALID_PARAMETER;
214                         }
215                 } 
216                 else {
217                         if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
218                                 DEBUG(0,("Can't set Group SID\n"));
219                                 return NT_STATUS_INVALID_PARAMETER;
220                         }
221                 }
222         }
223
224         /* check if this is a user account or a machine account */
225         if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
226         {
227                 pdb_set_profile_path(sam_account, 
228                                      talloc_sub_specified((sam_account)->mem_ctx, 
229                                                             lp_logon_path(), 
230                                                             pwd->pw_name, global_myname, 
231                                                             pwd->pw_uid, pwd->pw_gid), 
232                                      False);
233                 
234                 pdb_set_homedir(sam_account, 
235                                 talloc_sub_specified((sam_account)->mem_ctx, 
236                                                        lp_logon_home(),
237                                                        pwd->pw_name, global_myname, 
238                                                        pwd->pw_uid, pwd->pw_gid),
239                                 False);
240                 
241                 pdb_set_dir_drive(sam_account, 
242                                   talloc_sub_specified((sam_account)->mem_ctx, 
243                                                          lp_logon_drive(),
244                                                          pwd->pw_name, global_myname, 
245                                                          pwd->pw_uid, pwd->pw_gid),
246                                   False);
247                 
248                 pdb_set_logon_script(sam_account, 
249                                      talloc_sub_specified((sam_account)->mem_ctx, 
250                                                             lp_logon_script(),
251                                                             pwd->pw_name, global_myname, 
252                                                             pwd->pw_uid, pwd->pw_gid), 
253                                      False);
254         }
255         return NT_STATUS_OK;
256 }
257
258
259 /*************************************************************
260  Initialises a struct sam_passwd with sane values.
261  ************************************************************/
262
263 NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
264 {
265         NTSTATUS nt_status;
266
267         if (!pwd) {
268                 new_sam_acct = NULL;
269                 return NT_STATUS_UNSUCCESSFUL;
270         }
271
272         if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
273                 new_sam_acct = NULL;
274                 return nt_status;
275         }
276
277         if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
278                 pdb_free_sam(new_sam_acct);
279                 new_sam_acct = NULL;
280                 return nt_status;
281         }
282
283         return NT_STATUS_OK;
284 }
285
286
287 /**
288  * Free the contets of the SAM_ACCOUNT, but not the structure.
289  *
290  * Also wipes the LM and NT hashes and plaintext passwrod from 
291  * memory.
292  *
293  * @param user SAM_ACCOUNT to free members of.
294  **/
295
296 static void pdb_free_sam_contents(SAM_ACCOUNT *user)
297 {
298
299         /* Kill off sensitive data.  Free()ed by the
300            talloc mechinism */
301
302         data_blob_clear_free(&(user->private.lm_pw));
303         data_blob_clear_free(&(user->private.nt_pw));
304         data_blob_clear_free(&(user->private.plaintext_pw));
305 }
306
307
308 /************************************************************
309  Reset the SAM_ACCOUNT and free the NT/LM hashes.
310  ***********************************************************/
311
312 NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
313 {
314         if (user == NULL) {
315                 DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
316 #if 0
317                 smb_panic("NULL pointer passed to pdb_free_sam\n");
318 #endif
319                 return NT_STATUS_UNSUCCESSFUL;
320         }
321         
322         pdb_free_sam_contents(user);
323
324         pdb_fill_default_sam(user);
325
326         return NT_STATUS_OK;
327 }
328
329
330 /************************************************************
331  Free the SAM_ACCOUNT and the member pointers.
332  ***********************************************************/
333
334 NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
335 {
336         if (*user == NULL) {
337                 DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
338 #if 0
339                 smb_panic("NULL pointer passed to pdb_free_sam\n");
340 #endif
341                 return NT_STATUS_UNSUCCESSFUL;
342         }
343
344         pdb_free_sam_contents(*user);
345         
346         if ((*user)->free_fn) {
347                 (*user)->free_fn(user);
348         }
349
350         return NT_STATUS_OK;    
351 }
352
353
354 /**********************************************************
355  Encode the account control bits into a string.
356  length = length of string to encode into (including terminating
357  null). length *MUST BE MORE THAN 2* !
358  **********************************************************/
359
360 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
361 {
362         static fstring acct_str;
363         size_t i = 0;
364
365         acct_str[i++] = '[';
366
367         if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
368         if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
369         if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
370         if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
371         if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
372         if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
373         if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
374         if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
375         if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
376         if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
377         if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
378
379         for ( ; i < length - 2 ; i++ )
380                 acct_str[i] = ' ';
381
382         i = length - 2;
383         acct_str[i++] = ']';
384         acct_str[i++] = '\0';
385
386         return acct_str;
387 }     
388
389 /**********************************************************
390  Decode the account control bits from a string.
391  **********************************************************/
392
393 uint16 pdb_decode_acct_ctrl(const char *p)
394 {
395         uint16 acct_ctrl = 0;
396         BOOL finished = False;
397
398         /*
399          * Check if the account type bits have been encoded after the
400          * NT password (in the form [NDHTUWSLXI]).
401          */
402
403         if (*p != '[')
404                 return 0;
405
406         for (p++; *p && !finished; p++) {
407                 switch (*p) {
408                         case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
409                         case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
410                         case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
411                         case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
412                         case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
413                         case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
414                         case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
415                         case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
416                         case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
417                         case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
418                         case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
419             case ' ': { break; }
420                         case ':':
421                         case '\n':
422                         case '\0': 
423                         case ']':
424                         default:  { finished = True; }
425                 }
426         }
427
428         return acct_ctrl;
429 }
430
431 /*************************************************************
432  Routine to set 32 hex password characters from a 16 byte array.
433 **************************************************************/
434
435 void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
436 {
437         if (pwd != NULL) {
438                 int i;
439                 for (i = 0; i < 16; i++)
440                         slprintf(&p[i*2], 3, "%02X", pwd[i]);
441         } else {
442                 if (acct_ctrl & ACB_PWNOTREQ)
443                         safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
444                 else
445                         safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
446         }
447 }
448
449 /*************************************************************
450  Routine to get the 32 hex characters and turn them
451  into a 16 byte array.
452 **************************************************************/
453
454 BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
455 {
456         int i;
457         unsigned char   lonybble, hinybble;
458         char           *hexchars = "0123456789ABCDEF";
459         char           *p1, *p2;
460         
461         if (!p)
462                 return (False);
463         
464         for (i = 0; i < 32; i += 2) {
465                 hinybble = toupper(p[i]);
466                 lonybble = toupper(p[i + 1]);
467
468                 p1 = strchr(hexchars, hinybble);
469                 p2 = strchr(hexchars, lonybble);
470
471                 if (!p1 || !p2)
472                         return (False);
473
474                 hinybble = PTR_DIFF(p1, hexchars);
475                 lonybble = PTR_DIFF(p2, hexchars);
476
477                 pwd[i / 2] = (hinybble << 4) | lonybble;
478         }
479         return (True);
480 }
481
482 /*******************************************************************
483  Converts NT user RID to a UNIX uid.
484  ********************************************************************/
485
486 uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid)
487 {
488         int rid_offset = lp_algorithmic_rid_base();
489         return (uid_t)(((user_rid & (~USER_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
490 }
491
492
493 /*******************************************************************
494  converts UNIX uid to an NT User RID.
495  ********************************************************************/
496
497 uint32 fallback_pdb_uid_to_user_rid(uid_t uid)
498 {
499         int rid_offset = lp_algorithmic_rid_base();
500         return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
501 }
502
503 /*******************************************************************
504  Converts NT group RID to a UNIX gid.
505  ********************************************************************/
506
507 gid_t pdb_group_rid_to_gid(uint32 group_rid)
508 {
509         int rid_offset = lp_algorithmic_rid_base();
510         return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
511 }
512
513 /*******************************************************************
514  converts NT Group RID to a UNIX uid.
515  
516  warning: you must not call that function only
517  you must do a call to the group mapping first.
518  there is not anymore a direct link between the gid and the rid.
519  ********************************************************************/
520
521 uint32 pdb_gid_to_group_rid(gid_t gid)
522 {
523         int rid_offset = lp_algorithmic_rid_base();
524         return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
525 }
526
527 /*******************************************************************
528  Decides if a RID is a well known RID.
529  ********************************************************************/
530
531 static BOOL pdb_rid_is_well_known(uint32 rid)
532 {
533         /* Not using rid_offset here, becouse this is the actual
534            NT fixed value (1000) */
535
536         return (rid < BASE_RID);
537 }
538
539 /*******************************************************************
540  Decides if a RID is a user or group RID.
541  ********************************************************************/
542
543 BOOL pdb_rid_is_user(uint32 rid)
544 {
545   /* lkcl i understand that NT attaches an enumeration to a RID
546    * such that it can be identified as either a user, group etc
547    * type.  there are 5 such categories, and they are documented.
548    */
549         /* However, they are not in the RID, just somthing you can query
550            seperatly.  Sorry luke :-) */
551
552    if(pdb_rid_is_well_known(rid)) {
553       /*
554        * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
555        * and DOMAIN_USER_RID_GUEST.
556        */
557      if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
558        return True;
559    } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
560      return True;
561    }
562    return False;
563 }
564
565 /*******************************************************************
566  Convert a rid into a name. Used in the lookup SID rpc.
567  ********************************************************************/
568
569 BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
570 {
571         uint32 rid;
572         SAM_ACCOUNT *sam_account = NULL;
573         GROUP_MAP map;
574
575         if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
576                 DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n",
577                         sid_string_static(&map.sid)));
578                 return False;
579         }       
580         *psid_name_use = SID_NAME_UNKNOWN;
581         
582         DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
583         
584         if (rid == DOMAIN_USER_RID_ADMIN) {
585                 char **admin_list = lp_admin_users(-1);
586                 *psid_name_use = SID_NAME_USER;
587                 if (admin_list) {
588                         char *p = *admin_list;
589                         if(!next_token(&p, name, NULL, sizeof(fstring)))
590                                 fstrcpy(name, "Administrator");
591                 } else {
592                         fstrcpy(name, "Administrator");
593                 }
594                 return True;
595         }
596
597         /*
598          * Don't try to convert the rid to a name if 
599          * running in appliance mode
600          */
601
602         if (lp_hide_local_users())
603                 return False;
604                 
605         if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
606                 return False;
607         }
608                 
609         /* This now does the 'generic' mapping in pdb_unix */
610         /* 'guest' is also handled there */
611         if (pdb_getsampwsid(sam_account, sid)) {
612                 fstrcpy(name, pdb_get_username(sam_account));
613                 *psid_name_use = SID_NAME_USER;
614
615                 pdb_free_sam(&sam_account);
616                         
617                 return True;
618         }
619
620         pdb_free_sam(&sam_account);
621                 
622         if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) {
623                 if (map.gid!=-1) {
624                         DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
625                 } else {
626                         DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid.  Returning name.\n", map.nt_name));
627                 }
628
629                 fstrcpy(name, map.nt_name);
630                 *psid_name_use = map.sid_name_use;
631                 return True;
632         }
633
634         if (pdb_rid_is_user(rid)) {
635                 uid_t uid;
636
637                 DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
638
639                 uid = fallback_pdb_user_rid_to_uid(rid);
640                 slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);   
641
642                 return False;  /* Indicates that this user was 'not mapped' */
643         } else {
644                 gid_t gid;
645                 struct group *gr; 
646                         
647                 DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
648
649                 gid = pdb_group_rid_to_gid(rid);
650                 gr = getgrgid(gid);
651                         
652                 *psid_name_use = SID_NAME_ALIAS;
653                         
654                 DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
655                          gr ? "succeeded" : "failed" ));
656                         
657                 if(!gr) {
658                         slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
659                         return False; /* Indicates that this group was 'not mapped' */
660                 }
661                         
662                 fstrcpy( name, gr->gr_name);
663                         
664                 DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
665                          (unsigned int)rid ));
666                 return True;   
667         }
668 }
669
670 /*******************************************************************
671  Convert a name into a SID. Used in the lookup name rpc.
672  ********************************************************************/
673
674 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
675 {
676         extern DOM_SID global_sid_World_Domain;
677         DOM_SID local_sid;
678         fstring user;
679         SAM_ACCOUNT *sam_account = NULL;
680         struct group *grp;
681         GROUP_MAP map;
682                 
683         *psid_name_use = SID_NAME_UNKNOWN;
684
685         /*
686          * user may be quoted a const string, and map_username and
687          * friends can modify it. Make a modifiable copy. JRA.
688          */
689
690         fstrcpy(user, c_user);
691
692         sid_copy(&local_sid, get_global_sam_sid());
693
694         /*
695          * Special case for MACHINE\Everyone. Map to the world_sid.
696          */
697
698         if(strequal(user, "Everyone")) {
699                 sid_copy( psid, &global_sid_World_Domain);
700                 sid_append_rid(psid, 0);
701                 *psid_name_use = SID_NAME_ALIAS;
702                 return True;
703         }
704
705         /* 
706          * Don't lookup local unix users if running in appliance mode
707          */
708         if (lp_hide_local_users()) 
709                 return False;
710
711         (void)map_username(user);
712
713         if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
714                 return False;
715         }
716         
717         if (pdb_getsampwnam(sam_account, user)) {
718                 sid_copy(psid, pdb_get_user_sid(sam_account));
719                 *psid_name_use = SID_NAME_USER;
720                 
721                 pdb_free_sam(&sam_account);
722                 return True;
723         }
724
725         pdb_free_sam(&sam_account);
726
727         /*
728          * Maybe it was a group ?
729          */
730
731         /* check if it's a mapped group */
732         if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
733                 /* yes it's a mapped group */
734                 sid_copy(&local_sid, &map.sid);
735                 *psid_name_use = map.sid_name_use;
736         } else {
737                 /* it's not a mapped group */
738                 grp = getgrnam(user);
739                 if(!grp)
740                         return False;
741                 
742                 /* 
743                  *check if it's mapped, if it is reply it doesn't exist
744                  *
745                  * that's to prevent this case:
746                  *
747                  * unix group ug is mapped to nt group ng
748                  * someone does a lookup on ug
749                  * we must not reply as it doesn't "exist" anymore
750                  * for NT. For NT only ng exists.
751                  * JFM, 30/11/2001
752                  */
753                 
754                 if (get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){
755                         return False;
756                 }
757                 
758                 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
759                 *psid_name_use = SID_NAME_ALIAS;
760         }
761
762         sid_copy( psid, &local_sid);
763
764         return True;
765 }
766
767 /****************************************************************************
768  Convert a uid to SID - locally.
769 ****************************************************************************/
770
771 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
772 {
773         struct passwd *pass;
774         SAM_ACCOUNT *sam_user = NULL;
775         fstring str; /* sid string buffer */
776
777         sid_copy(psid, get_global_sam_sid());
778
779         if((pass = getpwuid_alloc(uid))) {
780
781                 if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) {
782                         passwd_free(&pass);
783                         return NULL;
784                 }
785                 
786                 if (pdb_getsampwnam(sam_user, pass->pw_name)) {
787                         sid_copy(psid, pdb_get_user_sid(sam_user));
788                 } else if (strcmp(pass->pw_name, lp_guestaccount()) == 0) {
789                         sid_append_rid(psid, DOMAIN_USER_RID_GUEST);
790                 } else {
791                         sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid));
792                 }
793
794                 DEBUG(10,("local_uid_to_sid: uid %u -> SID (%s) (%s).\n", 
795                           (unsigned)uid, sid_to_string( str, psid),
796                           pass->pw_name ));
797
798                 passwd_free(&pass);
799                 pdb_free_sam(&sam_user);
800         
801         } else {
802                 sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid));
803
804                 DEBUG(10,("local_uid_to_sid: uid %u -> SID (%s) (unknown user).\n", 
805                           (unsigned)uid, sid_to_string( str, psid)));
806         }
807
808         return psid;
809 }
810
811 /****************************************************************************
812  Convert a SID to uid - locally.
813 ****************************************************************************/
814
815 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
816 {
817         fstring str;
818         SAM_ACCOUNT *sam_user = NULL;
819
820         *name_type = SID_NAME_UNKNOWN;
821
822         if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
823                 return False;
824         
825         if (pdb_getsampwsid(sam_user, psid)) {
826                 *puid = pdb_get_uid(sam_user);
827                 if (*puid == -1) {
828                         pdb_free_sam(&sam_user);
829                         return False;
830                 }
831                 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
832                           (unsigned int)*puid, pdb_get_username(sam_user)));
833                 pdb_free_sam(&sam_user);
834         } else {
835
836                 DOM_SID dom_sid;
837                 uint32 rid;
838                 GROUP_MAP map;
839
840                 pdb_free_sam(&sam_user);  
841
842                 if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
843                         DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid)));
844                         /* It's a group, not a user... */
845                         return False;
846                 }
847
848                 sid_copy(&dom_sid, psid);
849                 if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
850                         DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
851                         return False;
852                 }
853
854                 if (!pdb_rid_is_user(rid)) {
855                         DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becouse it is a group\n", sid_to_string(str, psid)));
856                         return False;
857                 }
858                 
859                 *puid = fallback_pdb_user_rid_to_uid(rid);
860                 
861                 DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", 
862                          sid_to_string(str, psid), (signed long int)(*puid)));
863         }
864
865         *name_type = SID_NAME_USER;
866
867         return True;
868 }
869
870 /****************************************************************************
871  Convert a gid to SID - locally.
872 ****************************************************************************/
873
874 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
875 {
876         GROUP_MAP map;
877
878         sid_copy(psid, get_global_sam_sid());
879         
880         if (get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
881                 sid_copy(psid, &map.sid);
882         } 
883         else {
884                 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
885         }
886
887         return psid;
888 }
889
890 /****************************************************************************
891  Convert a SID to gid - locally.
892 ****************************************************************************/
893
894 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
895 {
896         fstring str;
897         GROUP_MAP map;
898
899         *name_type = SID_NAME_UNKNOWN;
900
901         /*
902          * We can only convert to a gid if this is our local
903          * Domain SID (ie. we are the controling authority).
904          *
905          * Or in the Builtin SID too. JFM, 11/30/2001
906          */
907
908         if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
909                 
910                 /* the SID is in the mapping table but not mapped */
911                 if (map.gid==-1)
912                         return False;
913
914                 *pgid = map.gid;
915                 *name_type = map.sid_name_use;
916                 DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", 
917                           sid_to_string( str, psid),
918                           map.nt_name, (unsigned int)*pgid));
919
920         } else {
921                 uint32 rid;
922                 SAM_ACCOUNT *sam_user = NULL;
923                 if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
924                         return False;
925                 
926                 if (pdb_getsampwsid(sam_user, psid)) {
927                         return False;
928                         pdb_free_sam(&sam_user);
929                 }
930
931                 pdb_free_sam(&sam_user);
932
933                 if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
934                         DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
935                         return False;
936                 }
937
938                 if (pdb_rid_is_user(rid))
939                         return False;
940                 
941                 *pgid = pdb_group_rid_to_gid(rid);
942                 *name_type = SID_NAME_ALIAS;
943                 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid),
944                           (unsigned int)*pgid));
945         }
946         
947         return True;
948 }
949
950 /** 
951  * Quick hack to do an easy ucs2 -> mulitbyte conversion 
952  * @return static buffer containing the converted string
953  **/
954
955 const char *pdb_unistr2_convert(const UNISTR2 *from)
956 {
957         static pstring convert_buffer;
958         *convert_buffer = 0;
959         if (!from) {
960                 return convert_buffer;
961         }
962
963         unistr2_to_ascii(convert_buffer, from, sizeof(pstring));
964         return convert_buffer;
965 }
966
967 /*************************************************************
968  Change a password entry in the local smbpasswd file.
969
970  FIXME!!  The function needs to be abstracted into the
971  passdb interface or something.  It is currently being called
972  by _api_samr_create_user() in rpc_server/srv_samr.c,
973  in SWAT and by smbpasswd/pdbedit.
974  
975  --jerry
976  *************************************************************/
977
978 BOOL local_password_change(const char *user_name, int local_flags,
979                            const char *new_passwd, 
980                            char *err_str, size_t err_str_len,
981                            char *msg_str, size_t msg_str_len)
982 {
983         struct passwd  *pwd = NULL;
984         SAM_ACCOUNT     *sam_pass=NULL;
985
986         *err_str = '\0';
987         *msg_str = '\0';
988
989         /* Get the smb passwd entry for this user */
990         pdb_init_sam(&sam_pass);
991         if(!pdb_getsampwnam(sam_pass, user_name)) {
992                 pdb_free_sam(&sam_pass);
993                 
994                 if (local_flags & LOCAL_ADD_USER) {
995                         pwd = getpwnam_alloc(user_name);
996                 } else if (local_flags & LOCAL_DELETE_USER) {
997                         /* Might not exist in /etc/passwd */
998                 } else {
999                         slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
1000                         return False;
1001                 }
1002                 
1003                 if (pwd) {
1004                         /* Local user found, so init from this */
1005                         if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){
1006                                 slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
1007                                 passwd_free(&pwd);
1008                                 return False;
1009                         }
1010                 
1011                         passwd_free(&pwd);
1012                 } else {
1013                         if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_pass))){
1014                                 slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
1015                                 return False;
1016                         }
1017
1018                         if (!pdb_set_username(sam_pass, user_name)) {
1019                                 slprintf(err_str, err_str_len - 1, "Failed to set username for user %s.\n", user_name);
1020                                 pdb_free_sam(&sam_pass);
1021                                 return False;
1022                         }
1023                 }
1024                 if (local_flags & LOCAL_TRUST_ACCOUNT) {
1025                         if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST)) {
1026                                 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
1027                                 pdb_free_sam(&sam_pass);
1028                                 return False;
1029                         }
1030                 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
1031                         if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST)) {
1032                                 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
1033                                 pdb_free_sam(&sam_pass);
1034                                 return False;
1035                         }
1036                 } else {
1037                         if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL)) {
1038                                 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1039                                 pdb_free_sam(&sam_pass);
1040                                 return False;
1041                         }
1042                 }
1043
1044         } else {
1045                 /* the entry already existed */
1046                 local_flags &= ~LOCAL_ADD_USER;
1047         }
1048
1049         /*
1050          * We are root - just write the new password
1051          * and the valid last change time.
1052          */
1053
1054         if (local_flags & LOCAL_DISABLE_USER) {
1055                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED)) {
1056                         slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1057                         pdb_free_sam(&sam_pass);
1058                         return False;
1059                 }
1060         } else if (local_flags & LOCAL_ENABLE_USER) {
1061                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED))) {
1062                         slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1063                         pdb_free_sam(&sam_pass);
1064                         return False;
1065                 }
1066         }
1067         
1068         if (local_flags & LOCAL_SET_NO_PASSWORD) {
1069                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ)) {
1070                         slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1071                         pdb_free_sam(&sam_pass);
1072                         return False;
1073                 }
1074         } else if (local_flags & LOCAL_SET_PASSWORD) {
1075                 /*
1076                  * If we're dealing with setting a completely empty user account
1077                  * ie. One with a password of 'XXXX', but not set disabled (like
1078                  * an account created from scratch) then if the old password was
1079                  * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1080                  * We remove that as we're giving this user their first password
1081                  * and the decision hasn't really been made to disable them (ie.
1082                  * don't create them disabled). JRA.
1083                  */
1084                 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1085                         if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED))) {
1086                                 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1087                                 pdb_free_sam(&sam_pass);
1088                                 return False;
1089                         }
1090                 }
1091                 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ))) {
1092                         slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1093                         pdb_free_sam(&sam_pass);
1094                         return False;
1095                 }
1096                 
1097                 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1098                         slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1099                         pdb_free_sam(&sam_pass);
1100                         return False;
1101                 }
1102         }       
1103
1104         if (local_flags & LOCAL_ADD_USER) {
1105                 if (pdb_add_sam_account(sam_pass)) {
1106                         slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1107                         pdb_free_sam(&sam_pass);
1108                         return True;
1109                 } else {
1110                         slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1111                         pdb_free_sam(&sam_pass);
1112                         return False;
1113                 }
1114         } else if (local_flags & LOCAL_DELETE_USER) {
1115                 if (!pdb_delete_sam_account(sam_pass)) {
1116                         slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1117                         pdb_free_sam(&sam_pass);
1118                         return False;
1119                 }
1120                 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1121         } else {
1122                 if(!pdb_update_sam_account(sam_pass)) {
1123                         slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1124                         pdb_free_sam(&sam_pass);
1125                         return False;
1126                 }
1127                 if(local_flags & LOCAL_DISABLE_USER)
1128                         slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1129                 else if (local_flags & LOCAL_ENABLE_USER)
1130                         slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1131                 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1132                         slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1133         }
1134
1135         pdb_free_sam(&sam_pass);
1136         return True;
1137 }