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
7 Copyright (C) Gerald (Jerry) Carter 2000
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /****************************************************************************
27 Read the machine SID from a file.
28 ****************************************************************************/
30 static BOOL read_sid_from_file(int fd, char *sid_file)
34 memset(fline, '\0', sizeof(fline));
36 if(read(fd, fline, sizeof(fline) -1 ) < 0) {
37 DEBUG(0,("unable to read file %s. Error was %s\n",
38 sid_file, strerror(errno) ));
43 * Convert to the machine SID.
46 fline[sizeof(fline)-1] = '\0';
47 if(!string_to_sid( &global_sam_sid, fline)) {
48 DEBUG(0,("unable to generate machine SID.\n"));
55 /****************************************************************************
56 Generate the global machine sid. Look for the MACHINE.SID file first, if
57 not found then look in smb.conf and use it to create the MACHINE.SID file.
58 Note this function will be replaced soon. JRA.
59 ****************************************************************************/
61 BOOL pdb_generate_sam_sid(void)
67 BOOL overwrite_bad_sid = False;
69 generate_wellknown_sids();
71 pstrcpy(sid_file, lp_private_dir());
73 if (!directory_exist(sid_file, NULL)) {
74 if (mkdir(sid_file, 0700) != 0) {
75 DEBUG(0,("can't create private directory %s : %s\n",
76 sid_file, strerror(errno)));
81 pstrcat(sid_file, "/MACHINE.SID");
83 if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
84 DEBUG(0,("unable to open or create file %s. Error was %s\n",
85 sid_file, strerror(errno) ));
90 * Check if the file contains data.
93 if(sys_fstat( fd, &st) < 0) {
94 DEBUG(0,("unable to stat file %s. Error was %s\n",
95 sid_file, strerror(errno) ));
102 * We have a valid SID - read it.
104 if(!read_sid_from_file( fd, sid_file)) {
105 DEBUG(0,("unable to read file %s. Error was %s\n",
106 sid_file, strerror(errno) ));
112 * JRA. Reversed the sense of this test now that I have
113 * actually done this test *personally*. One more reason
114 * to never trust third party information you have not
115 * independently verified.... sigh. JRA.
118 if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) {
120 * Fix and re-write...
122 overwrite_bad_sid = True;
123 global_sam_sid.sub_auths[0] = 21;
124 DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \
125 detected - re-writing to be decimal 21 instead.\n" ));
126 sid_to_string(sid_string, &global_sam_sid);
127 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) {
128 DEBUG(0,("unable to seek file file %s. Error was %s\n",
129 sid_file, strerror(errno) ));
139 * The file contains no data - we need to generate our
141 * Generate the new sid data & turn it into a string.
144 uchar raw_sid_data[12];
147 memset((char *)&mysid, '\0', sizeof(DOM_SID));
148 mysid.sid_rev_num = 1;
149 mysid.id_auth[5] = 5;
151 mysid.sub_auths[mysid.num_auths++] = 21;
153 generate_random_buffer( raw_sid_data, 12, True);
154 for( i = 0; i < 3; i++)
155 mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4);
157 sid_to_string(sid_string, &mysid);
160 fstrcat(sid_string, "\n");
163 * Ensure our new SID is valid.
166 if(!string_to_sid( &global_sam_sid, sid_string)) {
167 DEBUG(0,("unable to generate machine SID.\n"));
172 * Do an exclusive blocking lock on the file.
175 if(!do_file_lock( fd, 60, F_WRLCK)) {
176 DEBUG(0,("unable to lock file %s. Error was %s\n",
177 sid_file, strerror(errno) ));
182 if(!overwrite_bad_sid) {
184 * At this point we have a blocking lock on the SID
185 * file - check if in the meantime someone else wrote
186 * SID data into the file. If so - they were here first,
190 if(sys_fstat( fd, &st) < 0) {
191 DEBUG(0,("unable to stat file %s. Error was %s\n",
192 sid_file, strerror(errno) ));
199 * Unlock as soon as possible to reduce
200 * contention on the exclusive lock.
202 do_file_lock( fd, 60, F_UNLCK);
205 * We have a valid SID - read it.
208 if(!read_sid_from_file( fd, sid_file)) {
209 DEBUG(0,("unable to read file %s. Error was %s\n",
210 sid_file, strerror(errno) ));
220 * The file is still empty and we have an exlusive lock on it,
221 * or we're fixing an earlier mistake.
222 * Write out out SID data into the file.
226 * Use chmod here as some (strange) UNIX's don't
230 if(chmod(sid_file, 0644) < 0) {
231 DEBUG(0,("unable to set correct permissions on file %s. \
232 Error was %s\n", sid_file, strerror(errno) ));
233 do_file_lock( fd, 60, F_UNLCK);
238 if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
239 DEBUG(0,("unable to write file %s. Error was %s\n",
240 sid_file, strerror(errno) ));
241 do_file_lock( fd, 60, F_UNLCK);
250 do_file_lock( fd, 60, F_UNLCK);