From f8a4273407f2983bb05a76e914d4f532bbd5004e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 May 1998 21:10:49 +0000 Subject: passdb.c server.c: Moved generate_machine_sid() into passdb.c for Jean-Francois (who might want an LDAP version). Changed locking to free exclusive lock as soon as possible to prevent contention. lib/rpc/parse/parse_samr.c lib/rpc/server/srv_samr.c: Changed last SID-as-string manipulation function to use DOM_SID structure. Jeremy. (This used to be commit 3b8f5aef57b4f37265c0403385053085f0df6f18) --- source3/include/proto.h | 3 +- source3/passdb/passdb.c | 192 +++++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_samr.c | 4 +- source3/rpc_server/srv_samr.c | 19 ++-- source3/smbd/server.c | 183 +-------------------------------------- 5 files changed, 210 insertions(+), 191 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 70e10f1479..f448f4b9b3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -570,7 +570,7 @@ void samr_io_q_unknown_8(char *desc, SAMR_Q_UNKNOWN_8 *q_u, prs_struct *ps, int void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, POLICY_HND *user_pol, uint16 switch_value); void samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth); -void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, char *sidstr); +void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid); void sam_io_dom_sid3(char *desc, DOM_SID3 *sid3, prs_struct *ps, int depth); void make_sam_sid_stuff(SAM_SID_STUFF *stf, uint16 unknown_2, uint16 unknown_3, @@ -1585,6 +1585,7 @@ char *encode_acct_ctrl(uint16 acct_ctrl); uint16 decode_acct_ctrl(char *p); int gethexpwd(char *p, char *pwd); BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid); +BOOL generate_machine_sid(void); uid_t user_rid_to_uid(uint32 u_rid); uid_t group_rid_to_uid(uint32 u_gid); uint32 uid_to_user_rid(uint32 uid); diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 5fa354b637..4847149a00 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -25,6 +25,12 @@ extern int DEBUGLEVEL; +/* + * This is set on startup - it defines the SID for this + * machine. + */ +DOM_SID global_machine_sid; + /********************************************************** ********************************************************** @@ -474,6 +480,192 @@ BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid) return True; } +/**************************************************************************** + Read the machine SID from a file. +****************************************************************************/ + +static BOOL read_sid_from_file(int fd, char *sid_file) +{ + fstring fline; + + if(read(fd, &fline, sizeof(fline) -1 ) < 0) { + DEBUG(0,("read_sid_from_file: unable to read file %s. Error was %s\n", + sid_file, strerror(errno) )); + return False; + } + + /* + * Convert to the machine SID. + */ + + fline[sizeof(fline)-1] = '\0'; + if(!string_to_sid( &global_machine_sid, fline)) { + DEBUG(0,("read_sid_from_file: unable to generate machine SID.\n")); + return False; + } + + return True; +} + +/**************************************************************************** + 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. +****************************************************************************/ + +BOOL generate_machine_sid(void) +{ + int fd; + char *p; + pstring sid_file; + fstring sid_string; + struct stat st; + uchar raw_sid_data[12]; + + pstrcpy(sid_file, lp_smb_passwd_file()); + p = strrchr(sid_file, '/'); + if(p != NULL) + *++p = '\0'; + + pstrcat(sid_file, "MACHINE.SID"); + + if((fd = open( sid_file, O_RDWR | O_CREAT, 0644)) < 0 ) { + DEBUG(0,("generate_machine_sid: unable to open or create file %s. Error was %s\n", + sid_file, strerror(errno) )); + return False; + } + + /* + * Check if the file contains data. + */ + + if(fstat( fd, &st) < 0) { + DEBUG(0,("generate_machine_sid: 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,("generate_machine_sid: unable to read file %s. Error was %s\n", + sid_file, strerror(errno) )); + close(fd); + return False; + } + close(fd); + return True; + } + + /* + * The file contains no data - we may need to generate our + * own sid. Try the lp_domain_sid() first. + */ + + if(*lp_domain_sid()) + fstrcpy( sid_string, lp_domain_sid()); + else { + /* + * Generate the new sid data & turn it into a string. + */ + int i; + generate_random_buffer( raw_sid_data, 12, True); + + fstrcpy( sid_string, "S-1-5-21"); + for( i = 0; i < 3; i++) { + fstring tmp_string; + slprintf( tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4)); + fstrcat( sid_string, tmp_string); + } + } + + fstrcat(sid_string, "\n"); + + /* + * Ensure our new SID is valid. + */ + + if(!string_to_sid( &global_machine_sid, sid_string)) { + DEBUG(0,("generate_machine_sid: 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,("generate_machine_sid: unable to lock file %s. Error was %s\n", + sid_file, strerror(errno) )); + close(fd); + return False; + } + + /* + * 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(fstat( fd, &st) < 0) { + DEBUG(0,("generate_machine_sid: 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,("generate_machine_sid: unable to read file %s. Error was %s\n", + sid_file, strerror(errno) )); + close(fd); + return False; + } + close(fd); + return True; + } + + /* + * The file is still empty and we have an exlusive lock on it. + * Write out out SID data into the file. + */ + + if(fchmod(fd, 0644) < 0) { + DEBUG(0,("generate_machine_sid: unable to set correct permissions on file %s. \ +Error was %s\n", sid_file, strerror(errno) )); + close(fd); + return False; + } + + if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) { + DEBUG(0,("generate_machine_sid: unable to write file %s. Error was %s\n", + sid_file, strerror(errno) )); + close(fd); + return False; + } + + /* + * Unlock & exit. + */ + + do_file_lock( fd, 60, F_UNLCK); + close(fd); + return True; +} + /******************************************************************* XXXX THIS FUNCTION SHOULD NOT BE HERE: IT SHOULD BE A STATIC FUNCTION INSIDE smbpass.c diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 09c47ab25a..a85b6a692d 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -204,11 +204,11 @@ void samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int calculate length by adding up the size of the components. ********************************************************************/ -void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, char *sidstr) +void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid) { if (sid3 == NULL) return; - string_to_sid(&(sid3->sid), sidstr); + sid3->sid = *sid; sid3->len = 2 + 8 + sid3->sid.num_auths * 4; } diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 88217f73aa..821ae75c11 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -211,8 +211,6 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, { SAMR_R_UNKNOWN_3 r_u; DOM_SID3 sid[MAX_SAM_SIDS]; - fstring user_sid; - fstring user_rid; int pol_idx; uint32 rid; uint32 status; @@ -233,14 +231,21 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, if (status == 0x0) { - sid_to_string(user_sid, &global_machine_sid); - slprintf(user_rid, sizeof(user_rid) - 1, "-%x", rid); - fstrcat(user_sid, user_rid); + DOM_SID user_sid; + DOM_SID other_sid; + + user_sid = global_machine_sid; + /* + * Add the user RID. + */ + user_sid.sub_auths[user_sid.num_auths++] = rid; + + string_to_sid(&other_sid, "S-1-1"); /* maybe need another 1 or 2 (S-1-5-20-0x220 and S-1-5-20-0x224) */ /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */ - make_dom_sid3(&(sid[0]), 0x035b, 0x0002, "S-1-1"); - make_dom_sid3(&(sid[1]), 0x0044, 0x0002, user_sid); + make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &other_sid); + make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid); } make_samr_r_unknown_3(&r_u, diff --git a/source3/smbd/server.c b/source3/smbd/server.c index f277bea421..9821b305bc 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -62,8 +62,8 @@ extern int dcelogin_atmost_once; /* * This is set on startup - it defines the SID for this * machine. -*/ -DOM_SID global_machine_sid; + */ +extern DOM_SID global_machine_sid; connection_struct Connections[MAX_CONNECTIONS]; files_struct Files[MAX_OPEN_FILES]; @@ -141,185 +141,6 @@ void killkids(void) if(am_parent) kill(0,SIGTERM); } -/**************************************************************************** - Read the machine SID from a file. -****************************************************************************/ - -static BOOL read_sid_from_file(int fd, char *sid_file) -{ - fstring fline; - - if(read(fd, &fline, sizeof(fline) -1 ) < 0) { - DEBUG(0,("read_sid_from_file: unable to read file %s. Error was %s\n", - sid_file, strerror(errno) )); - return False; - } - - /* - * Convert to the machine SID. - */ - - fline[sizeof(fline)-1] = '\0'; - if(!string_to_sid( &global_machine_sid, fline)) { - DEBUG(0,("read_sid_from_file: unable to generate machine SID.\n")); - return False; - } - - return True; -} - -/**************************************************************************** - 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. -****************************************************************************/ - -static BOOL generate_machine_sid(void) -{ - int fd; - char *p; - pstring sid_file; - fstring sid_string; - struct stat st; - uchar raw_sid_data[12]; - - pstrcpy(sid_file, lp_smb_passwd_file()); - p = strrchr(sid_file, '/'); - if(p != NULL) - *++p = '\0'; - - pstrcat(sid_file, "MACHINE.SID"); - - if((fd = open( sid_file, O_RDWR | O_CREAT, 0644)) < 0 ) { - DEBUG(0,("generate_machine_sid: unable to open or create file %s. Error was %s\n", - sid_file, strerror(errno) )); - return False; - } - - /* - * Check if the file contains data. - */ - - if(fstat( fd, &st) < 0) { - DEBUG(0,("generate_machine_sid: 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,("generate_machine_sid: unable to read file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - close(fd); - return True; - } - - /* - * The file contains no data - we may need to generate our - * own sid. Try the lp_domain_sid() first. - */ - - if(*lp_domain_sid()) - fstrcpy( sid_string, lp_domain_sid()); - else { - /* - * Generate the new sid data & turn it into a string. - */ - int i; - generate_random_buffer( raw_sid_data, 12, True); - - fstrcpy( sid_string, "S-1-5-21"); - for( i = 0; i < 3; i++) { - fstring tmp_string; - slprintf( tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4)); - fstrcat( sid_string, tmp_string); - } - } - - fstrcat(sid_string, "\n"); - - /* - * Ensure our new SID is valid. - */ - - if(!string_to_sid( &global_machine_sid, sid_string)) { - DEBUG(0,("generate_machine_sid: 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,("generate_machine_sid: unable to lock file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - - /* - * 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(fstat( fd, &st) < 0) { - DEBUG(0,("generate_machine_sid: 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,("generate_machine_sid: unable to read file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - close(fd); - return True; - } - - /* - * The file is still empty and we have an exlusive lock on it. - * Write out out SID data into the file. - */ - - if(fchmod(fd, 0644) < 0) { - DEBUG(0,("generate_machine_sid: unable to set correct permissions on file %s. \ -Error was %s\n", sid_file, strerror(errno) )); - close(fd); - return False; - } - - if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) { - DEBUG(0,("generate_machine_sid: unable to write file %s. Error was %s\n", - sid_file, strerror(errno) )); - close(fd); - return False; - } - - /* - * Unlock & exit. - */ - - do_file_lock( fd, 60, F_UNLCK); - close(fd); - return True; -} - /**************************************************************************** change a dos mode to a unix mode base permission for files: -- cgit