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