2 Unix SMB/CIFS implementation.
3 Password and authentication handling
4 Copyright (C) Jeremy Allison 1996-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000
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.
25 /****************************************************************************
26 Read the machine SID from a file.
27 ****************************************************************************/
29 static BOOL read_sid_from_file(int fd, char *sid_file)
33 memset(fline, '\0', sizeof(fline));
35 if(read(fd, fline, sizeof(fline) -1 ) < 0) {
36 DEBUG(0,("unable to read file %s. Error was %s\n",
37 sid_file, strerror(errno) ));
42 * Convert to the machine SID.
45 fline[sizeof(fline)-1] = '\0';
46 if(!string_to_sid( &global_sam_sid, fline)) {
47 DEBUG(0,("unable to generate machine SID.\n"));
54 /****************************************************************************
55 Generate the global machine sid. Look for the MACHINE.SID file first, if
56 not found then look in smb.conf and use it to create the MACHINE.SID file.
57 Note this function will be replaced soon. JRA.
58 ****************************************************************************/
60 BOOL pdb_generate_sam_sid(void)
66 BOOL overwrite_bad_sid = False;
68 generate_wellknown_sids();
70 pstrcpy(sid_file, lp_private_dir());
72 if (!directory_exist(sid_file, NULL)) {
73 if (mkdir(sid_file, 0700) != 0) {
74 DEBUG(0,("can't create private directory %s : %s\n",
75 sid_file, strerror(errno)));
80 pstrcat(sid_file, "/MACHINE.SID");
82 if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
83 DEBUG(0,("unable to open or create file %s. Error was %s\n",
84 sid_file, strerror(errno) ));
89 * Check if the file contains data.
92 if(sys_fstat( fd, &st) < 0) {
93 DEBUG(0,("unable to stat file %s. Error was %s\n",
94 sid_file, strerror(errno) ));
101 * We have a valid SID - read it.
103 if(!read_sid_from_file( fd, sid_file)) {
104 DEBUG(0,("unable to read file %s. Error was %s\n",
105 sid_file, strerror(errno) ));
111 * JRA. Reversed the sense of this test now that I have
112 * actually done this test *personally*. One more reason
113 * to never trust third party information you have not
114 * independently verified.... sigh. JRA.
117 if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) {
119 * Fix and re-write...
121 overwrite_bad_sid = True;
122 global_sam_sid.sub_auths[0] = 21;
123 DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \
124 detected - re-writing to be decimal 21 instead.\n" ));
125 sid_to_string(sid_string, &global_sam_sid);
126 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) {
127 DEBUG(0,("unable to seek file file %s. Error was %s\n",
128 sid_file, strerror(errno) ));
138 * The file contains no data - we need to generate our
140 * Generate the new sid data & turn it into a string.
143 uchar raw_sid_data[12];
146 memset((char *)&mysid, '\0', sizeof(DOM_SID));
147 mysid.sid_rev_num = 1;
148 mysid.id_auth[5] = 5;
150 mysid.sub_auths[mysid.num_auths++] = 21;
152 generate_random_buffer( raw_sid_data, 12, True);
153 for( i = 0; i < 3; i++)
154 mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4);
156 sid_to_string(sid_string, &mysid);
159 fstrcat(sid_string, "\n");
162 * Ensure our new SID is valid.
165 if(!string_to_sid( &global_sam_sid, sid_string)) {
166 DEBUG(0,("unable to generate machine SID.\n"));
171 * Do an exclusive blocking lock on the file.
174 if(!do_file_lock( fd, 60, F_WRLCK)) {
175 DEBUG(0,("unable to lock file %s. Error was %s\n",
176 sid_file, strerror(errno) ));
181 if(!overwrite_bad_sid) {
183 * At this point we have a blocking lock on the SID
184 * file - check if in the meantime someone else wrote
185 * SID data into the file. If so - they were here first,
189 if(sys_fstat( fd, &st) < 0) {
190 DEBUG(0,("unable to stat file %s. Error was %s\n",
191 sid_file, strerror(errno) ));
198 * Unlock as soon as possible to reduce
199 * contention on the exclusive lock.
201 do_file_lock( fd, 60, F_UNLCK);
204 * We have a valid SID - read it.
207 if(!read_sid_from_file( fd, sid_file)) {
208 DEBUG(0,("unable to read file %s. Error was %s\n",
209 sid_file, strerror(errno) ));
219 * The file is still empty and we have an exlusive lock on it,
220 * or we're fixing an earlier mistake.
221 * Write out out SID data into the file.
225 * Use chmod here as some (strange) UNIX's don't
229 if(chmod(sid_file, 0644) < 0) {
230 DEBUG(0,("unable to set correct permissions on file %s. \
231 Error was %s\n", sid_file, strerror(errno) ));
232 do_file_lock( fd, 60, F_UNLCK);
237 if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
238 DEBUG(0,("unable to write file %s. Error was %s\n",
239 sid_file, strerror(errno) ));
240 do_file_lock( fd, 60, F_UNLCK);
249 do_file_lock( fd, 60, F_UNLCK);