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