From 02a601b98c2fa36f1e0b00d8bbf5f5ebb46e8363 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 01:44:21 +0000 Subject: rewrote the machine sid storage code to store the SID in secrets.tdb rather than MACHINE.SID. We try to load MACHINE.SID only if we can't fetch the SID from secrets.tdb This also fixes the value of global_sam_sid for the DC/non-DC case (This used to be commit bcd018f07c2e2c0aabdb4574d199d7f5f199a264) --- source3/passdb/machine_sid.c | 271 ++++++++++--------------------------------- 1 file changed, 63 insertions(+), 208 deletions(-) (limited to 'source3/passdb') diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index 593cc94f40..16a9903ec8 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -22,233 +22,88 @@ #include "includes.h" + /**************************************************************************** - Read the machine SID from a file. + Read a SID from a file. This is for compatibility with the old MACHINE.SID + style of SID storage ****************************************************************************/ - -static BOOL read_sid_from_file(int fd, char *sid_file) +static BOOL read_sid_from_file(const char *fname, DOM_SID *sid) { - fstring fline; - - memset(fline, '\0', sizeof(fline)); - - if(read(fd, fline, sizeof(fline) -1 ) < 0) { - DEBUG(0,("unable to read file %s. Error was %s\n", - sid_file, strerror(errno) )); - return False; - } - - /* - * Convert to the machine SID. - */ + char **lines; + int numlines; + BOOL ret; - fline[sizeof(fline)-1] = '\0'; - if(!string_to_sid( &global_sam_sid, fline)) { - DEBUG(0,("unable to generate machine SID.\n")); - return False; - } + lines = file_lines_load(fname, &numlines); + + if (!lines || numlines < 1) { + if (lines) file_lines_free(lines); + return False; + } + + ret = string_to_sid(sid, lines[0]); + file_lines_free(lines); + return ret; +} - return True; +/* + generate a random sid - used to build our own sid if we don't have one +*/ +static void generate_random_sid(DOM_SID *sid) +{ + int i; + uchar raw_sid_data[12]; + + memset((char *)sid, '\0', sizeof(*sid)); + sid->sid_rev_num = 1; + sid->id_auth[5] = 5; + sid->num_auths = 0; + sid->sub_auths[sid->num_auths++] = 21; + + generate_random_buffer(raw_sid_data, 12, True); + for (i = 0; i < 3; i++) + sid->sub_auths[sid->num_auths++] = IVAL(raw_sid_data, i*4); } /**************************************************************************** - Generate the global machine sid. Look for the MACHINE.SID file first, if - not found then look in smb.conf and use it to create the MACHINE.SID file. - Note this function will be replaced soon. JRA. + Generate the global machine sid. ****************************************************************************/ - BOOL pdb_generate_sam_sid(void) { - int fd; - pstring sid_file; - fstring sid_string; - SMB_STRUCT_STAT st; - BOOL overwrite_bad_sid = False; + char *fname = NULL; + char *domain_name; + extern pstring global_myname; + extern fstring global_myworkgroup; generate_wellknown_sids(); - pstrcpy(sid_file, lp_private_dir()); - - if (!directory_exist(sid_file, NULL)) { - if (mkdir(sid_file, 0700) != 0) { - DEBUG(0,("can't create private directory %s : %s\n", - sid_file, strerror(errno))); - return False; - } + /* the local SAMR sid is based on the workgroup only when we are a DC */ + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + domain_name = global_myworkgroup; + break; + default: + domain_name = global_myname; + break; } - pstrcat(sid_file, "/MACHINE.SID"); - - if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) { - DEBUG(0,("unable to open or create file %s. Error was %s\n", - sid_file, strerror(errno) )); - return False; - } - - /* - * Check if the file contains data. - */ - - if(sys_fstat( fd, &st) < 0) { - DEBUG(0,("unable to stat file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - - if(st.st_size > 0) { - /* - * We have a valid SID - read it. - */ - if(!read_sid_from_file( fd, sid_file)) { - DEBUG(0,("unable to read file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - - /* - * JRA. Reversed the sense of this test now that I have - * actually done this test *personally*. One more reason - * to never trust third party information you have not - * independently verified.... sigh. JRA. - */ + if (secrets_fetch_domain_sid(domain_name, &global_sam_sid)) { + return True; + } - if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) { - /* - * Fix and re-write... - */ - overwrite_bad_sid = True; - global_sam_sid.sub_auths[0] = 21; - DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \ -detected - re-writing to be decimal 21 instead.\n" )); - sid_to_string(sid_string, &global_sam_sid); - if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) { - DEBUG(0,("unable to seek file file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - } else { - close(fd); - return True; + /* check for an old MACHINE.SID file for backwards compatibility */ + asprintf(&fname, "%s/MACHINE.SID", lp_private_dir()); + if (read_sid_from_file(fname, &global_sam_sid)) { + /* remember it for future reference and unlink the old MACHINE.SID */ + if (secrets_store_domain_sid(domain_name, &global_sam_sid)) { + unlink(fname); } - } else { - /* - * The file contains no data - we need to generate our - * own sid. - * Generate the new sid data & turn it into a string. - */ - int i; - uchar raw_sid_data[12]; - DOM_SID mysid; - - memset((char *)&mysid, '\0', sizeof(DOM_SID)); - mysid.sid_rev_num = 1; - mysid.id_auth[5] = 5; - mysid.num_auths = 0; - mysid.sub_auths[mysid.num_auths++] = 21; - - generate_random_buffer( raw_sid_data, 12, True); - for( i = 0; i < 3; i++) - mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4); - - sid_to_string(sid_string, &mysid); - } - - fstrcat(sid_string, "\n"); - - /* - * Ensure our new SID is valid. - */ - - if(!string_to_sid( &global_sam_sid, sid_string)) { - DEBUG(0,("unable to generate machine SID.\n")); - return False; - } - - /* - * Do an exclusive blocking lock on the file. - */ - - if(!do_file_lock( fd, 60, F_WRLCK)) { - DEBUG(0,("unable to lock file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - - if(!overwrite_bad_sid) { - /* - * At this point we have a blocking lock on the SID - * file - check if in the meantime someone else wrote - * SID data into the file. If so - they were here first, - * use their data. - */ - - if(sys_fstat( fd, &st) < 0) { - DEBUG(0,("unable to stat file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - - if(st.st_size > 0) { - /* - * Unlock as soon as possible to reduce - * contention on the exclusive lock. - */ - do_file_lock( fd, 60, F_UNLCK); - - /* - * We have a valid SID - read it. - */ - - if(!read_sid_from_file( fd, sid_file)) { - DEBUG(0,("unable to read file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - close(fd); - return True; - } + return True; } - - /* - * The file is still empty and we have an exlusive lock on it, - * or we're fixing an earlier mistake. - * Write out out SID data into the file. - */ - /* - * Use chmod here as some (strange) UNIX's don't - * have fchmod. JRA. - */ + /* we don't have the SID in secrets.tdb, we will need to + generate one and save it */ + generate_random_sid(&global_sam_sid); - if(chmod(sid_file, 0644) < 0) { - DEBUG(0,("unable to set correct permissions on file %s. \ -Error was %s\n", sid_file, strerror(errno) )); - do_file_lock( fd, 60, F_UNLCK); - close(fd); - return False; - } - - if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) { - DEBUG(0,("unable to write file %s. Error was %s\n", - sid_file, strerror(errno) )); - do_file_lock( fd, 60, F_UNLCK); - close(fd); - return False; - } - - /* - * Unlock & exit. - */ - - do_file_lock( fd, 60, F_UNLCK); - close(fd); - return True; + return secrets_store_domain_sid(domain_name, &global_sam_sid); } - - -- cgit