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 * TODO NOTE. All these functions will be abstracted into a structure
37 * that points to the correct function for the selected database. JRA.
41 * Functions that return/manipulate a struct smb_passwd.
44 /************************************************************************
45 Routine to search smb passwd by uid. use this if your database
46 does not have search facilities.
47 *************************************************************************/
49 static struct smb_passwd *_getsmbpwuid(uid_t smb_userid)
51 struct smb_passwd *pwd = NULL;
54 DEBUG(10, ("getsmbpwuid: search by smb_userid: %x\n", smb_userid));
56 /* Open the smb password database - not for update. */
57 fp = startsmbpwent(False);
61 DEBUG(0, ("getsmbpwuid: unable to open smb password database.\n"));
65 while ((pwd = getsmbpwent(fp)) != NULL && pwd->smb_userid != smb_userid)
70 DEBUG(10, ("getsmbpwuid: found by smb_userid: %x\n", smb_userid));
77 /************************************************************************
78 Routine to search smb passwd by name. use this if your database
79 does not have search facilities.
80 *************************************************************************/
82 static struct smb_passwd *_getsmbpwnam(char *name)
84 struct smb_passwd *pwd = NULL;
87 DEBUG(10, ("getsmbpwnam: search by name: %s\n", name));
89 /* Open the sam password file - not for update. */
90 fp = startsmbpwent(False);
94 DEBUG(0, ("_getsmbpwnam: unable to open smb password database.\n"));
98 while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->smb_name, name))
103 DEBUG(10, ("_getsmbpwnam: found by name: %s\n", name));
110 /***************************************************************
111 Start to enumerate the smb or sam passwd list. Returns a void pointer
112 to ensure no modification outside this module.
114 Note that currently it is being assumed that a pointer returned
115 from this function may be used to enumerate struct sam_passwd
116 entries as well as struct smb_passwd entries. This may need
118 ****************************************************************/
120 void *startsmbpwent(BOOL update)
122 #ifdef USE_NISPLUS_DB
123 return startnisppwent(update);
124 #endif /* USE_NISPLUS_DB */
127 return startldappwent(update);
128 #endif /* USE_LDAP_DB */
130 #ifdef USE_SMBPASS_DB
131 return startsmbfilepwent(update);
132 #endif /* USE_SMBPASS_DB */
135 /***************************************************************
136 End enumeration of the smb or sam passwd list.
138 Note that currently it is being assumed that a pointer returned
139 from this function may be used to enumerate struct sam_passwd
140 entries as well as struct smb_passwd entries. This may need
143 ****************************************************************/
145 void endsmbpwent(void *vp)
147 #ifdef USE_NISPLUS_DB
149 #endif /* USE_NISPLUS_DB */
153 #endif /* USE_LDAP_DB */
155 #ifdef USE_SMBPASS_DB
157 #endif /* USE_SMBPASS_DB */
160 /*************************************************************************
161 Routine to return the next entry in the sam passwd list.
162 *************************************************************************/
164 struct smb_passwd *getsmbpwent(void *vp)
166 #ifdef USE_NISPLUS_DB
167 return pdb_sam_to_smb(getnisp21pwent(vp));
168 #endif /* USE_NISPLUS_DB */
171 return pdb_sam_to_smb(getldap21pwent(vp));
172 #endif /* USE_LDAP_DB */
174 #ifdef USE_SMBPASS_DB
175 return getsmbfilepwent(vp);
176 #endif /* USE_SMBPASS_DB */
180 /*************************************************************************
181 Return the current position in the smb passwd list as an unsigned long.
182 This must be treated as an opaque token.
184 Note that currently it is being assumed that a pointer returned
185 from this function may be used to enumerate struct sam_passwd
186 entries as well as struct smb_passwd entries. This may need
189 *************************************************************************/
191 unsigned long getsmbpwpos(void *vp)
193 #ifdef USE_NISPLUS_DB
194 return getnisppwpos(vp);
195 #endif /* USE_NISPLUS_DB */
198 return getldappwpos(vp);
199 #endif /* USE_LDAP_DB */
201 #ifdef USE_SMBPASS_DB
202 return getsmbfilepwpos(vp);
203 #endif /* USE_SMBPASS_DB */
206 /*************************************************************************
207 Set the current position in the smb passwd list from unsigned long.
208 This must be treated as an opaque token.
210 Note that currently it is being assumed that a pointer returned
211 from this function may be used to enumerate struct sam_passwd
212 entries as well as struct smb_passwd entries. This may need
215 *************************************************************************/
217 BOOL setsmbpwpos(void *vp, unsigned long tok)
219 #ifdef USE_NISPLUS_DB
220 return setnisppwpos(vp, tok);
221 #endif /* USE_NISPLUS_DB */
224 return setldappwpos(vp, tok);
225 #endif /* USE_LDAP_DB */
227 #ifdef USE_SMBPASS_DB
228 return setsmbfilepwpos(vp, tok);
229 #endif /* USE_SMBPASS_DB */
232 /************************************************************************
233 Routine to add an entry to the smb passwd file.
234 *************************************************************************/
236 BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
238 #ifdef USE_NISPLUS_DB
239 return add_nisp21pwd_entry(pdb_smb_to_sam(newpwd));
240 #endif /* USE_NISPLUS_DB */
243 return add_ldap21pwd_entry(pdb_smb_to_sam(newpwd));
244 #endif /* USE_LDAP_DB */
246 #ifdef USE_SMBPASS_DB
247 return add_smbfilepwd_entry(newpwd);
248 #endif /* USE_SMBPASS_DB */
251 /************************************************************************
252 Routine to search the smb passwd file for an entry matching the username.
253 and then modify its password entry. We can't use the startsampwent()/
254 getsampwent()/endsampwent() interfaces here as we depend on looking
255 in the actual file to decide how much room we have to write data.
256 override = False, normal
257 override = True, override XXXXXXXX'd out password or NO PASS
258 ************************************************************************/
260 BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
262 #ifdef USE_NISPLUS_DB
263 return mod_nisp21pwd_entry(pdb_smb_to_sam(pwd), override);
264 #endif /* USE_NISPLUS_DB */
267 return mod_ldap21pwd_entry(pdb_smb_to_sam(pwd), override);
268 #endif /* USE_LDAP_DB */
270 #ifdef USE_SMBPASS_DB
271 return mod_smbfilepwd_entry(pwd, override);
272 #endif /* USE_SMBPASS_DB */
275 /************************************************************************
276 Routine to search smb passwd by name.
277 *************************************************************************/
279 struct smb_passwd *getsmbpwnam(char *name)
281 #ifdef USE_NISPLUS_DB
282 return pdb_sam_to_smb(_getsam21pwnam(name));
283 #endif /* USE_NISPLUS_DB */
286 return pdb_sam_to_smb(_getsam21pwnam(name));
287 #endif /* USE_LDAP_DB */
289 #ifdef USE_SMBPASS_DB
290 return _getsmbpwnam(name);
291 #endif /* USE_SMBPASS_DB */
294 /************************************************************************
295 Routine to search smb passwd by uid.
296 *************************************************************************/
298 struct smb_passwd *getsmbpwuid(uid_t smb_userid)
300 #ifdef USE_NISPLUS_DB
301 return pdb_sam_to_smb(_getsam21pwrid(smb_userid));
302 #endif /* USE_NISPLUS_DB */
305 return pdb_sam_to_smb(_getsam21pwrid(smb_userid));
306 #endif /* USE_LDAP_DB */
308 #ifdef USE_SMBPASS_DB
309 return _getsmbpwuid(smb_userid);
310 #endif /* USE_SMBPASS_DB */
314 * Functions that manupulate a struct sam_passwd.
317 /*************************************************************************
318 Routine to return the next entry in the sam passwd list.
319 *************************************************************************/
321 struct sam_disp_info *getsamdispent(void *vp)
323 #ifdef USE_NISPLUS_DB
324 return pdb_sam_to_dispinfo(getnisp21pwent(vp));
325 #endif /* USE_NISPLUS_DB */
328 return pdb_sam_to_dispinfo(getldap21pwent(vp));
329 #endif /* USE_LDAP_DB */
331 #ifdef USE_SMBPASS_DB
332 return pdb_sam_to_dispinfo(getsmbfile21pwent(vp));
333 #endif /* USE_SMBPASS_DB */
338 /*************************************************************************
339 Routine to return the next entry in the sam passwd list.
340 *************************************************************************/
342 struct sam_passwd *getsam21pwent(void *vp)
344 #ifdef USE_NISPLUS_DB
345 return getnisp21pwent(vp);
346 #endif /* USE_NISPLUS_DB */
349 return getldap21pwent(vp);
350 #endif /* USE_LDAP_DB */
352 #ifdef USE_SMBPASS_DB
353 return getsmbfile21pwent(vp);
354 #endif /* USE_SMBPASS_DB */
359 /************************************************************************
360 Routine to add an entry to the sam passwd file.
361 *************************************************************************/
363 BOOL add_sam21pwd_entry(struct sam_passwd *newpwd)
365 #ifdef USE_NISPLUS_DB
366 return add_nisp21pwd_entry(newpwd);
367 #endif /* USE_NISPLUS_DB */
370 return add_ldap21pwd_entry(newpwd);
371 #endif /* USE_LDAP_DB */
373 #ifdef USE_SMBPASS_DB
374 return add_smbfile21pwd_entry(newpwd);
375 #endif /* USE_SMBPASS_DB */
378 /************************************************************************
379 Routine to search the sam passwd database for an entry matching the username.
380 and then modify its password entry. We can't use the startsampwent()/
381 getsampwent()/endsampwent() interfaces here as we depend on looking
382 in the actual file to decide how much room we have to write data.
383 override = False, normal
384 override = True, override XXXXXXXX'd out password or NO PASS
385 ************************************************************************/
387 BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override)
389 #ifdef USE_NISPLUS_DB
390 return mod_nisp21pwd_entry(pwd, override);
391 #endif /* USE_NISPLUS_DB */
394 return mod_ldap21pwd_entry(pwd, override);
395 #endif /* USE_LDAP_DB */
397 #ifdef USE_SMBPASS_DB
398 return mod_smbfile21pwd_entry(pwd, override);
399 #endif /* USE_SMBPASS_DB */
402 /************************************************************************
403 Routine to search sam passwd by name. use this if your database
404 does not have search facilities.
405 *************************************************************************/
407 static struct sam_passwd *_getsam21pwnam(char *name)
409 struct sam_passwd *pwd = NULL;
412 DEBUG(10, ("_getsam21pwnam: search by name: %s\n", name));
414 /* Open the smb password database - not for update. */
415 fp = startsmbpwent(False);
419 DEBUG(0, ("_getsam21pwnam: unable to open sam password database.\n"));
423 while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name));
427 DEBUG(10, ("_getsam21pwnam: found by name: %s\n", name));
435 /************************************************************************
436 Routine to search sam passwd by name.
437 *************************************************************************/
439 struct sam_passwd *getsam21pwnam(char *name)
441 #ifdef USE_NISPLUS_DB
442 return _getsam21pwnam(name);
443 #endif /* USE_NISPLUS_DB */
446 return _getsam21pwnam(name);
447 #endif /* USE_LDAP_DB */
449 #ifdef USE_SMBPASS_DB
450 return _getsam21pwnam(name);
451 #endif /* USE_SMBPASS_DB */
454 /************************************************************************
455 Routine to search sam passwd by uid. use this if your database
456 does not have search facilities.
457 *************************************************************************/
459 static struct sam_passwd *_getsam21pwuid(uint32 uid)
461 struct sam_passwd *pwd = NULL;
464 DEBUG(10, ("_getsam21pwuid: search by uid: %x\n", uid));
466 /* Open the smb password file - not for update. */
467 fp = startsmbpwent(False);
471 DEBUG(0, ("_getsam21pwuid: unable to open sam password database.\n"));
475 while ((pwd = getsam21pwent(fp)) != NULL && pwd->smb_userid != uid)
480 DEBUG(10, ("_getsam21pwuid: found by smb_userid: %x\n", uid));
487 /************************************************************************
488 Routine to search sam passwd by uid.
489 *************************************************************************/
491 struct sam_passwd *getsam21pwuid(uint32 uid)
493 #ifdef USE_NISPLUS_DB
494 return _getsam21pwuid(uid);
495 #endif /* USE_NISPLUS_DB */
498 return _getsam21pwuid(uid);
499 #endif /* USE_LDAP_DB */
501 #ifdef USE_SMBPASS_DB
502 return _getsam21pwuid(uid);
503 #endif /* USE_SMBPASS_DB */
507 /**********************************************************
508 **********************************************************
510 utility routines which are likely to be useful to all password
513 **********************************************************
514 **********************************************************/
516 /*************************************************************
517 initialises a struct sam_disp_info.
518 **************************************************************/
520 void pdb_init_dispinfo(struct sam_disp_info *user)
522 if (user == NULL) return;
523 bzero(user, sizeof(*user));
526 /*************************************************************
527 initialises a struct smb_passwd.
528 **************************************************************/
530 void pdb_init_smb(struct smb_passwd *user)
532 if (user == NULL) return;
533 bzero(user, sizeof(*user));
534 user->pass_last_set_time = (time_t)-1;
537 /*************************************************************
538 initialises a struct sam_passwd.
539 **************************************************************/
540 void pdb_init_sam(struct sam_passwd *user)
542 if (user == NULL) return;
543 bzero(user, sizeof(*user));
544 user->logon_time = (time_t)-1;
545 user->logoff_time = (time_t)-1;
546 user->kickoff_time = (time_t)-1;
547 user->pass_last_set_time = (time_t)-1;
548 user->pass_can_change_time = (time_t)-1;
549 user->pass_must_change_time = (time_t)-1;
552 /*************************************************************************
553 Routine to return the next entry in the sam passwd list.
554 *************************************************************************/
555 struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user)
557 static struct sam_disp_info disp_info;
559 if (user == NULL) return NULL;
561 pdb_init_dispinfo(&disp_info);
563 disp_info.smb_name = user->smb_name;
564 disp_info.full_name = user->full_name;
565 disp_info.user_rid = user->user_rid;
570 /*************************************************************
571 converts a sam_passwd structure to a smb_passwd structure.
572 **************************************************************/
574 struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user)
576 static struct smb_passwd pw_buf;
578 if (user == NULL) return NULL;
580 pdb_init_smb(&pw_buf);
582 pw_buf.smb_userid = user->smb_userid;
583 pw_buf.smb_name = user->smb_name;
584 pw_buf.smb_passwd = user->smb_passwd;
585 pw_buf.smb_nt_passwd = user->smb_nt_passwd;
586 pw_buf.acct_ctrl = user->acct_ctrl;
587 pw_buf.pass_last_set_time = user->pass_last_set_time;
592 /*************************************************************
593 converts a smb_passwd structure to a sam_passwd structure.
594 **************************************************************/
596 struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user)
598 static struct sam_passwd pw_buf;
600 if (user == NULL) return NULL;
602 pdb_init_sam(&pw_buf);
604 pw_buf.smb_userid = user->smb_userid;
605 pw_buf.smb_name = user->smb_name;
606 pw_buf.smb_passwd = user->smb_passwd;
607 pw_buf.smb_nt_passwd = user->smb_nt_passwd;
608 pw_buf.acct_ctrl = user->acct_ctrl;
609 pw_buf.pass_last_set_time = user->pass_last_set_time;
616 COMMENTED OUT UNTIL SOMETHING ACTUALLY USES THEM. JRA.
618 /*******************************************************************
619 gets password-database-format time from a string.
620 ********************************************************************/
622 static time_t get_time_from_string(char *p)
626 for (i = 0; i < 8; i++)
628 if (p[i] == '\0' || !isxdigit(p[i]))
634 * p points at 8 characters of hex digits -
635 * read into a time_t as the seconds since
636 * 1970 that the password was last changed.
638 return (time_t)strtol((char *)p, NULL, 16);
643 /*******************************************************************
644 gets password last set time
645 ********************************************************************/
647 time_t pdb_get_last_set_time(char *p)
649 if (*p && StrnCaseCmp((char *)p, "LCT-", 4))
651 return get_time_from_string(p + 4);
657 /*******************************************************************
658 sets password-database-format time in a string.
659 ********************************************************************/
661 static void set_time_in_string(char *p, int max_len, char *type, time_t t)
663 slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
666 /*******************************************************************
667 sets password last set time
668 ********************************************************************/
670 void pdb_set_last_set_time(char *p, int max_len, time_t t)
672 set_time_in_string(p, max_len, "LCT", t);
677 /**********************************************************
678 Encode the account control bits into a string.
679 **********************************************************/
681 char *pdb_encode_acct_ctrl(uint16 acct_ctrl)
683 static fstring acct_str;
688 if (acct_ctrl & ACB_HOMDIRREQ) *p++ = 'H';
689 if (acct_ctrl & ACB_TEMPDUP ) *p++ = 'T';
690 if (acct_ctrl & ACB_NORMAL ) *p++ = 'U';
691 if (acct_ctrl & ACB_MNS ) *p++ = 'M';
692 if (acct_ctrl & ACB_WSTRUST ) *p++ = 'W';
693 if (acct_ctrl & ACB_SVRTRUST ) *p++ = 'S';
694 if (acct_ctrl & ACB_AUTOLOCK ) *p++ = 'L';
695 if (acct_ctrl & ACB_PWNOEXP ) *p++ = 'X';
696 if (acct_ctrl & ACB_DOMTRUST ) *p++ = 'I';
703 /**********************************************************
704 Decode the account control bits from a string.
706 this function breaks coding standards minimum line width of 80 chars.
707 reason: vertical line-up code clarity - all case statements fit into
708 15 lines, which is more important.
709 **********************************************************/
711 uint16 pdb_decode_acct_ctrl(char *p)
713 uint16 acct_ctrl = 0;
714 BOOL finished = False;
717 * Check if the account type bits have been encoded after the
718 * NT password (in the form [NDHTUWSLXI]).
721 if (*p != '[') return 0;
723 for (p++; *p && !finished; p++)
729 * Hmmm. Don't allow these to be set/read independently
730 * of the actual password fields. We don't want a mismatch.
733 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
734 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
736 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
737 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
738 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
739 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
740 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
741 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
742 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
743 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
744 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
750 default: { finished = True; }
757 /*************************************************************
758 Routine to get the next 32 hex characters and turn them
759 into a 16 byte array.
760 **************************************************************/
762 int pdb_gethexpwd(char *p, char *pwd)
765 unsigned char lonybble, hinybble;
766 char *hexchars = "0123456789ABCDEF";
769 for (i = 0; i < 32; i += 2) {
770 hinybble = toupper(p[i]);
771 lonybble = toupper(p[i + 1]);
773 p1 = strchr(hexchars, hinybble);
774 p2 = strchr(hexchars, lonybble);
777 hinybble = PTR_DIFF(p1, hexchars);
778 lonybble = PTR_DIFF(p2, hexchars);
780 pwd[i / 2] = (hinybble << 4) | lonybble;
785 /*******************************************************************
786 Group and User RID username mapping function
787 ********************************************************************/
789 BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
791 struct passwd *pw = Get_Pwnam(user_name, False);
793 if (u_rid == NULL || g_rid == NULL || user_name == NULL)
800 DEBUG(1,("Username %s is invalid on this system\n", user_name));
804 if (user_in_list(user_name, lp_domain_guest_users()))
806 *u_rid = DOMAIN_USER_RID_GUEST;
808 else if (user_in_list(user_name, lp_domain_admin_users()))
810 *u_rid = DOMAIN_USER_RID_ADMIN;
814 /* turn the unix UID into a Domain RID. this is what the posix
815 sub-system does (adds 1000 to the uid) */
816 *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
819 /* absolutely no idea what to do about the unix GID to Domain RID mapping */
820 *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
825 /****************************************************************************
826 Read the machine SID from a file.
827 ****************************************************************************/
829 static BOOL read_sid_from_file(int fd, char *sid_file)
833 if(read(fd, &fline, sizeof(fline) -1 ) < 0) {
834 DEBUG(0,("read_sid_from_file: unable to read file %s. Error was %s\n",
835 sid_file, strerror(errno) ));
840 * Convert to the machine SID.
843 fline[sizeof(fline)-1] = '\0';
844 if(!string_to_sid( &global_machine_sid, fline)) {
845 DEBUG(0,("read_sid_from_file: unable to generate machine SID.\n"));
852 /****************************************************************************
853 Generate the global machine sid. Look for the MACHINE.SID file first, if
854 not found then look in smb.conf and use it to create the MACHINE.SID file.
855 ****************************************************************************/
857 BOOL pdb_generate_machine_sid(void)
864 uchar raw_sid_data[12];
866 pstrcpy(sid_file, lp_smb_passwd_file());
867 p = strrchr(sid_file, '/');
871 pstrcat(sid_file, "MACHINE.SID");
873 if((fd = open( sid_file, O_RDWR | O_CREAT, 0644)) < 0 ) {
874 DEBUG(0,("generate_machine_sid: unable to open or create file %s. Error was %s\n",
875 sid_file, strerror(errno) ));
880 * Check if the file contains data.
883 if(fstat( fd, &st) < 0) {
884 DEBUG(0,("generate_machine_sid: unable to stat file %s. Error was %s\n",
885 sid_file, strerror(errno) ));
892 * We have a valid SID - read it.
894 if(!read_sid_from_file( fd, sid_file)) {
895 DEBUG(0,("generate_machine_sid: unable to read file %s. Error was %s\n",
896 sid_file, strerror(errno) ));
905 * The file contains no data - we may need to generate our
906 * own sid. Try the lp_domain_sid() first.
910 fstrcpy( sid_string, lp_domain_sid());
913 * Generate the new sid data & turn it into a string.
916 generate_random_buffer( raw_sid_data, 12, True);
918 fstrcpy( sid_string, "S-1-5-21");
919 for( i = 0; i < 3; i++) {
921 slprintf( tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
922 fstrcat( sid_string, tmp_string);
926 fstrcat(sid_string, "\n");
929 * Ensure our new SID is valid.
932 if(!string_to_sid( &global_machine_sid, sid_string)) {
933 DEBUG(0,("generate_machine_sid: unable to generate machine SID.\n"));
938 * Do an exclusive blocking lock on the file.
941 if(!do_file_lock( fd, 60, F_WRLCK)) {
942 DEBUG(0,("generate_machine_sid: unable to lock file %s. Error was %s\n",
943 sid_file, strerror(errno) ));
949 * At this point we have a blocking lock on the SID
950 * file - check if in the meantime someone else wrote
951 * SID data into the file. If so - they were here first,
955 if(fstat( fd, &st) < 0) {
956 DEBUG(0,("generate_machine_sid: unable to stat file %s. Error was %s\n",
957 sid_file, strerror(errno) ));
964 * Unlock as soon as possible to reduce
965 * contention on the exclusive lock.
967 do_file_lock( fd, 60, F_UNLCK);
970 * We have a valid SID - read it.
973 if(!read_sid_from_file( fd, sid_file)) {
974 DEBUG(0,("generate_machine_sid: unable to read file %s. Error was %s\n",
975 sid_file, strerror(errno) ));
984 * The file is still empty and we have an exlusive lock on it.
985 * Write out out SID data into the file.
988 if(fchmod(fd, 0644) < 0) {
989 DEBUG(0,("generate_machine_sid: unable to set correct permissions on file %s. \
990 Error was %s\n", sid_file, strerror(errno) ));
995 if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
996 DEBUG(0,("generate_machine_sid: unable to write file %s. Error was %s\n",
997 sid_file, strerror(errno) ));
1006 do_file_lock( fd, 60, F_UNLCK);
1011 /*******************************************************************
1012 converts NT User RID to a UNIX uid.
1013 ********************************************************************/
1015 uint32 pdb_user_rid_to_uid(uint32 u_rid)
1017 return (u_rid - 1000);
1020 /*******************************************************************
1021 converts NT Group RID to a UNIX uid.
1022 ********************************************************************/
1024 uint32 pdb_group_rid_to_gid(uint32 u_gid)
1026 return (u_gid - 1000);
1029 /*******************************************************************
1030 converts UNIX uid to an NT User RID.
1031 ********************************************************************/
1033 uint32 pdb_uid_to_user_rid(uint32 uid)
1035 return (uint32)(uid + 1000);
1038 /*******************************************************************
1039 converts NT Group RID to a UNIX uid.
1040 ********************************************************************/
1042 uint32 pdb_gid_to_group_rid(uint32 gid)
1044 return (uint32)(gid + 1000);
1047 /*******************************************************************
1048 Decides if a RID is a user or group RID.
1049 ********************************************************************/
1051 BOOL pdb_rid_is_user(uint32 rid)
1053 /* Punt for now - we need to look at the encoding here. JRA. */