a7635308b7bd233a9b0fb8a11581c3a93c449319
[samba.git] / source / passdb / passdb.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Password and authentication handling
5    Copyright (C) Jeremy Allison 1996-1998
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1998
7       
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "nterr.h"
25
26 extern int DEBUGLEVEL;
27
28 /*
29  * NOTE. All these functions are abstracted into a structure
30  * that points to the correct function for the selected database. JRA.
31  *
32  * NOTE.  for the get/mod/add functions, there are two sets of functions.
33  * one supports struct sam_passwd, the other supports struct smb_passwd.
34  * for speed optimisation it is best to support both these sets.
35  * 
36  * it is, however, optional to support one set but not the other: there
37  * is conversion-capability built in to passdb.c, and run-time error
38  * detection for when neither are supported.
39  * 
40  * password database writers are recommended to implement the sam_passwd
41  * functions in a first pass, as struct sam_passwd contains more
42  * information, needed by the NT Domain support.
43  * 
44  * an API writer is expected to create either one set (struct smb_passwd) or
45  * the other (struct sam_passwd) OR both, and optionally also to write display
46  * info routines * (struct sam_disp_info).  functions which the API writer
47  * chooses NOT to write must be wrapped in conversion functions (pwdb_x_to_y)
48  * such that API users can call any function and still get valid results.
49  *
50  * the password API does NOT fill in the gaps if you set an API function
51  * to NULL: it will deliberately attempt to call the NULL function.
52  *
53  */
54
55 static struct passdb_ops *pwdb_ops;
56
57 /***************************************************************
58  Initialise the password db operations.
59 ***************************************************************/
60
61 BOOL initialise_password_db(void)
62 {
63   if (pwdb_ops)
64   {
65     return True;
66   }
67
68 #ifdef WITH_NISPLUS
69   pwdb_ops =  nisplus_initialise_password_db();
70 #elif defined(WITH_LDAP)
71   pwdb_ops = ldap_initialise_password_db();
72 #elif defined(USE_SMBPASS_DB)
73   pwdb_ops = file_initialise_password_db();
74 #endif 
75
76   return (pwdb_ops != NULL);
77 }
78
79 /*
80  * Functions that return/manipulate a struct smb_passwd.
81  */
82
83 /************************************************************************
84  Utility function to search smb passwd by rid.  
85 *************************************************************************/
86
87 struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid)
88 {
89         return iterate_getsmbpwuid(pwdb_user_rid_to_uid(user_rid));
90 }
91
92 /************************************************************************
93  Utility function to search smb passwd by uid.  use this if your database
94  does not have search facilities.
95 *************************************************************************/
96
97 struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid)
98 {
99         struct smb_passwd *pwd = NULL;
100         void *fp = NULL;
101
102         DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid));
103
104         /* Open the smb password database - not for update. */
105         fp = startsmbpwent(False);
106
107         if (fp == NULL)
108         {
109                 DEBUG(0, ("unable to open smb password database.\n"));
110                 return NULL;
111         }
112
113         while ((pwd = getsmbpwent(fp)) != NULL && pwd->smb_userid != smb_userid)
114       ;
115
116         if (pwd != NULL)
117         {
118                 DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid));
119         }
120
121         endsmbpwent(fp);
122         return pwd;
123 }
124
125 /************************************************************************
126  Utility function to search smb passwd by name.  use this if your database
127  does not have search facilities.
128 *************************************************************************/
129
130 struct smb_passwd *iterate_getsmbpwnam(char *name)
131 {
132         struct smb_passwd *pwd = NULL;
133         void *fp = NULL;
134
135         DEBUG(10, ("search by name: %s\n", name));
136
137         /* Open the sam password file - not for update. */
138         fp = startsmbpwent(False);
139
140         if (fp == NULL)
141         {
142                 DEBUG(0, ("unable to open smb password database.\n"));
143                 return NULL;
144         }
145
146         while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->smb_name, name))
147       ;
148
149         if (pwd != NULL)
150         {
151                 DEBUG(10, ("found by name: %s\n", name));
152         }
153
154         endsmbpwent(fp);
155         return pwd;
156 }
157
158 /***************************************************************
159  Start to enumerate the smb or sam passwd list. Returns a void pointer
160  to ensure no modification outside this module.
161
162  Note that currently it is being assumed that a pointer returned
163  from this function may be used to enumerate struct sam_passwd
164  entries as well as struct smb_passwd entries. This may need
165  to change. JRA.
166
167 ****************************************************************/
168
169 void *startsmbpwent(BOOL update)
170 {
171   return pwdb_ops->startsmbpwent(update);
172 }
173
174 /***************************************************************
175  End enumeration of the smb or sam passwd list.
176
177  Note that currently it is being assumed that a pointer returned
178  from this function may be used to enumerate struct sam_passwd
179  entries as well as struct smb_passwd entries. This may need
180  to change. JRA.
181
182 ****************************************************************/
183
184 void endsmbpwent(void *vp)
185 {
186   pwdb_ops->endsmbpwent(vp);
187 }
188
189 /*************************************************************************
190  Routine to return the next entry in the smb passwd list.
191  *************************************************************************/
192
193 struct smb_passwd *getsmbpwent(void *vp)
194 {
195         return pwdb_ops->getsmbpwent(vp);
196 }
197
198 /************************************************************************
199  Routine to add an entry to the smb passwd file.
200 *************************************************************************/
201
202 BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
203 {
204         return pwdb_ops->add_smbpwd_entry(newpwd);
205 }
206
207 /************************************************************************
208  Routine to search the smb passwd file for an entry matching the username.
209  and then modify its password entry. We can't use the startsampwent()/
210  getsampwent()/endsampwent() interfaces here as we depend on looking
211  in the actual file to decide how much room we have to write data.
212  override = False, normal
213  override = True, override XXXXXXXX'd out password or NO PASS
214 ************************************************************************/
215
216 BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
217 {
218         return pwdb_ops->mod_smbpwd_entry(pwd, override);
219 }
220
221 /************************************************************************
222  Routine to search smb passwd by name.
223 *************************************************************************/
224
225 struct smb_passwd *getsmbpwnam(char *name)
226 {
227         return pwdb_ops->getsmbpwnam(name);
228 }
229
230 /************************************************************************
231  Routine to search smb passwd by user rid.
232 *************************************************************************/
233
234 struct smb_passwd *getsmbpwrid(uint32 user_rid)
235 {
236         return pwdb_ops->getsmbpwrid(user_rid);
237 }
238
239 /************************************************************************
240  Routine to search smb passwd by uid.
241 *************************************************************************/
242
243 struct smb_passwd *getsmbpwuid(uid_t smb_userid)
244 {
245         return pwdb_ops->getsmbpwuid(smb_userid);
246 }
247
248 /*
249  * Functions that manupulate a struct sam_passwd.
250  */
251
252 /************************************************************************
253  Utility function to search sam passwd by name.  use this if your database
254  does not have search facilities.
255 *************************************************************************/
256
257 struct sam_passwd *iterate_getsam21pwnam(char *name)
258 {
259         struct sam_passwd *pwd = NULL;
260         void *fp = NULL;
261
262         DEBUG(10, ("search by name: %s\n", name));
263
264         /* Open the smb password database - not for update. */
265         fp = startsmbpwent(False);
266
267         if (fp == NULL)
268         {
269                 DEBUG(0, ("unable to open sam password database.\n"));
270                 return NULL;
271         }
272
273         while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name))
274         {
275                 DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
276         }
277
278         if (pwd != NULL)
279         {
280                 DEBUG(10, ("found by name: %s\n", name));
281         }
282
283         endsmbpwent(fp);
284         return pwd;
285 }
286
287 /************************************************************************
288  Utility function to search sam passwd by rid.  use this if your database
289  does not have search facilities.
290
291  search capability by both rid and uid are needed as the rid <-> uid
292  mapping may be non-monotonic.  
293
294 *************************************************************************/
295
296 struct sam_passwd *iterate_getsam21pwrid(uint32 rid)
297 {
298         struct sam_passwd *pwd = NULL;
299         void *fp = NULL;
300
301         DEBUG(10, ("search by rid: %x\n", rid));
302
303         /* Open the smb password file - not for update. */
304         fp = startsmbpwent(False);
305
306         if (fp == NULL)
307         {
308                 DEBUG(0, ("unable to open sam password database.\n"));
309                 return NULL;
310         }
311
312         while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid)
313         {
314                 DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
315         }
316
317         if (pwd != NULL)
318         {
319                 DEBUG(10, ("found by user_rid: %x\n", rid));
320         }
321
322         endsmbpwent(fp);
323         return pwd;
324 }
325
326 /************************************************************************
327  Utility function to search sam passwd by uid.  use this if your database
328  does not have search facilities.
329
330  search capability by both rid and uid are needed as the rid <-> uid
331  mapping may be non-monotonic.  
332
333 *************************************************************************/
334
335 struct sam_passwd *iterate_getsam21pwuid(uid_t uid)
336 {
337         struct sam_passwd *pwd = NULL;
338         void *fp = NULL;
339
340         DEBUG(10, ("search by uid: %x\n", (int)uid));
341
342         /* Open the smb password file - not for update. */
343         fp = startsmbpwent(False);
344
345         if (fp == NULL)
346         {
347                 DEBUG(0, ("unable to open sam password database.\n"));
348                 return NULL;
349         }
350
351         while ((pwd = getsam21pwent(fp)) != NULL && pwd->smb_userid != uid)
352       ;
353
354         if (pwd != NULL)
355         {
356                 DEBUG(10, ("found by smb_userid: %x\n", (int)uid));
357         }
358
359         endsmbpwent(fp);
360         return pwd;
361 }
362
363 /*************************************************************************
364  Routine to return a display info structure, by rid
365  *************************************************************************/
366 struct sam_disp_info *getsamdisprid(uint32 rid)
367 {
368         return pwdb_ops->getsamdisprid(rid);
369 }
370
371 /*************************************************************************
372  Routine to return the next entry in the sam passwd list.
373  *************************************************************************/
374
375 struct sam_passwd *getsam21pwent(void *vp)
376 {
377         return pwdb_ops->getsam21pwent(vp);
378 }
379
380
381 /************************************************************************
382  Routine to search sam passwd by name.
383 *************************************************************************/
384
385 struct sam_passwd *getsam21pwnam(char *name)
386 {
387         return pwdb_ops->getsam21pwnam(name);
388 }
389
390 /************************************************************************
391  Routine to search sam passwd by rid.  
392 *************************************************************************/
393
394 struct sam_passwd *getsam21pwrid(uint32 rid)
395 {
396         return pwdb_ops->getsam21pwrid(rid);
397 }
398
399
400 /**********************************************************
401  **********************************************************
402
403  utility routines which are likely to be useful to all password
404  databases
405
406  **********************************************************
407  **********************************************************/
408
409 /*************************************************************
410  initialises a struct sam_disp_info.
411  **************************************************************/
412
413 static void pwdb_init_dispinfo(struct sam_disp_info *user)
414 {
415         if (user == NULL) return;
416         bzero(user, sizeof(*user));
417 }
418
419 /*************************************************************
420  initialises a struct smb_passwd.
421  **************************************************************/
422
423 void pwdb_init_smb(struct smb_passwd *user)
424 {
425         if (user == NULL) return;
426         bzero(user, sizeof(*user));
427         user->pass_last_set_time    = (time_t)-1;
428 }
429
430 /*************************************************************
431  initialises a struct sam_passwd.
432  **************************************************************/
433 void pwdb_init_sam(struct sam_passwd *user)
434 {
435         if (user == NULL) return;
436         bzero(user, sizeof(*user));
437         user->logon_time            = (time_t)-1;
438         user->logoff_time           = (time_t)-1;
439         user->kickoff_time          = (time_t)-1;
440         user->pass_last_set_time    = (time_t)-1;
441         user->pass_can_change_time  = (time_t)-1;
442         user->pass_must_change_time = (time_t)-1;
443 }
444
445 /*************************************************************************
446  Routine to return the next entry in the sam passwd list.
447  *************************************************************************/
448
449 struct sam_disp_info *pwdb_sam_to_dispinfo(struct sam_passwd *user)
450 {
451         static struct sam_disp_info disp_info;
452
453         if (user == NULL) return NULL;
454
455         pwdb_init_dispinfo(&disp_info);
456
457         disp_info.smb_name  = user->smb_name;
458         disp_info.full_name = user->full_name;
459         disp_info.user_rid  = user->user_rid;
460
461         return &disp_info;
462 }
463
464 /*************************************************************
465  converts a sam_passwd structure to a smb_passwd structure.
466  **************************************************************/
467
468 struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user)
469 {
470         static struct smb_passwd pw_buf;
471
472         if (user == NULL) return NULL;
473
474         pwdb_init_smb(&pw_buf);
475
476         pw_buf.smb_userid         = user->smb_userid;
477         pw_buf.smb_name           = user->smb_name;
478         pw_buf.smb_passwd         = user->smb_passwd;
479         pw_buf.smb_nt_passwd      = user->smb_nt_passwd;
480         pw_buf.acct_ctrl          = user->acct_ctrl;
481         pw_buf.pass_last_set_time = user->pass_last_set_time;
482
483         return &pw_buf;
484 }
485
486
487 /*************************************************************
488  converts a smb_passwd structure to a sam_passwd structure.
489  **************************************************************/
490
491 struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user)
492 {
493         static struct sam_passwd pw_buf;
494
495         if (user == NULL) return NULL;
496
497         pwdb_init_sam(&pw_buf);
498
499         pw_buf.smb_userid         = user->smb_userid;
500         pw_buf.smb_name           = user->smb_name;
501         pw_buf.smb_passwd         = user->smb_passwd;
502         pw_buf.smb_nt_passwd      = user->smb_nt_passwd;
503         pw_buf.acct_ctrl          = user->acct_ctrl;
504         pw_buf.pass_last_set_time = user->pass_last_set_time;
505
506         return &pw_buf;
507 }
508
509 /**********************************************************
510  Encode the account control bits into a string.
511  length = length of string to encode into (including terminating
512  null). length *MUST BE MORE THAN 2* !
513  **********************************************************/
514
515 char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
516 {
517   static fstring acct_str;
518   size_t i = 0;
519
520   acct_str[i++] = '[';
521
522   if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
523   if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
524   if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
525   if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
526   if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
527   if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
528   if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
529   if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
530   if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
531   if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
532   if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
533
534   for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
535
536   i = length - 2;
537   acct_str[i++] = ']';
538   acct_str[i++] = '\0';
539
540   return acct_str;
541 }     
542
543 /**********************************************************
544  Decode the account control bits from a string.
545
546  this function breaks coding standards minimum line width of 80 chars.
547  reason: vertical line-up code clarity - all case statements fit into
548  15 lines, which is more important.
549  **********************************************************/
550
551 uint16 pwdb_decode_acct_ctrl(const char *p)
552 {
553         uint16 acct_ctrl = 0;
554         BOOL finished = False;
555
556         /*
557          * Check if the account type bits have been encoded after the
558          * NT password (in the form [NDHTUWSLXI]).
559          */
560
561         if (*p != '[') return 0;
562
563         for (p++; *p && !finished; p++)
564         {
565                 switch (*p)
566                 {
567                         case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
568                         case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
569                         case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
570                         case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
571                         case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
572                         case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
573                         case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
574                         case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
575                         case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
576                         case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
577                         case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
578             case ' ': { break; }
579                         case ':':
580                         case '\n':
581                         case '\0': 
582                         case ']':
583                         default:  { finished = True; }
584                 }
585         }
586
587         return acct_ctrl;
588 }
589
590 /*******************************************************************
591  gets password-database-format time from a string.
592  ********************************************************************/
593
594 static time_t get_time_from_string(const char *p)
595 {
596         int i;
597
598         for (i = 0; i < 8; i++)
599         {
600                 if (p[i] == '\0' || !isxdigit((int)(p[i]&0xFF)))
601                 {
602                         break;
603                 }
604         }
605         if (i == 8)
606         {
607                 /*
608                  * p points at 8 characters of hex digits - 
609                  * read into a time_t as the seconds since
610                  * 1970 that the password was last changed.
611                  */
612                 return (time_t)strtol(p, NULL, 16);
613         }
614         return (time_t)-1;
615 }
616
617 /*******************************************************************
618  gets password last set time
619  ********************************************************************/
620
621 time_t pwdb_get_last_set_time(const char *p)
622 {
623         if (*p && StrnCaseCmp(p, "LCT-", 4))
624         {
625                 return get_time_from_string(p + 4);
626         }
627         return (time_t)-1;
628 }
629
630
631 /*******************************************************************
632  sets password-database-format time in a string.
633  ********************************************************************/
634 static void set_time_in_string(char *p, int max_len, char *type, time_t t)
635 {
636         slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
637 }
638
639 /*******************************************************************
640  sets logon time
641  ********************************************************************/
642 void pwdb_set_logon_time(char *p, int max_len, time_t t)
643 {
644         set_time_in_string(p, max_len, "LNT", t);
645 }
646
647 /*******************************************************************
648  sets logoff time
649  ********************************************************************/
650 void pwdb_set_logoff_time(char *p, int max_len, time_t t)
651 {
652         set_time_in_string(p, max_len, "LOT", t);
653 }
654
655 /*******************************************************************
656  sets kickoff time
657  ********************************************************************/
658 void pwdb_set_kickoff_time(char *p, int max_len, time_t t)
659 {
660         set_time_in_string(p, max_len, "KOT", t);
661 }
662
663 /*******************************************************************
664  sets password can change time
665  ********************************************************************/
666 void pwdb_set_can_change_time(char *p, int max_len, time_t t)
667 {
668         set_time_in_string(p, max_len, "CCT", t);
669 }
670
671 /*******************************************************************
672  sets password last set time
673  ********************************************************************/
674 void pwdb_set_must_change_time(char *p, int max_len, time_t t)
675 {
676         set_time_in_string(p, max_len, "MCT", t);
677 }
678
679 /*******************************************************************
680  sets password last set time
681  ********************************************************************/
682 void pwdb_set_last_set_time(char *p, int max_len, time_t t)
683 {
684         set_time_in_string(p, max_len, "LCT", t);
685 }
686
687
688 /*************************************************************
689  Routine to set 32 hex password characters from a 16 byte array.
690 **************************************************************/
691 void pwdb_sethexpwd(char *p, char *pwd, uint16 acct_ctrl)
692 {
693         if (pwd != NULL)
694         {
695                 int i;
696                 for (i = 0; i < 16; i++)
697                 {
698                         slprintf(&p[i*2], 33, "%02X", pwd[i]);
699                 }
700         }
701         else
702         {
703                 if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
704                 {
705                         safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
706                 }
707                 else
708                 {
709                         safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
710                 }
711         }
712 }
713
714 /*************************************************************
715  Routine to get the 32 hex characters and turn them
716  into a 16 byte array.
717 **************************************************************/
718 BOOL pwdb_gethexpwd(char *p, char *pwd)
719 {
720         return strhex_to_str(pwd, 32, p) == 16;
721 }
722
723 /*******************************************************************
724  converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
725  ********************************************************************/
726 uid_t pwdb_user_rid_to_uid(uint32 user_rid)
727 {
728         uid_t uid = (uid_t)(((user_rid & (~RID_TYPE_USER))- 1000)/RID_MULTIPLIER);
729         return uid;
730 }
731
732 /*******************************************************************
733  converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
734  ********************************************************************/
735 uint32 pwdb_uid_to_user_rid(uid_t uid)
736 {
737         uint32 user_rid = (((((uint32)uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
738         return user_rid;
739 }
740
741 /*******************************************************************
742  converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
743  ********************************************************************/
744 uint32 pwdb_gid_to_group_rid(gid_t gid)
745 {
746         uint32 grp_rid = (((((uint32)gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
747         return grp_rid;
748 }
749
750 /*******************************************************************
751  converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
752  ********************************************************************/
753 gid_t pwdb_group_rid_to_gid(uint32 group_rid)
754 {
755         gid_t gid = (gid_t)(((group_rid & (~RID_TYPE_GROUP))- 1000)/RID_MULTIPLIER);
756         return gid;
757 }
758
759 /*******************************************************************
760  converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
761  ********************************************************************/
762 uint32 pwdb_gid_to_alias_rid(gid_t gid)
763 {
764         uint32 alias_rid = (((((uint32)gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
765         return alias_rid;
766 }
767
768 /*******************************************************************
769  converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
770  ********************************************************************/
771 gid_t pwdb_alias_rid_to_gid(uint32 alias_rid)
772 {
773         gid_t gid = (gid_t)(((alias_rid & (~RID_TYPE_ALIAS))- 1000)/RID_MULTIPLIER);
774         return gid;
775 }
776
777 /*******************************************************************
778  Decides if a RID is a well known RID.
779  ********************************************************************/
780 static BOOL pwdb_rid_is_well_known(uint32 rid)
781 {
782         return (rid < 1000);
783 }
784
785 /*******************************************************************
786  determines a rid's type.  NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
787  ********************************************************************/
788 static uint32 pwdb_rid_type(uint32 rid)
789 {
790         /* lkcl i understand that NT attaches an enumeration to a RID
791          * such that it can be identified as either a user, group etc
792          * type: SID_ENUM_TYPE.
793          */
794         if (pwdb_rid_is_well_known(rid))
795         {
796                 /*
797                  * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
798                  * and DOMAIN_USER_RID_GUEST.
799                  */
800                 if (rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
801                 {
802                         return RID_TYPE_USER;
803                 }
804                 if (DOMAIN_GROUP_RID_ADMINS <= rid && rid <= DOMAIN_GROUP_RID_GUESTS)
805                 {
806                         return RID_TYPE_GROUP;
807                 }
808                 if (BUILTIN_ALIAS_RID_ADMINS <= rid && rid <= BUILTIN_ALIAS_RID_REPLICATOR)
809                 {
810                         return RID_TYPE_ALIAS;
811                 }
812         }
813         return (rid & RID_TYPE_MASK);
814 }
815
816 /*******************************************************************
817  checks whether rid is a user rid.  NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
818  ********************************************************************/
819 BOOL pwdb_rid_is_user(uint32 rid)
820 {
821         return pwdb_rid_type(rid) == RID_TYPE_USER;
822 }
823