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 rid. 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;
596 /*******************************************************************
597 gets password-database-format time from a string.
598 ********************************************************************/
600 static time_t get_time_from_string(char *p)
604 for (i = 0; i < 8; i++)
606 if (p[i] == '\0' || !isxdigit(p[i]))
612 * p points at 8 characters of hex digits -
613 * read into a time_t as the seconds since
614 * 1970 that the password was last changed.
616 return (time_t)strtol((char *)p, NULL, 16);
621 /*******************************************************************
622 gets password last set time
623 ********************************************************************/
625 time_t pdb_get_last_set_time(char *p)
627 if (*p && StrnCaseCmp((char *)p, "LCT-", 4))
629 return get_time_from_string(p + 4);
635 /*******************************************************************
636 sets password-database-format time in a string.
637 ********************************************************************/
638 static void set_time_in_string(char *p, int max_len, char *type, time_t t)
640 slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
643 /*******************************************************************
645 ********************************************************************/
646 void pdb_set_logon_time(char *p, int max_len, time_t t)
648 set_time_in_string(p, max_len, "LNT", t);
651 /*******************************************************************
653 ********************************************************************/
654 void pdb_set_logoff_time(char *p, int max_len, time_t t)
656 set_time_in_string(p, max_len, "LOT", t);
659 /*******************************************************************
661 ********************************************************************/
662 void pdb_set_kickoff_time(char *p, int max_len, time_t t)
664 set_time_in_string(p, max_len, "KOT", t);
667 /*******************************************************************
668 sets password can change time
669 ********************************************************************/
670 void pdb_set_can_change_time(char *p, int max_len, time_t t)
672 set_time_in_string(p, max_len, "CCT", t);
675 /*******************************************************************
676 sets password last set time
677 ********************************************************************/
678 void pdb_set_must_change_time(char *p, int max_len, time_t t)
680 set_time_in_string(p, max_len, "MCT", t);
683 /*******************************************************************
684 sets password last set time
685 ********************************************************************/
686 void pdb_set_last_set_time(char *p, int max_len, time_t t)
688 set_time_in_string(p, max_len, "LCT", t);
691 /**********************************************************
692 Encode the account control bits into a string.
693 **********************************************************/
695 char *pdb_encode_acct_ctrl(uint16 acct_ctrl)
697 static fstring acct_str;
702 if (acct_ctrl & ACB_HOMDIRREQ) *p++ = 'H';
703 if (acct_ctrl & ACB_TEMPDUP ) *p++ = 'T';
704 if (acct_ctrl & ACB_NORMAL ) *p++ = 'U';
705 if (acct_ctrl & ACB_MNS ) *p++ = 'M';
706 if (acct_ctrl & ACB_WSTRUST ) *p++ = 'W';
707 if (acct_ctrl & ACB_SVRTRUST ) *p++ = 'S';
708 if (acct_ctrl & ACB_AUTOLOCK ) *p++ = 'L';
709 if (acct_ctrl & ACB_PWNOEXP ) *p++ = 'X';
710 if (acct_ctrl & ACB_DOMTRUST ) *p++ = 'I';
717 /**********************************************************
718 Decode the account control bits from a string.
720 this function breaks coding standards minimum line width of 80 chars.
721 reason: vertical line-up code clarity - all case statements fit into
722 15 lines, which is more important.
723 **********************************************************/
725 uint16 pdb_decode_acct_ctrl(char *p)
727 uint16 acct_ctrl = 0;
728 BOOL finished = False;
731 * Check if the account type bits have been encoded after the
732 * NT password (in the form [NDHTUWSLXI]).
735 if (*p != '[') return 0;
737 for (p++; *p && !finished; p++)
743 * Hmmm. Don't allow these to be set/read independently
744 * of the actual password fields. We don't want a mismatch.
747 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
748 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
750 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
751 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
752 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
753 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
754 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
755 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
756 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
757 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
758 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
764 default: { finished = True; }
771 /*************************************************************
772 Routine to get the 32 hex characters and turn them
773 into a 16 byte array.
774 **************************************************************/
775 BOOL pdb_gethexpwd(char *p, char *pwd)
778 unsigned char lonybble, hinybble;
779 char *hexchars = "0123456789ABCDEF";
782 for (i = 0; i < 32; i += 2)
784 hinybble = toupper(p[i]);
785 lonybble = toupper(p[i + 1]);
787 p1 = strchr(hexchars, hinybble);
788 p2 = strchr(hexchars, lonybble);
795 hinybble = PTR_DIFF(p1, hexchars);
796 lonybble = PTR_DIFF(p2, hexchars);
798 pwd[i / 2] = (hinybble << 4) | lonybble;
803 /*************************************************************
804 Routine to set 32 hex password characters from a 16 byte array.
805 **************************************************************/
806 void pdb_sethexpwd(char *p, char *pwd, uint16 acct_ctrl)
811 for (i = 0; i < 16; i++)
813 slprintf(&p[i*2], 33, "%02X", pwd[i]);
818 if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
820 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
824 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
829 /*******************************************************************
830 Group and User RID username mapping function
831 ********************************************************************/
833 BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
835 struct passwd *pw = Get_Pwnam(user_name, False);
837 if (u_rid == NULL || g_rid == NULL || user_name == NULL)
844 DEBUG(1,("Username %s is invalid on this system\n", user_name));
848 if (user_in_list(user_name, lp_domain_guest_users()))
850 *u_rid = DOMAIN_USER_RID_GUEST;
852 else if (user_in_list(user_name, lp_domain_admin_users()))
854 *u_rid = DOMAIN_USER_RID_ADMIN;
858 /* turn the unix UID into a Domain RID. this is what the posix
859 sub-system does (adds 1000 to the uid) */
860 *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
863 /* absolutely no idea what to do about the unix GID to Domain RID mapping */
864 *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
869 /****************************************************************************
870 Read the machine SID from a file.
871 ****************************************************************************/
873 static BOOL read_sid_from_file(int fd, char *sid_file)
877 if(read(fd, fline, sizeof(fline) -1 ) < 0) {
878 DEBUG(0,("read_sid_from_file: unable to read file %s. Error was %s\n",
879 sid_file, strerror(errno) ));
884 * Convert to the machine SID.
887 fline[sizeof(fline)-1] = '\0';
888 if(!string_to_sid( &global_machine_sid, fline)) {
889 DEBUG(0,("read_sid_from_file: unable to generate machine SID.\n"));
896 /****************************************************************************
897 Generate the global machine sid. Look for the MACHINE.SID file first, if
898 not found then look in smb.conf and use it to create the MACHINE.SID file.
899 ****************************************************************************/
901 BOOL pdb_generate_machine_sid(void)
908 uchar raw_sid_data[12];
910 pstrcpy(sid_file, lp_smb_passwd_file());
911 p = strrchr(sid_file, '/');
915 pstrcat(sid_file, "MACHINE.SID");
917 if((fd = open( sid_file, O_RDWR | O_CREAT, 0644)) < 0 ) {
918 DEBUG(0,("generate_machine_sid: unable to open or create file %s. Error was %s\n",
919 sid_file, strerror(errno) ));
924 * Check if the file contains data.
927 if(fstat( fd, &st) < 0) {
928 DEBUG(0,("generate_machine_sid: unable to stat file %s. Error was %s\n",
929 sid_file, strerror(errno) ));
936 * We have a valid SID - read it.
938 if(!read_sid_from_file( fd, sid_file)) {
939 DEBUG(0,("generate_machine_sid: unable to read file %s. Error was %s\n",
940 sid_file, strerror(errno) ));
949 * The file contains no data - we may need to generate our
950 * own sid. Try the lp_domain_sid() first.
954 fstrcpy( sid_string, lp_domain_sid());
957 * Generate the new sid data & turn it into a string.
960 generate_random_buffer( raw_sid_data, 12, True);
962 fstrcpy( sid_string, "S-1-5-21");
963 for( i = 0; i < 3; i++) {
965 slprintf( tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
966 fstrcat( sid_string, tmp_string);
970 fstrcat(sid_string, "\n");
973 * Ensure our new SID is valid.
976 if(!string_to_sid( &global_machine_sid, sid_string)) {
977 DEBUG(0,("generate_machine_sid: unable to generate machine SID.\n"));
982 * Do an exclusive blocking lock on the file.
985 if(!do_file_lock( fd, 60, F_WRLCK)) {
986 DEBUG(0,("generate_machine_sid: unable to lock file %s. Error was %s\n",
987 sid_file, strerror(errno) ));
993 * At this point we have a blocking lock on the SID
994 * file - check if in the meantime someone else wrote
995 * SID data into the file. If so - they were here first,
999 if(fstat( fd, &st) < 0) {
1000 DEBUG(0,("generate_machine_sid: unable to stat file %s. Error was %s\n",
1001 sid_file, strerror(errno) ));
1006 if(st.st_size > 0) {
1008 * Unlock as soon as possible to reduce
1009 * contention on the exclusive lock.
1011 do_file_lock( fd, 60, F_UNLCK);
1014 * We have a valid SID - read it.
1017 if(!read_sid_from_file( fd, sid_file)) {
1018 DEBUG(0,("generate_machine_sid: unable to read file %s. Error was %s\n",
1019 sid_file, strerror(errno) ));
1028 * The file is still empty and we have an exlusive lock on it.
1029 * Write out out SID data into the file.
1032 if(fchmod(fd, 0644) < 0) {
1033 DEBUG(0,("generate_machine_sid: unable to set correct permissions on file %s. \
1034 Error was %s\n", sid_file, strerror(errno) ));
1039 if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
1040 DEBUG(0,("generate_machine_sid: unable to write file %s. Error was %s\n",
1041 sid_file, strerror(errno) ));
1050 do_file_lock( fd, 60, F_UNLCK);
1055 /*******************************************************************
1056 converts NT User RID to a UNIX uid.
1057 ********************************************************************/
1059 uid_t pdb_user_rid_to_uid(uint32 u_rid)
1061 return (uid_t)(u_rid - 1000);
1064 /*******************************************************************
1065 converts NT Group RID to a UNIX uid.
1066 ********************************************************************/
1068 gid_t pdb_group_rid_to_gid(uint32 g_rid)
1070 return (gid_t)(g_rid - 1000);
1073 /*******************************************************************
1074 converts UNIX uid to an NT User RID.
1075 ********************************************************************/
1077 uint32 pdb_uid_to_user_rid(uid_t uid)
1079 return (uint32)(uid + 1000);
1082 /*******************************************************************
1083 converts NT Group RID to a UNIX uid.
1084 ********************************************************************/
1086 uint32 pdb_gid_to_group_rid(gid_t gid)
1088 return (uint32)(gid + 1000);
1091 /*******************************************************************
1092 Decides if a RID is a user or group RID.
1093 ********************************************************************/
1095 BOOL pdb_rid_is_user(uint32 rid)
1097 /* Punt for now - we need to look at the encoding here. JRA. */
1098 /* lkcl i understand that NT attaches an enumeration to a RID
1099 * such that it can be identified as either a user, group etc
1100 * type. there are 5 such categories, and they are documented.