sync with SAMBA_2_2
[Samba/gbeck.git] / source / passdb / machine_sid.c
blobf714106b43138935704045fdc8a0f036cb9ef23f
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
24 #include "includes.h"
26 /****************************************************************************
27 Read the machine SID from a file.
28 ****************************************************************************/
30 static BOOL read_sid_from_file(int fd, char *sid_file)
32 fstring fline;
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) ));
39 return False;
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"));
49 return False;
52 return True;
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)
63 int fd;
64 char *p;
65 pstring sid_file;
66 fstring sid_string;
67 SMB_STRUCT_STAT st;
68 BOOL overwrite_bad_sid = False;
70 generate_wellknown_sids();
72 pstrcpy(sid_file, lp_smb_passwd_file());
73 p = strrchr(sid_file, '/');
74 if(p != NULL) {
75 *++p = '\0';
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)));
82 return False;
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) ));
91 return False;
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) ));
101 close(fd);
102 return False;
105 if(st.st_size > 0) {
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) ));
112 close(fd);
113 return False;
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) ));
135 close(fd);
136 return False;
138 } else {
139 close(fd);
140 return True;
142 } else {
144 * The file contains no data - we need to generate our
145 * own sid.
146 * Generate the new sid data & turn it into a string.
148 int i;
149 uchar raw_sid_data[12];
150 DOM_SID mysid;
152 memset((char *)&mysid, '\0', sizeof(DOM_SID));
153 mysid.sid_rev_num = 1;
154 mysid.id_auth[5] = 5;
155 mysid.num_auths = 0;
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"));
173 return False;
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) ));
183 close(fd);
184 return False;
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,
192 * use their data.
195 if(sys_fstat( fd, &st) < 0) {
196 DEBUG(0,("unable to stat file %s. Error was %s\n",
197 sid_file, strerror(errno) ));
198 close(fd);
199 return False;
202 if(st.st_size > 0) {
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) ));
216 close(fd);
217 return False;
219 close(fd);
220 return True;
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
232 * have fchmod. JRA.
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);
239 close(fd);
240 return False;
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);
247 close(fd);
248 return False;
252 * Unlock & exit.
255 do_file_lock( fd, 60, F_UNLCK);
256 close(fd);
257 return True;