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
33 DOM_SID global_machine_sid;
36 * NOTE. All these functions are abstracted into a structure
37 * that points to the correct function for the selected database. JRA.
39 * NOTE. for the get/mod/add functions, there are two sets of functions.
40 * one supports struct sam_passwd, the other supports struct smb_passwd.
41 * for speed optimisation it is best to support both these sets.
43 * it is, however, optional to support one set but not the other: there
44 * is conversion-capability built in to passdb.c, and run-time error
45 * detection for when neither are supported.
47 * password database writers are recommended to implement the sam_passwd
48 * functions in a first pass, as struct sam_passwd contains more
49 * information, needed by the NT Domain support.
51 * a full example set of derivative functions are listed below. an API
52 * writer is expected to cut/paste these into their module, replace
53 * either one set (struct smb_passwd) or the other (struct sam_passwd)
54 * OR both, and optionally also to write display info routines
55 * (struct sam_disp_info). lkcl
60 static struct smb_passwd *getPDBpwent (void *vp) { return pdb_sam_to_smb(getPDB21pwent(vp)); }
61 static BOOL add_PDBpwd_entry (struct smb_passwd *newpwd) { return add_PDB21pwd_entry(pdb_smb_to_sam(newpwd)); }
62 static BOOL mod_PDBpwd_entry (struct smb_passwd* pwd, BOOL override) { return mod_PDB21pwd_entry(pdb_smb_to_sam(pwd), override); }
63 static struct smb_passwd *getPDBpwnam (char *name) { return pdb_sam_to_smb(getPDB21pwnam(name)); }
64 static struct smb_passwd *getPDBpwuid (uid_t smb_userid) { return pdb_sam_to_smb(getPDB21pwuid(pdb_uid_to_user_rid(smb_userid))); }
66 static struct sam_passwd *getPDB21pwent (void *vp) { return pdb_smb_to_sam(getPDBpwent(vp)); }
67 static BOOL add_PDB21pwd_entry (struct sam_passwd *newpwd) { return add_PDBpwd_entry(pdb_sam_to_smb(newpwd)); }
68 static BOOL mod_PDB21pwd_entry (struct sam_passwd* pwd, BOOL override) { return mod_PDBpwd_entry(pdb_sam_to_smb(pwd), override); }
69 static struct sam_passwd *getPDB21pwnam (char *name) { return pdb_smb_to_sam(getPDBpwnam(name)); }
70 static struct sam_passwd *getPDB21pwrid (uint32 rid) { return pdb_smb_to_sam(getPDBpwuid(pdb_user_rid_to_uid(rid))); }
71 static struct sam_passwd *getPDB21pwuid (uid_t uid) { return pdb_smb_to_sam(getPDBpwuid(uid)); }
73 static struct sam_disp_info *getPDBdispnam (char *name) { return pdb_sam_to_dispinfo(getPDB21pwnam(name)); }
74 static struct sam_disp_info *getPDBdisprid (uint32 rid) { return pdb_sam_to_dispinfo(getPDB21pwrid(rid)); }
75 static struct sam_disp_info *getPDBdispent (void *vp) { return pdb_sam_to_dispinfo(getPDB21pwent(vp)); }
78 static struct passdb_ops *pdb_ops;
80 /***************************************************************
81 Initialize the password db operations.
82 ***************************************************************/
84 BOOL initialize_password_db(void)
92 pdb_ops = nisplus_initialize_password_db();
93 #endif /* USE_NISPLUS_DB */
96 pdb_ops = ldap_initialize_password_db();
97 #endif /* USE_LDAP_DB */
100 pdb_ops = file_initialize_password_db();
101 #endif /* USE_SMBPASS_DB */
103 return (pdb_ops != NULL);
107 * Functions that return/manipulate a struct smb_passwd.
110 /************************************************************************
111 Utility function to search smb passwd by uid. use this if your database
112 does not have search facilities.
113 *************************************************************************/
115 struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid)
117 struct smb_passwd *pwd = NULL;
120 DEBUG(10, ("iterate_getsmbpwuid: search by smb_userid: %x\n", smb_userid));
122 /* Open the smb password database - not for update. */
123 fp = startsmbpwent(False);
127 DEBUG(0, ("iterate_getsmbpwuid: unable to open smb password database.\n"));
131 while ((pwd = getsmbpwent(fp)) != NULL && pwd->smb_userid != smb_userid)
136 DEBUG(10, ("iterate_getsmbpwuid: found by smb_userid: %x\n", smb_userid));
143 /************************************************************************
144 Utility function to search smb passwd by name. use this if your database
145 does not have search facilities.
146 *************************************************************************/
148 struct smb_passwd *iterate_getsmbpwnam(char *name)
150 struct smb_passwd *pwd = NULL;
153 DEBUG(10, ("iterate_getsmbpwnam: search by name: %s\n", name));
155 /* Open the sam password file - not for update. */
156 fp = startsmbpwent(False);
160 DEBUG(0, ("iterate_getsmbpwnam: unable to open smb password database.\n"));
164 while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->smb_name, name))
169 DEBUG(10, ("iterate_getsmbpwnam: found by name: %s\n", name));
176 /***************************************************************
177 Start to enumerate the smb or sam passwd list. Returns a void pointer
178 to ensure no modification outside this module.
180 Note that currently it is being assumed that a pointer returned
181 from this function may be used to enumerate struct sam_passwd
182 entries as well as struct smb_passwd entries. This may need
185 ****************************************************************/
187 void *startsmbpwent(BOOL update)
189 return pdb_ops->startsmbpwent(update);
192 /***************************************************************
193 End enumeration of the smb or sam passwd list.
195 Note that currently it is being assumed that a pointer returned
196 from this function may be used to enumerate struct sam_passwd
197 entries as well as struct smb_passwd entries. This may need
200 ****************************************************************/
202 void endsmbpwent(void *vp)
204 pdb_ops->endsmbpwent(vp);
207 /*************************************************************************
208 Routine to return the next entry in the smb passwd list.
209 *************************************************************************/
211 struct smb_passwd *getsmbpwent(void *vp)
213 return pdb_ops->getsmbpwent(vp);
216 /*************************************************************************
217 Return the current position in the smb passwd list as an unsigned long.
218 This must be treated as an opaque token.
220 Note that currently it is being assumed that a pointer returned
221 from this function may be used to enumerate struct sam_passwd
222 entries as well as struct smb_passwd entries. This may need
225 *************************************************************************/
227 unsigned long getsmbpwpos(void *vp)
229 return pdb_ops->getsmbpwpos(vp);
232 /*************************************************************************
233 Set the current position in the smb passwd list from unsigned long.
234 This must be treated as an opaque token.
236 Note that currently it is being assumed that a pointer returned
237 from this function may be used to enumerate struct sam_passwd
238 entries as well as struct smb_passwd entries. This may need
241 *************************************************************************/
243 BOOL setsmbpwpos(void *vp, unsigned long tok)
245 return pdb_ops->setsmbpwpos(vp, tok);
248 /************************************************************************
249 Routine to add an entry to the smb passwd file.
250 *************************************************************************/
252 BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
254 return pdb_ops->add_smbpwd_entry(newpwd);
257 /************************************************************************
258 Routine to search the smb passwd file for an entry matching the username.
259 and then modify its password entry. We can't use the startsampwent()/
260 getsampwent()/endsampwent() interfaces here as we depend on looking
261 in the actual file to decide how much room we have to write data.
262 override = False, normal
263 override = True, override XXXXXXXX'd out password or NO PASS
264 ************************************************************************/
266 BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
268 return pdb_ops->mod_smbpwd_entry(pwd, override);
271 /************************************************************************
272 Routine to search smb passwd by name.
273 *************************************************************************/
275 struct smb_passwd *getsmbpwnam(char *name)
277 return pdb_ops->getsmbpwnam(name);
280 /************************************************************************
281 Routine to search smb passwd by uid.
282 *************************************************************************/
284 struct smb_passwd *getsmbpwuid(uid_t smb_userid)
286 return pdb_ops->getsmbpwuid(smb_userid);
290 * Functions that manupulate a struct sam_passwd.
293 /************************************************************************
294 Utility function to search sam passwd by name. use this if your database
295 does not have search facilities.
296 *************************************************************************/
298 struct sam_passwd *iterate_getsam21pwnam(char *name)
300 struct sam_passwd *pwd = NULL;
303 DEBUG(10, ("iterate_getsam21pwnam: search by name: %s\n", name));
305 /* Open the smb password database - not for update. */
306 fp = startsmbpwent(False);
310 DEBUG(0, ("iterate_getsam21pwnam: unable to open sam password database.\n"));
314 while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name))
319 DEBUG(10, ("iterate_getsam21pwnam: found by name: %s\n", name));
326 /************************************************************************
327 Utility function to search sam passwd by uid. use this if your database
328 does not have search facilities.
330 search capability by both rid and uid are needed as the rid <-> uid
331 mapping may be non-monotonic.
333 *************************************************************************/
335 struct sam_passwd *iterate_getsam21pwrid(uint32 rid)
337 struct sam_passwd *pwd = NULL;
340 DEBUG(10, ("iterate_getsam21pwrid: search by rid: %x\n", rid));
342 /* Open the smb password file - not for update. */
343 fp = startsmbpwent(False);
347 DEBUG(0, ("iterate_getsam21pwrid: unable to open sam password database.\n"));
351 while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid)
356 DEBUG(10, ("iterate_getsam21pwrid: found by user_rid: %x\n", rid));
363 /************************************************************************
364 Utility function to search sam passwd by uid. use this if your database
365 does not have search facilities.
367 search capability by both rid and uid are needed as the rid <-> uid
368 mapping may be non-monotonic.
370 *************************************************************************/
372 struct sam_passwd *iterate_getsam21pwuid(uid_t uid)
374 struct sam_passwd *pwd = NULL;
377 DEBUG(10, ("iterate_getsam21pwuid: search by uid: %x\n", uid));
379 /* Open the smb password file - not for update. */
380 fp = startsmbpwent(False);
384 DEBUG(0, ("iterate_getsam21pwuid: unable to open sam password database.\n"));
388 while ((pwd = getsam21pwent(fp)) != NULL && pwd->smb_userid != uid)
393 DEBUG(10, ("iterate_getsam21pwuid: found by smb_userid: %x\n", uid));
400 /*************************************************************************
401 Routine to return a display info structure, by name
402 *************************************************************************/
403 struct sam_disp_info *getsamdispnam(char *name)
405 return pdb_ops->getsamdispnam(name);
408 /*************************************************************************
409 Routine to return a display info structure, by rid
410 *************************************************************************/
411 struct sam_disp_info *getsamdisprid(uint32 rid)
413 return pdb_ops->getsamdisprid(rid);
416 /*************************************************************************
417 Routine to return the next entry in the sam passwd list.
418 *************************************************************************/
419 struct sam_disp_info *getsamdispent(void *vp)
421 return pdb_ops->getsamdispent(vp);
424 /*************************************************************************
425 Routine to return the next entry in the sam passwd list.
426 *************************************************************************/
428 struct sam_passwd *getsam21pwent(void *vp)
430 return pdb_ops->getsam21pwent(vp);
433 /************************************************************************
434 Routine to add an entry to the sam passwd file.
435 *************************************************************************/
437 BOOL add_sam21pwd_entry(struct sam_passwd *newpwd)
439 return pdb_ops->add_sam21pwd_entry(newpwd);
442 /************************************************************************
443 Routine to search the sam passwd database for an entry matching the username.
444 and then modify its password entry. We can't use the startsampwent()/
445 getsampwent()/endsampwent() interfaces here as we depend on looking
446 in the actual file to decide how much room we have to write data.
447 override = False, normal
448 override = True, override XXXXXXXX'd out password or NO PASS
449 ************************************************************************/
451 BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override)
453 return pdb_ops->mod_sam21pwd_entry(pwd, override);
457 /************************************************************************
458 Routine to search sam passwd by name.
459 *************************************************************************/
461 struct sam_passwd *getsam21pwnam(char *name)
463 return pdb_ops->getsam21pwnam(name);
466 /************************************************************************
467 Routine to search sam passwd by rid.
468 *************************************************************************/
470 struct sam_passwd *getsam21pwrid(uint32 rid)
472 return pdb_ops->getsam21pwrid(rid);
475 /************************************************************************
476 Routine to search sam passwd by uid.
477 *************************************************************************/
479 struct sam_passwd *getsam21pwuid(uid_t uid)
481 return pdb_ops->getsam21pwuid(uid);
487 /**********************************************************
488 **********************************************************
490 utility routines which are likely to be useful to all password
493 **********************************************************
494 **********************************************************/
496 /*************************************************************
497 initialises a struct sam_disp_info.
498 **************************************************************/
500 void pdb_init_dispinfo(struct sam_disp_info *user)
502 if (user == NULL) return;
503 bzero(user, sizeof(*user));
506 /*************************************************************
507 initialises a struct smb_passwd.
508 **************************************************************/
510 void pdb_init_smb(struct smb_passwd *user)
512 if (user == NULL) return;
513 bzero(user, sizeof(*user));
514 user->pass_last_set_time = (time_t)-1;
517 /*************************************************************
518 initialises a struct sam_passwd.
519 **************************************************************/
520 void pdb_init_sam(struct sam_passwd *user)
522 if (user == NULL) return;
523 bzero(user, sizeof(*user));
524 user->logon_time = (time_t)-1;
525 user->logoff_time = (time_t)-1;
526 user->kickoff_time = (time_t)-1;
527 user->pass_last_set_time = (time_t)-1;
528 user->pass_can_change_time = (time_t)-1;
529 user->pass_must_change_time = (time_t)-1;
532 /*************************************************************************
533 Routine to return the next entry in the sam passwd list.
534 *************************************************************************/
536 struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user)
538 static struct sam_disp_info disp_info;
540 if (user == NULL) return NULL;
542 pdb_init_dispinfo(&disp_info);
544 disp_info.smb_name = user->smb_name;
545 disp_info.full_name = user->full_name;
546 disp_info.user_rid = user->user_rid;
551 /*************************************************************
552 converts a sam_passwd structure to a smb_passwd structure.
553 **************************************************************/
555 struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user)
557 static struct smb_passwd pw_buf;
559 if (user == NULL) return NULL;
561 pdb_init_smb(&pw_buf);
563 pw_buf.smb_userid = user->smb_userid;
564 pw_buf.smb_name = user->smb_name;
565 pw_buf.smb_passwd = user->smb_passwd;
566 pw_buf.smb_nt_passwd = user->smb_nt_passwd;
567 pw_buf.acct_ctrl = user->acct_ctrl;
568 pw_buf.pass_last_set_time = user->pass_last_set_time;
573 /*************************************************************
574 converts a smb_passwd structure to a sam_passwd structure.
575 **************************************************************/
577 struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user)
579 static struct sam_passwd pw_buf;
581 if (user == NULL) return NULL;
583 pdb_init_sam(&pw_buf);
585 pw_buf.smb_userid = user->smb_userid;
586 pw_buf.smb_name = user->smb_name;
587 pw_buf.smb_passwd = user->smb_passwd;
588 pw_buf.smb_nt_passwd = user->smb_nt_passwd;
589 pw_buf.acct_ctrl = user->acct_ctrl;
590 pw_buf.pass_last_set_time = user->pass_last_set_time;
597 COMMENTED OUT UNTIL SOMETHING ACTUALLY USES THEM. JRA.
599 /*******************************************************************
600 gets password-database-format time from a string.
601 ********************************************************************/
603 static time_t get_time_from_string(char *p)
607 for (i = 0; i < 8; i++)
609 if (p[i] == '\0' || !isxdigit(p[i]))
615 * p points at 8 characters of hex digits -
616 * read into a time_t as the seconds since
617 * 1970 that the password was last changed.
619 return (time_t)strtol((char *)p, NULL, 16);
624 /*******************************************************************
625 gets password last set time
626 ********************************************************************/
628 time_t pdb_get_last_set_time(char *p)
630 if (*p && StrnCaseCmp((char *)p, "LCT-", 4))
632 return get_time_from_string(p + 4);
638 /*******************************************************************
639 sets password-database-format time in a string.
640 ********************************************************************/
642 static void set_time_in_string(char *p, int max_len, char *type, time_t t)
644 slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
647 /*******************************************************************
648 sets password last set time
649 ********************************************************************/
651 void pdb_set_last_set_time(char *p, int max_len, time_t t)
653 set_time_in_string(p, max_len, "LCT", t);
658 /**********************************************************
659 Encode the account control bits into a string.
660 **********************************************************/
662 char *pdb_encode_acct_ctrl(uint16 acct_ctrl)
664 static fstring acct_str;
669 if (acct_ctrl & ACB_HOMDIRREQ) *p++ = 'H';
670 if (acct_ctrl & ACB_TEMPDUP ) *p++ = 'T';
671 if (acct_ctrl & ACB_NORMAL ) *p++ = 'U';
672 if (acct_ctrl & ACB_MNS ) *p++ = 'M';
673 if (acct_ctrl & ACB_WSTRUST ) *p++ = 'W';
674 if (acct_ctrl & ACB_SVRTRUST ) *p++ = 'S';
675 if (acct_ctrl & ACB_AUTOLOCK ) *p++ = 'L';
676 if (acct_ctrl & ACB_PWNOEXP ) *p++ = 'X';
677 if (acct_ctrl & ACB_DOMTRUST ) *p++ = 'I';
684 /**********************************************************
685 Decode the account control bits from a string.
687 this function breaks coding standards minimum line width of 80 chars.
688 reason: vertical line-up code clarity - all case statements fit into
689 15 lines, which is more important.
690 **********************************************************/
692 uint16 pdb_decode_acct_ctrl(char *p)
694 uint16 acct_ctrl = 0;
695 BOOL finished = False;
698 * Check if the account type bits have been encoded after the
699 * NT password (in the form [NDHTUWSLXI]).
702 if (*p != '[') return 0;
704 for (p++; *p && !finished; p++)
710 * Hmmm. Don't allow these to be set/read independently
711 * of the actual password fields. We don't want a mismatch.
714 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
715 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
717 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
718 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
719 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
720 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
721 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
722 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
723 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
724 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
725 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
731 default: { finished = True; }
738 /*************************************************************
739 Routine to get the next 32 hex characters and turn them
740 into a 16 byte array.
741 **************************************************************/
743 int pdb_gethexpwd(char *p, char *pwd)
746 unsigned char lonybble, hinybble;
747 char *hexchars = "0123456789ABCDEF";
750 for (i = 0; i < 32; i += 2) {
751 hinybble = toupper(p[i]);
752 lonybble = toupper(p[i + 1]);
754 p1 = strchr(hexchars, hinybble);
755 p2 = strchr(hexchars, lonybble);
758 hinybble = PTR_DIFF(p1, hexchars);
759 lonybble = PTR_DIFF(p2, hexchars);
761 pwd[i / 2] = (hinybble << 4) | lonybble;
766 /*******************************************************************
767 Group and User RID username mapping function
768 ********************************************************************/
770 BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
772 struct passwd *pw = Get_Pwnam(user_name, False);
774 if (u_rid == NULL || g_rid == NULL || user_name == NULL)
781 DEBUG(1,("Username %s is invalid on this system\n", user_name));
785 if (user_in_list(user_name, lp_domain_guest_users()))
787 *u_rid = DOMAIN_USER_RID_GUEST;
789 else if (user_in_list(user_name, lp_domain_admin_users()))
791 *u_rid = DOMAIN_USER_RID_ADMIN;
795 /* turn the unix UID into a Domain RID. this is what the posix
796 sub-system does (adds 1000 to the uid) */
797 *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
800 /* absolutely no idea what to do about the unix GID to Domain RID mapping */
801 *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
806 /****************************************************************************
807 Read the machine SID from a file.
808 ****************************************************************************/
810 static BOOL read_sid_from_file(int fd, char *sid_file)
814 if(read(fd, &fline, sizeof(fline) -1 ) < 0) {
815 DEBUG(0,("read_sid_from_file: unable to read file %s. Error was %s\n",
816 sid_file, strerror(errno) ));
821 * Convert to the machine SID.
824 fline[sizeof(fline)-1] = '\0';
825 if(!string_to_sid( &global_machine_sid, fline)) {
826 DEBUG(0,("read_sid_from_file: unable to generate machine SID.\n"));
833 /****************************************************************************
834 Generate the global machine sid. Look for the MACHINE.SID file first, if
835 not found then look in smb.conf and use it to create the MACHINE.SID file.
836 ****************************************************************************/
838 BOOL pdb_generate_machine_sid(void)
845 uchar raw_sid_data[12];
847 pstrcpy(sid_file, lp_smb_passwd_file());
848 p = strrchr(sid_file, '/');
852 pstrcat(sid_file, "MACHINE.SID");
854 if((fd = open( sid_file, O_RDWR | O_CREAT, 0644)) < 0 ) {
855 DEBUG(0,("generate_machine_sid: unable to open or create file %s. Error was %s\n",
856 sid_file, strerror(errno) ));
861 * Check if the file contains data.
864 if(fstat( fd, &st) < 0) {
865 DEBUG(0,("generate_machine_sid: unable to stat file %s. Error was %s\n",
866 sid_file, strerror(errno) ));
873 * We have a valid SID - read it.
875 if(!read_sid_from_file( fd, sid_file)) {
876 DEBUG(0,("generate_machine_sid: unable to read file %s. Error was %s\n",
877 sid_file, strerror(errno) ));
886 * The file contains no data - we may need to generate our
887 * own sid. Try the lp_domain_sid() first.
891 fstrcpy( sid_string, lp_domain_sid());
894 * Generate the new sid data & turn it into a string.
897 generate_random_buffer( raw_sid_data, 12, True);
899 fstrcpy( sid_string, "S-1-5-21");
900 for( i = 0; i < 3; i++) {
902 slprintf( tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
903 fstrcat( sid_string, tmp_string);
907 fstrcat(sid_string, "\n");
910 * Ensure our new SID is valid.
913 if(!string_to_sid( &global_machine_sid, sid_string)) {
914 DEBUG(0,("generate_machine_sid: unable to generate machine SID.\n"));
919 * Do an exclusive blocking lock on the file.
922 if(!do_file_lock( fd, 60, F_WRLCK)) {
923 DEBUG(0,("generate_machine_sid: unable to lock file %s. Error was %s\n",
924 sid_file, strerror(errno) ));
930 * At this point we have a blocking lock on the SID
931 * file - check if in the meantime someone else wrote
932 * SID data into the file. If so - they were here first,
936 if(fstat( fd, &st) < 0) {
937 DEBUG(0,("generate_machine_sid: unable to stat file %s. Error was %s\n",
938 sid_file, strerror(errno) ));
945 * Unlock as soon as possible to reduce
946 * contention on the exclusive lock.
948 do_file_lock( fd, 60, F_UNLCK);
951 * We have a valid SID - read it.
954 if(!read_sid_from_file( fd, sid_file)) {
955 DEBUG(0,("generate_machine_sid: unable to read file %s. Error was %s\n",
956 sid_file, strerror(errno) ));
965 * The file is still empty and we have an exlusive lock on it.
966 * Write out out SID data into the file.
969 if(fchmod(fd, 0644) < 0) {
970 DEBUG(0,("generate_machine_sid: unable to set correct permissions on file %s. \
971 Error was %s\n", sid_file, strerror(errno) ));
976 if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
977 DEBUG(0,("generate_machine_sid: unable to write file %s. Error was %s\n",
978 sid_file, strerror(errno) ));
987 do_file_lock( fd, 60, F_UNLCK);
992 /*******************************************************************
993 converts NT User RID to a UNIX uid.
994 ********************************************************************/
996 uid_t pdb_user_rid_to_uid(uint32 u_rid)
998 return (uid_t)(u_rid - 1000);
1001 /*******************************************************************
1002 converts NT Group RID to a UNIX uid.
1003 ********************************************************************/
1005 gid_t pdb_group_rid_to_gid(uint32 g_rid)
1007 return (gid_t)(g_rid - 1000);
1010 /*******************************************************************
1011 converts UNIX uid to an NT User RID.
1012 ********************************************************************/
1014 uint32 pdb_uid_to_user_rid(uid_t uid)
1016 return (uint32)(uid + 1000);
1019 /*******************************************************************
1020 converts NT Group RID to a UNIX uid.
1021 ********************************************************************/
1023 uint32 pdb_gid_to_group_rid(gid_t gid)
1025 return (uint32)(gid + 1000);
1028 /*******************************************************************
1029 Decides if a RID is a user or group RID.
1030 ********************************************************************/
1032 BOOL pdb_rid_is_user(uint32 rid)
1034 /* Punt for now - we need to look at the encoding here. JRA. */
1035 /* lkcl i understand that NT attaches an enumeration to a RID
1036 * such that it can be identified as either a user, group etc
1037 * type. there are 5 such categories, and they are documented.