2 Unix SMB/Netbios implementation.
4 Password and authentication handling
5 Copyright (C) Jeremy Allison 1996-1998
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
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.
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.
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.
26 extern int DEBUGLEVEL
;
29 * This is set on startup - it defines the SID for this
30 * machine, and therefore the SAM database for which it is
34 DOM_SID global_sam_sid
;
37 * NOTE. All these functions are abstracted into a structure
38 * that points to the correct function for the selected database. JRA.
40 * NOTE. for the get/mod/add functions, there are two sets of functions.
41 * one supports struct sam_passwd, the other supports struct smb_passwd.
42 * for speed optimisation it is best to support both these sets.
44 * it is, however, optional to support one set but not the other: there
45 * is conversion-capability built in to passdb.c, and run-time error
46 * detection for when neither are supported.
48 * password database writers are recommended to implement the sam_passwd
49 * functions in a first pass, as struct sam_passwd contains more
50 * information, needed by the NT Domain support.
52 * a full example set of derivative functions are listed below. an API
53 * writer is expected to cut/paste these into their module, replace
54 * either one set (struct smb_passwd) or the other (struct sam_passwd)
55 * OR both, and optionally also to write display info routines
56 * (struct sam_disp_info). lkcl
60 static struct passdb_ops
*pdb_ops
;
62 /***************************************************************
63 Initialize the password db operations.
64 ***************************************************************/
66 BOOL
initialize_password_db(void)
74 pdb_ops
= nisplus_initialize_password_db();
75 #elif defined(WITH_LDAP)
76 pdb_ops
= ldap_initialize_password_db();
78 pdb_ops
= file_initialize_password_db();
81 return (pdb_ops
!= NULL
);
85 * Functions that return/manipulate a struct smb_passwd.
88 /************************************************************************
89 Utility function to search smb passwd by rid.
90 *************************************************************************/
92 struct smb_passwd
*iterate_getsmbpwrid(uint32 user_rid
)
94 return iterate_getsmbpwuid(pdb_user_rid_to_uid(user_rid
));
97 /************************************************************************
98 Utility function to search smb passwd by uid. use this if your database
99 does not have search facilities.
100 *************************************************************************/
102 struct smb_passwd
*iterate_getsmbpwuid(uid_t smb_userid
)
104 struct smb_passwd
*pwd
= NULL
;
107 DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid
));
109 /* Open the smb password database - not for update. */
110 fp
= startsmbpwent(False
);
114 DEBUG(0, ("unable to open smb password database.\n"));
118 while ((pwd
= getsmbpwent(fp
)) != NULL
&& pwd
->smb_userid
!= smb_userid
)
123 DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid
));
130 /************************************************************************
131 Utility function to search smb passwd by name. use this if your database
132 does not have search facilities.
133 *************************************************************************/
135 struct smb_passwd
*iterate_getsmbpwnam(char *name
)
137 struct smb_passwd
*pwd
= NULL
;
140 DEBUG(10, ("search by name: %s\n", name
));
142 /* Open the sam password file - not for update. */
143 fp
= startsmbpwent(False
);
147 DEBUG(0, ("unable to open smb password database.\n"));
151 while ((pwd
= getsmbpwent(fp
)) != NULL
&& !strequal(pwd
->smb_name
, name
))
156 DEBUG(10, ("found by name: %s\n", name
));
163 /***************************************************************
164 Start to enumerate the smb or sam passwd list. Returns a void pointer
165 to ensure no modification outside this module.
167 Note that currently it is being assumed that a pointer returned
168 from this function may be used to enumerate struct sam_passwd
169 entries as well as struct smb_passwd entries. This may need
172 ****************************************************************/
174 void *startsmbpwent(BOOL update
)
176 return pdb_ops
->startsmbpwent(update
);
179 /***************************************************************
180 End enumeration of the smb or sam passwd list.
182 Note that currently it is being assumed that a pointer returned
183 from this function may be used to enumerate struct sam_passwd
184 entries as well as struct smb_passwd entries. This may need
187 ****************************************************************/
189 void endsmbpwent(void *vp
)
191 pdb_ops
->endsmbpwent(vp
);
194 /*************************************************************************
195 Routine to return the next entry in the smb passwd list.
196 *************************************************************************/
198 struct smb_passwd
*getsmbpwent(void *vp
)
200 return pdb_ops
->getsmbpwent(vp
);
203 /************************************************************************
204 Routine to add an entry to the smb passwd file.
205 *************************************************************************/
207 BOOL
add_smbpwd_entry(struct smb_passwd
*newpwd
)
209 return pdb_ops
->add_smbpwd_entry(newpwd
);
212 /************************************************************************
213 Routine to search the smb passwd file for an entry matching the username.
214 and then modify its password entry. We can't use the startsampwent()/
215 getsampwent()/endsampwent() interfaces here as we depend on looking
216 in the actual file to decide how much room we have to write data.
217 override = False, normal
218 override = True, override XXXXXXXX'd out password or NO PASS
219 ************************************************************************/
221 BOOL
mod_smbpwd_entry(struct smb_passwd
* pwd
, BOOL override
)
223 return pdb_ops
->mod_smbpwd_entry(pwd
, override
);
226 /************************************************************************
227 Routine to search smb passwd by name.
228 *************************************************************************/
230 struct smb_passwd
*getsmbpwnam(char *name
)
232 return pdb_ops
->getsmbpwnam(name
);
235 /************************************************************************
236 Routine to search smb passwd by user rid.
237 *************************************************************************/
239 struct smb_passwd
*getsmbpwrid(uint32 user_rid
)
241 return pdb_ops
->getsmbpwrid(user_rid
);
244 /************************************************************************
245 Routine to search smb passwd by uid.
246 *************************************************************************/
248 struct smb_passwd
*getsmbpwuid(uid_t smb_userid
)
250 return pdb_ops
->getsmbpwuid(smb_userid
);
254 * Functions that manupulate a struct sam_passwd.
257 /************************************************************************
258 Utility function to search sam passwd by name. use this if your database
259 does not have search facilities.
260 *************************************************************************/
262 struct sam_passwd
*iterate_getsam21pwnam(char *name
)
264 struct sam_passwd
*pwd
= NULL
;
267 DEBUG(10, ("search by name: %s\n", name
));
269 /* Open the smb password database - not for update. */
270 fp
= startsmbpwent(False
);
274 DEBUG(0, ("unable to open sam password database.\n"));
278 while ((pwd
= getsam21pwent(fp
)) != NULL
&& !strequal(pwd
->smb_name
, name
))
280 DEBUG(10, ("iterate: %s 0x%x\n", pwd
->smb_name
, pwd
->user_rid
));
285 DEBUG(10, ("found by name: %s\n", name
));
292 /************************************************************************
293 Utility function to search sam passwd by rid. use this if your database
294 does not have search facilities.
296 search capability by both rid and uid are needed as the rid <-> uid
297 mapping may be non-monotonic.
299 *************************************************************************/
301 struct sam_passwd
*iterate_getsam21pwrid(uint32 rid
)
303 struct sam_passwd
*pwd
= NULL
;
306 DEBUG(10, ("search by rid: %x\n", rid
));
308 /* Open the smb password file - not for update. */
309 fp
= startsmbpwent(False
);
313 DEBUG(0, ("unable to open sam password database.\n"));
317 while ((pwd
= getsam21pwent(fp
)) != NULL
&& pwd
->user_rid
!= rid
)
319 DEBUG(10, ("iterate: %s 0x%x\n", pwd
->smb_name
, pwd
->user_rid
));
324 DEBUG(10, ("found by user_rid: %x\n", rid
));
331 /************************************************************************
332 Utility function to search sam passwd by uid. use this if your database
333 does not have search facilities.
335 search capability by both rid and uid are needed as the rid <-> uid
336 mapping may be non-monotonic.
338 *************************************************************************/
340 struct sam_passwd
*iterate_getsam21pwuid(uid_t uid
)
342 struct sam_passwd
*pwd
= NULL
;
345 DEBUG(10, ("search by uid: %x\n", (int)uid
));
347 /* Open the smb password file - not for update. */
348 fp
= startsmbpwent(False
);
352 DEBUG(0, ("unable to open sam password database.\n"));
356 while ((pwd
= getsam21pwent(fp
)) != NULL
&& pwd
->smb_userid
!= uid
)
361 DEBUG(10, ("found by smb_userid: %x\n", (int)uid
));
368 /*************************************************************************
369 Routine to return a display info structure, by rid
370 *************************************************************************/
371 struct sam_disp_info
*getsamdisprid(uint32 rid
)
373 return pdb_ops
->getsamdisprid(rid
);
376 /*************************************************************************
377 Routine to return the next entry in the sam passwd list.
378 *************************************************************************/
380 struct sam_passwd
*getsam21pwent(void *vp
)
382 return pdb_ops
->getsam21pwent(vp
);
386 /************************************************************************
387 Routine to search sam passwd by name.
388 *************************************************************************/
390 struct sam_passwd
*getsam21pwnam(char *name
)
392 return pdb_ops
->getsam21pwnam(name
);
395 /************************************************************************
396 Routine to search sam passwd by rid.
397 *************************************************************************/
399 struct sam_passwd
*getsam21pwrid(uint32 rid
)
401 return pdb_ops
->getsam21pwrid(rid
);
405 /**********************************************************
406 **********************************************************
408 utility routines which are likely to be useful to all password
411 **********************************************************
412 **********************************************************/
414 /*************************************************************
415 initialises a struct sam_disp_info.
416 **************************************************************/
418 static void pdb_init_dispinfo(struct sam_disp_info
*user
)
420 if (user
== NULL
) return;
421 bzero(user
, sizeof(*user
));
424 /*************************************************************
425 initialises a struct smb_passwd.
426 **************************************************************/
428 void pdb_init_smb(struct smb_passwd
*user
)
430 if (user
== NULL
) return;
431 bzero(user
, sizeof(*user
));
432 user
->pass_last_set_time
= (time_t)-1;
435 /*************************************************************
436 initialises a struct sam_passwd.
437 **************************************************************/
438 void pdb_init_sam(struct sam_passwd
*user
)
440 if (user
== NULL
) return;
441 bzero(user
, sizeof(*user
));
442 user
->logon_time
= (time_t)-1;
443 user
->logoff_time
= (time_t)-1;
444 user
->kickoff_time
= (time_t)-1;
445 user
->pass_last_set_time
= (time_t)-1;
446 user
->pass_can_change_time
= (time_t)-1;
447 user
->pass_must_change_time
= (time_t)-1;
450 /*************************************************************************
451 Routine to return the next entry in the sam passwd list.
452 *************************************************************************/
454 struct sam_disp_info
*pdb_sam_to_dispinfo(struct sam_passwd
*user
)
456 static struct sam_disp_info disp_info
;
458 if (user
== NULL
) return NULL
;
460 pdb_init_dispinfo(&disp_info
);
462 disp_info
.smb_name
= user
->smb_name
;
463 disp_info
.full_name
= user
->full_name
;
464 disp_info
.user_rid
= user
->user_rid
;
469 /*************************************************************
470 converts a sam_passwd structure to a smb_passwd structure.
471 **************************************************************/
473 struct smb_passwd
*pdb_sam_to_smb(struct sam_passwd
*user
)
475 static struct smb_passwd pw_buf
;
477 if (user
== NULL
) return NULL
;
479 pdb_init_smb(&pw_buf
);
481 pw_buf
.smb_userid
= user
->smb_userid
;
482 pw_buf
.smb_name
= user
->smb_name
;
483 pw_buf
.smb_passwd
= user
->smb_passwd
;
484 pw_buf
.smb_nt_passwd
= user
->smb_nt_passwd
;
485 pw_buf
.acct_ctrl
= user
->acct_ctrl
;
486 pw_buf
.pass_last_set_time
= user
->pass_last_set_time
;
492 /*************************************************************
493 converts a smb_passwd structure to a sam_passwd structure.
494 **************************************************************/
496 struct sam_passwd
*pdb_smb_to_sam(struct smb_passwd
*user
)
498 static struct sam_passwd pw_buf
;
500 if (user
== NULL
) return NULL
;
502 pdb_init_sam(&pw_buf
);
504 pw_buf
.smb_userid
= user
->smb_userid
;
505 pw_buf
.smb_name
= user
->smb_name
;
506 pw_buf
.smb_passwd
= user
->smb_passwd
;
507 pw_buf
.smb_nt_passwd
= user
->smb_nt_passwd
;
508 pw_buf
.acct_ctrl
= user
->acct_ctrl
;
509 pw_buf
.pass_last_set_time
= user
->pass_last_set_time
;
514 /**********************************************************
515 Encode the account control bits into a string.
516 length = length of string to encode into (including terminating
517 null). length *MUST BE MORE THAN 2* !
518 **********************************************************/
520 char *pdb_encode_acct_ctrl(uint16 acct_ctrl
, size_t length
)
522 static fstring acct_str
;
527 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
528 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
529 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
530 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
531 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
532 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
533 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
534 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
535 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
536 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
537 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
539 for ( ; i
< length
- 2 ; i
++ ) { acct_str
[i
] = ' '; }
543 acct_str
[i
++] = '\0';
548 /**********************************************************
549 Decode the account control bits from a string.
551 this function breaks coding standards minimum line width of 80 chars.
552 reason: vertical line-up code clarity - all case statements fit into
553 15 lines, which is more important.
554 **********************************************************/
556 uint16
pdb_decode_acct_ctrl(char *p
)
558 uint16 acct_ctrl
= 0;
559 BOOL finished
= False
;
562 * Check if the account type bits have been encoded after the
563 * NT password (in the form [NDHTUWSLXI]).
566 if (*p
!= '[') return 0;
568 for (p
++; *p
&& !finished
; p
++)
572 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
573 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
574 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
575 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
576 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
577 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
578 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
579 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
580 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
581 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
582 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
588 default: { finished
= True
; }
595 /*******************************************************************
596 gets password-database-format time from a string.
597 ********************************************************************/
599 static time_t get_time_from_string(char *p
)
603 for (i
= 0; i
< 8; i
++)
605 if (p
[i
] == '\0' || !isxdigit((int)(p
[i
]&0xFF)))
611 * p points at 8 characters of hex digits -
612 * read into a time_t as the seconds since
613 * 1970 that the password was last changed.
615 return (time_t)strtol((char *)p
, NULL
, 16);
620 /*******************************************************************
621 gets password last set time
622 ********************************************************************/
624 time_t pdb_get_last_set_time(char *p
)
626 if (*p
&& StrnCaseCmp((char *)p
, "LCT-", 4))
628 return get_time_from_string(p
+ 4);
634 /*******************************************************************
635 sets password-database-format time in a string.
636 ********************************************************************/
637 static void set_time_in_string(char *p
, int max_len
, char *type
, time_t t
)
639 slprintf(p
, max_len
, ":%s-%08X:", type
, (uint32
)t
);
642 /*******************************************************************
644 ********************************************************************/
645 void pdb_set_logon_time(char *p
, int max_len
, time_t t
)
647 set_time_in_string(p
, max_len
, "LNT", t
);
650 /*******************************************************************
652 ********************************************************************/
653 void pdb_set_logoff_time(char *p
, int max_len
, time_t t
)
655 set_time_in_string(p
, max_len
, "LOT", t
);
658 /*******************************************************************
660 ********************************************************************/
661 void pdb_set_kickoff_time(char *p
, int max_len
, time_t t
)
663 set_time_in_string(p
, max_len
, "KOT", t
);
666 /*******************************************************************
667 sets password can change time
668 ********************************************************************/
669 void pdb_set_can_change_time(char *p
, int max_len
, time_t t
)
671 set_time_in_string(p
, max_len
, "CCT", t
);
674 /*******************************************************************
675 sets password last set time
676 ********************************************************************/
677 void pdb_set_must_change_time(char *p
, int max_len
, time_t t
)
679 set_time_in_string(p
, max_len
, "MCT", t
);
682 /*******************************************************************
683 sets password last set time
684 ********************************************************************/
685 void pdb_set_last_set_time(char *p
, int max_len
, time_t t
)
687 set_time_in_string(p
, max_len
, "LCT", t
);
691 /*************************************************************
692 Routine to set 32 hex password characters from a 16 byte array.
693 **************************************************************/
694 void pdb_sethexpwd(char *p
, char *pwd
, uint16 acct_ctrl
)
699 for (i
= 0; i
< 16; i
++)
701 slprintf(&p
[i
*2], 33, "%02X", pwd
[i
]);
706 if (IS_BITS_SET_ALL(acct_ctrl
, ACB_PWNOTREQ
))
708 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
712 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
716 /*************************************************************
717 Routine to get the 32 hex characters and turn them
718 into a 16 byte array.
719 **************************************************************/
720 BOOL
pdb_gethexpwd(char *p
, char *pwd
)
723 unsigned char lonybble
, hinybble
;
724 char *hexchars
= "0123456789ABCDEF";
727 for (i
= 0; i
< 32; i
+= 2)
729 hinybble
= toupper(p
[i
]);
730 lonybble
= toupper(p
[i
+ 1]);
732 p1
= strchr(hexchars
, hinybble
);
733 p2
= strchr(hexchars
, lonybble
);
740 hinybble
= PTR_DIFF(p1
, hexchars
);
741 lonybble
= PTR_DIFF(p2
, hexchars
);
743 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
748 /*******************************************************************
749 Group and User RID username mapping function
750 ********************************************************************/
752 BOOL
pdb_name_to_rid(char *user_name
, uint32
*u_rid
, uint32
*g_rid
)
754 struct passwd
*pw
= Get_Pwnam(user_name
, False
);
756 if (u_rid
== NULL
|| g_rid
== NULL
|| user_name
== NULL
)
763 DEBUG(1,("Username %s is invalid on this system\n", user_name
));
767 if (user_in_list(user_name
, lp_domain_guest_users()))
769 *u_rid
= DOMAIN_USER_RID_GUEST
;
771 else if (user_in_list(user_name
, lp_domain_admin_users()))
773 *u_rid
= DOMAIN_USER_RID_ADMIN
;
777 /* turn the unix UID into a Domain RID. this is what the posix
778 sub-system does (adds 1000 to the uid) */
779 *u_rid
= pdb_uid_to_user_rid(pw
->pw_uid
);
782 /* absolutely no idea what to do about the unix GID to Domain RID mapping */
783 *g_rid
= pdb_gid_to_group_rid(pw
->pw_gid
);
788 /****************************************************************************
789 Read the machine SID from a file.
790 ****************************************************************************/
792 static BOOL
read_sid_from_file(int fd
, char *sid_file
)
796 memset(fline
, '\0', sizeof(fline
));
798 if(read(fd
, fline
, sizeof(fline
) -1 ) < 0) {
799 DEBUG(0,("unable to read file %s. Error was %s\n",
800 sid_file
, strerror(errno
) ));
805 * Convert to the machine SID.
808 fline
[sizeof(fline
)-1] = '\0';
809 if(!string_to_sid( &global_sam_sid
, fline
)) {
810 DEBUG(0,("unable to generate machine SID.\n"));
817 /****************************************************************************
818 Generate the global machine sid. Look for the MACHINE.SID file first, if
819 not found then look in smb.conf and use it to create the MACHINE.SID file.
820 ****************************************************************************/
821 BOOL
pdb_generate_sam_sid(void)
828 uchar raw_sid_data
[12];
830 pstrcpy(sid_file
, lp_smb_passwd_file());
831 p
= strrchr(sid_file
, '/');
836 if (!directory_exist(sid_file
, NULL
)) {
837 if (dos_mkdir(sid_file
, 0700) != 0) {
838 DEBUG(0,("can't create private directory %s : %s\n",
839 sid_file
, strerror(errno
)));
844 pstrcat(sid_file
, "MACHINE.SID");
846 if((fd
= open(sid_file
, O_RDWR
| O_CREAT
, 0644)) == -1) {
847 DEBUG(0,("unable to open or create file %s. Error was %s\n",
848 sid_file
, strerror(errno
) ));
853 * Check if the file contains data.
856 if(sys_fstat( fd
, &st
) < 0) {
857 DEBUG(0,("unable to stat file %s. Error was %s\n",
858 sid_file
, strerror(errno
) ));
865 * We have a valid SID - read it.
867 if(!read_sid_from_file( fd
, sid_file
)) {
868 DEBUG(0,("unable to read file %s. Error was %s\n",
869 sid_file
, strerror(errno
) ));
878 * The file contains no data - we need to generate our
884 * Generate the new sid data & turn it into a string.
887 generate_random_buffer( raw_sid_data
, 12, True
);
889 fstrcpy( sid_string
, "S-1-5-21");
890 for( i
= 0; i
< 3; i
++) {
892 slprintf( tmp_string
, sizeof(tmp_string
) - 1, "-%u", IVAL(raw_sid_data
, i
*4));
893 fstrcat( sid_string
, tmp_string
);
897 fstrcat(sid_string
, "\n");
900 * Ensure our new SID is valid.
903 if(!string_to_sid( &global_sam_sid
, sid_string
)) {
904 DEBUG(0,("unable to generate machine SID.\n"));
909 * Do an exclusive blocking lock on the file.
912 if(!do_file_lock( fd
, 60, F_WRLCK
)) {
913 DEBUG(0,("unable to lock file %s. Error was %s\n",
914 sid_file
, strerror(errno
) ));
920 * At this point we have a blocking lock on the SID
921 * file - check if in the meantime someone else wrote
922 * SID data into the file. If so - they were here first,
926 if(sys_fstat( fd
, &st
) < 0) {
927 DEBUG(0,("unable to stat file %s. Error was %s\n",
928 sid_file
, strerror(errno
) ));
935 * Unlock as soon as possible to reduce
936 * contention on the exclusive lock.
938 do_file_lock( fd
, 60, F_UNLCK
);
941 * We have a valid SID - read it.
944 if(!read_sid_from_file( fd
, sid_file
)) {
945 DEBUG(0,("unable to read file %s. Error was %s\n",
946 sid_file
, strerror(errno
) ));
955 * The file is still empty and we have an exlusive lock on it.
956 * Write out out SID data into the file.
959 if(fchmod(fd
, 0644) < 0) {
960 DEBUG(0,("unable to set correct permissions on file %s. \
961 Error was %s\n", sid_file
, strerror(errno
) ));
966 if(write( fd
, sid_string
, strlen(sid_string
)) != strlen(sid_string
)) {
967 DEBUG(0,("unable to write file %s. Error was %s\n",
968 sid_file
, strerror(errno
) ));
977 do_file_lock( fd
, 60, F_UNLCK
);
982 /*******************************************************************
983 converts UNIX uid to an NT User RID.
984 ********************************************************************/
986 uid_t
pdb_user_rid_to_uid(uint32 user_rid
)
988 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
))- 1000)/RID_MULTIPLIER
);
991 /*******************************************************************
992 converts UNIX uid to an NT User RID.
993 ********************************************************************/
995 uint32
pdb_uid_to_user_rid(uid_t uid
)
997 return (((((uint32
)uid
)*RID_MULTIPLIER
) + 1000) | USER_RID_TYPE
);
1000 /*******************************************************************
1001 converts NT Group RID to a UNIX uid.
1002 ********************************************************************/
1004 uint32
pdb_gid_to_group_rid(gid_t gid
)
1006 return (((((uint32
)gid
)*RID_MULTIPLIER
) + 1000) | GROUP_RID_TYPE
);
1009 /*******************************************************************
1010 Decides if a RID is a well known RID.
1011 ********************************************************************/
1013 static BOOL
pdb_rid_is_well_known(uint32 rid
)
1015 return (rid
< 1000);
1018 /*******************************************************************
1019 Decides if a RID is a user or group RID.
1020 ********************************************************************/
1022 BOOL
pdb_rid_is_user(uint32 rid
)
1024 /* lkcl i understand that NT attaches an enumeration to a RID
1025 * such that it can be identified as either a user, group etc
1026 * type. there are 5 such categories, and they are documented.
1028 if(pdb_rid_is_well_known(rid
)) {
1030 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
1031 * and DOMAIN_USER_RID_GUEST.
1033 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
1035 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {