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)
68 BOOL overwrite_bad_sid = False;
70 generate_wellknown_sids();
72 pstrcpy(sid_file, lp_smb_passwd_file());
73 p = strrchr_m(sid_file, '/');
78 if (!directory_exist(sid_file, NULL)) {
79 if (mkdir(sid_file, 0700) != 0) {
80 DEBUG(0,("can't create private directory %s : %s\n",
81 sid_file, strerror(errno)));
86 pstrcat(sid_file, "MACHINE.SID");
88 if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
89 DEBUG(0,("unable to open or create file %s. Error was %s\n",
90 sid_file, strerror(errno) ));
95 * Check if the file contains data.
98 if(sys_fstat( fd, &st) < 0) {
99 DEBUG(0,("unable to stat file %s. Error was %s\n",
100 sid_file, strerror(errno) ));
107 * We have a valid SID - read it.
109 if(!read_sid_from_file( fd, sid_file)) {
110 DEBUG(0,("unable to read file %s. Error was %s\n",
111 sid_file, strerror(errno) ));
117 * JRA. Reversed the sense of this test now that I have
118 * actually done this test *personally*. One more reason
119 * to never trust third party information you have not
120 * independently verified.... sigh. JRA.
123 if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) {
125 * Fix and re-write...
127 overwrite_bad_sid = True;
128 global_sam_sid.sub_auths[0] = 21;
129 DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \
130 detected - re-writing to be decimal 21 instead.\n" ));
131 sid_to_string(sid_string, &global_sam_sid);
132 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) {
133 DEBUG(0,("unable to seek file file %s. Error was %s\n",
134 sid_file, strerror(errno) ));
144 * The file contains no data - we need to generate our
146 * Generate the new sid data & turn it into a string.
149 uchar raw_sid_data[12];
152 memset((char *)&mysid, '\0', sizeof(DOM_SID));
153 mysid.sid_rev_num = 1;
154 mysid.id_auth[5] = 5;
156 mysid.sub_auths[mysid.num_auths++] = 21;
158 generate_random_buffer( raw_sid_data, 12, True);
159 for( i = 0; i < 3; i++)
160 mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4);
162 sid_to_string(sid_string, &mysid);
165 fstrcat(sid_string, "\n");
168 * Ensure our new SID is valid.
171 if(!string_to_sid( &global_sam_sid, sid_string)) {
172 DEBUG(0,("unable to generate machine SID.\n"));
177 * Do an exclusive blocking lock on the file.
180 if(!do_file_lock( fd, 60, F_WRLCK)) {
181 DEBUG(0,("unable to lock file %s. Error was %s\n",
182 sid_file, strerror(errno) ));
187 if(!overwrite_bad_sid) {
189 * At this point we have a blocking lock on the SID
190 * file - check if in the meantime someone else wrote
191 * SID data into the file. If so - they were here first,
195 if(sys_fstat( fd, &st) < 0) {
196 DEBUG(0,("unable to stat file %s. Error was %s\n",
197 sid_file, strerror(errno) ));
204 * Unlock as soon as possible to reduce
205 * contention on the exclusive lock.
207 do_file_lock( fd, 60, F_UNLCK);
210 * We have a valid SID - read it.
213 if(!read_sid_from_file( fd, sid_file)) {
214 DEBUG(0,("unable to read file %s. Error was %s\n",
215 sid_file, strerror(errno) ));
225 * The file is still empty and we have an exlusive lock on it,
226 * or we're fixing an earlier mistake.
227 * Write out out SID data into the file.
231 * Use chmod here as some (strange) UNIX's don't
235 if(chmod(sid_file, 0644) < 0) {
236 DEBUG(0,("unable to set correct permissions on file %s. \
237 Error was %s\n", sid_file, strerror(errno) ));
238 do_file_lock( fd, 60, F_UNLCK);
243 if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
244 DEBUG(0,("unable to write file %s. Error was %s\n",
245 sid_file, strerror(errno) ));
246 do_file_lock( fd, 60, F_UNLCK);
255 do_file_lock( fd, 60, F_UNLCK);