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