DOM_SID global_sid_S_1_3; /* Creator Owner */
DOM_SID global_sid_S_1_5; /* NT Authority */
-static struct sid_name_map_info
+struct sid_map
{
DOM_SID *sid;
char *name;
-}
-sid_name_map[] =
+};
+
+struct sid_map static_sid_name_map[] =
{
{ &global_sid_S_1_5_20, "BUILTIN" },
{ &global_sid_S_1_1 , "Everyone" },
{ NULL , NULL }
};
-/****************************************************************************
- Read the machine SID from a file.
-****************************************************************************/
-
-static BOOL read_sid_from_file(int fd, char *sid_file)
-{
- fstring fline;
- fstring sid_str;
-
- 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;
- }
+struct sid_map **sid_name_map = NULL;
+uint32 num_maps = 0;
- /*
- * Convert to the machine SID.
- */
-
- fline[sizeof(fline)-1] = '\0';
- if (!string_to_sid( &global_sam_sid, fline)) {
- DEBUG(0,("unable to generate machine SID.\n"));
- return False;
- }
+static struct sid_map *sid_map_dup(const struct sid_map *from)
+{
+ if (from != NULL)
+ {
+ struct sid_map *copy = (struct sid_map *)
+ malloc(sizeof(struct sid_map));
+ if (copy != NULL)
+ {
+ ZERO_STRUCTP(copy);
+ if (from->name != NULL)
+ {
+ copy->name = strdup(from->name );
+ }
+ if (from->sid != NULL)
+ {
+ copy->sid = sid_dup(from->sid);
+ }
+ }
+ return copy;
+ }
+ return NULL;
+}
- sid_to_string(sid_str, &global_sam_sid);
- DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
+static void sid_map_free(struct sid_map *map)
+{
+ if (map->name != NULL)
+ {
+ free(map->name);
+ }
+ if (map->sid != NULL)
+ {
+ free(map->sid);
+ }
+ free(map);
+}
- return True;
+/****************************************************************************
+free a sid map array
+****************************************************************************/
+static void free_sidmap_array(uint32 num_entries, struct sid_map **entries)
+{
+ void(*fn)(void*) = (void(*)(void*))&sid_map_free;
+ free_void_array(num_entries, (void**)entries, *fn);
}
+/****************************************************************************
+add a sid map state to the array
+****************************************************************************/
+struct sid_map* add_sidmap_to_array(uint32 *len, struct sid_map ***array,
+ const struct sid_map *name)
+{
+ void*(*fn)(const void*) = (void*(*)(const void*))&sid_map_dup;
+ return (struct sid_map*)add_copy_to_array(len,
+ (void***)array, (const void*)name, *fn, False);
+
+}
/****************************************************************************
sets up the name associated with the SAM database for which we are responsible
****************************************************************************/
}
}
- return get_domain_sids(NULL, &global_member_sid, lp_passwordserver());
+ return get_domain_sids(lp_workgroup(), NULL, &global_member_sid);
}
+
/****************************************************************************
- obtain the sid from the PDC. do some verification along the way...
+ creates some useful well known sids
****************************************************************************/
-BOOL get_domain_sids(DOM_SID *sid3, DOM_SID *sid5, char *servers)
+void generate_wellknown_sids(void)
{
- uint16 nt_pipe_fnum;
- POLICY_HND pol;
- fstring srv_name;
- struct cli_state cli;
- BOOL res = True;
- fstring dom3;
- fstring dom5;
-
- if (sid3 == NULL && sid5 == NULL)
- {
- /* don't waste my time... */
- return False;
- }
-
- if (!cli_connect_serverlist(&cli, servers))
- {
- DEBUG(0,("get_member_domain_sid: unable to initialise client connection.\n"));
- return False;
- }
+ string_to_sid(&global_sid_S_1_5_20, "S-1-5-32");
+ string_to_sid(&global_sid_S_1_1 , "S-1-1" );
+ string_to_sid(&global_sid_S_1_3 , "S-1-3" );
+ string_to_sid(&global_sid_S_1_5 , "S-1-5" );
+}
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
+/****************************************************************************
+ create a sid map table
+****************************************************************************/
+BOOL create_sidmap_table(void)
+{
+ int i;
+ char **doms = NULL;
+ uint32 num_doms = 0;
- fstrcpy(dom3, "");
- fstrcpy(dom5, "");
- if (sid3 != NULL)
- {
- ZERO_STRUCTP(sid3);
- }
- if (sid5 != NULL)
+ for (i = 0; static_sid_name_map[i].name != NULL; i++)
{
- ZERO_STRUCTP(sid5);
+ add_sidmap_to_array(&num_maps, &sid_name_map,
+ &static_sid_name_map[i]);
}
- fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, global_myname);
- strupper(srv_name);
+ enumtrustdoms(&doms, &num_doms);
- /* open LSARPC session. */
- res = res ? cli_nt_session_open(&cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
-
- /* lookup domain controller; receive a policy handle */
- res = res ? lsa_open_policy(&cli, nt_pipe_fnum, srv_name, &pol, False) : False;
-
- if (sid3 != NULL)
+ for (i = 0; i < num_doms; i++)
{
- /* send client info query, level 3. receive domain name and sid */
- res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 3, dom3, sid3) : False;
- }
+ struct sid_map map;
+ DOM_SID sid;
- if (sid5 != NULL)
- {
- /* send client info query, level 5. receive domain name and sid */
- res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 5, dom5, sid5) : False;
- }
-
- /* close policy handle */
- res = res ? lsa_close(&cli, nt_pipe_fnum, &pol) : False;
-
- /* close the session */
- cli_nt_session_close(&cli, nt_pipe_fnum);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
+ map.name = doms[i];
+ map.sid = &sid;
- if (res)
- {
- pstring sid;
- DEBUG(2,("LSA Query Info Policy\n"));
- if (sid3 != NULL)
+ if (!read_sid(map.name, map.sid))
{
- sid_to_string(sid, sid3);
- DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid));
- }
- if (sid5 != NULL)
- {
- sid_to_string(sid, sid5);
- DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid));
+ DEBUG(0,("Could not read Domain SID %s\n", map.name));
+ return False;
}
+ add_sidmap_to_array(&num_maps, &sid_name_map, &map);
}
- else
+
+
+ for (i = 0; i < num_maps; i++)
{
- DEBUG(1,("lsa query info failed\n"));
+ fstring sidstr;
+ sid_to_string(sidstr, sid_name_map[i]->sid);
+ DEBUG(10,("Map:\tDomain:\t%s\tSID:\t%s\n",
+ sid_name_map[i]->name, sidstr));
}
- return res;
-}
-/****************************************************************************
- creates some useful well known sids
-****************************************************************************/
-void generate_wellknown_sids(void)
-{
- string_to_sid(&global_sid_S_1_5_20, "S-1-5-32");
- string_to_sid(&global_sid_S_1_1 , "S-1-1" );
- string_to_sid(&global_sid_S_1_3 , "S-1-3" );
- string_to_sid(&global_sid_S_1_5 , "S-1-5" );
+ free_char_array(num_doms, doms);
+
+ return True;
}
/****************************************************************************
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
-BOOL generate_sam_sid(char *domain_name)
+BOOL generate_sam_sid(char *domain_name, DOM_SID *sid)
{
- int fd;
- int i;
char *p;
pstring sid_file;
pstring machine_sid_file;
- fstring sid_string;
fstring file_name;
- SMB_STRUCT_STAT st;
- uchar raw_sid_data[12];
pstrcpy(sid_file, lp_smb_passwd_file());
}
}
- 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;
- }
- close(fd);
+ /* attempt to read the SID from the file */
+ if (read_sid(domain_name, sid))
+ {
return True;
- }
-
- /*
- * Generate the new sid data & turn it into a string.
- */
- 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_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;
- }
-
- /*
- * 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);
+ if (!create_new_sid(sid))
+ {
return False;
- }
+ }
+ /* attempt to read the SID from the file */
+ if (!write_sid(domain_name, sid))
+ {
+ return True;
+ }
- 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);
+ /* during the attempt to write, someone else wrote? */
+
+ /* attempt to read the SID from the file */
+ if (read_sid(domain_name, sid))
+ {
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,("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,("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;
}
DEBUG(5,("map_domain_name_to_sid: %s\n", (*nt_domain)));
- while (sid_name_map[i].name != NULL)
+ for (i = 0; sid_name_map[i]->name != NULL; i++)
{
- DEBUG(5,("compare: %s\n", sid_name_map[i].name));
- if (strequal(sid_name_map[i].name, (*nt_domain)))
+ DEBUG(5,("compare: %s\n", sid_name_map[i]->name));
+ if (strequal(sid_name_map[i]->name, (*nt_domain)))
{
fstring sid_str;
- sid_copy(sid, sid_name_map[i].sid);
- sid_to_string(sid_str, sid_name_map[i].sid);
+ sid_copy(sid, sid_name_map[i]->sid);
+ sid_to_string(sid_str, sid_name_map[i]->sid);
DEBUG(5,("found %s\n", sid_str));
return True;
}
- i++;
}
DEBUG(0,("map_domain_name_to_sid: mapping to %s NOT IMPLEMENTED\n",
return False;
}
- while (sid_name_map[i].sid != NULL)
+ for (i = 0; sid_name_map[i]->sid != NULL; i++)
{
- sid_to_string(sid_str, sid_name_map[i].sid);
+ sid_to_string(sid_str, sid_name_map[i]->sid);
DEBUG(5,("compare: %s\n", sid_str));
- if (sid_equal(sid_name_map[i].sid, sid))
+ if (sid_equal(sid_name_map[i]->sid, sid))
{
- fstrcpy(nt_domain, sid_name_map[i].name);
+ fstrcpy(nt_domain, sid_name_map[i]->name);
DEBUG(5,("found %s\n", nt_domain));
return True;
}
- i++;
}
DEBUG(0,("map_domain_sid_to_name: mapping NOT IMPLEMENTED\n"));
return False;
}
+/**************************************************************************
+ turns a domain SID into a domain controller name.
+***************************************************************************/
+BOOL map_domain_sid_to_any_dc(DOM_SID *sid, char *dc_name)
+{
+ fstring domain;
+
+ if (!map_domain_sid_to_name(sid, domain))
+ {
+ return False;
+ }
+
+ return get_any_dc_name(domain, dc_name);
+}
/**************************************************************************
splits a name of format \DOMAIN\name or name into its two components.
DEBUG(10,("name '%s' split into domain:%s and nt name:%s'\n", fullname, domain, name));
return True;
}
+
+/**************************************************************************
+ enumerates all trusted domains
+***************************************************************************/
+BOOL enumtrustdoms(char ***doms, uint32 *num_entries)
+{
+ fstring tmp;
+ char *tok;
+
+ /* add trusted domains */
+
+ tok = lp_trusted_domains();
+ if (next_token(&tok, tmp, NULL, sizeof(tmp)))
+ {
+ do
+ {
+ fstring domain;
+ split_at_first_component(tmp, domain, '=', NULL);
+ add_chars_to_array(num_entries, doms, domain);
+
+ } while (next_token(NULL, tmp, NULL, sizeof(tmp)));
+ }
+
+ return True;
+}
+
+/**************************************************************************
+ enumerates all domains for which the SAM server is responsible
+***************************************************************************/
+BOOL enumdomains(char ***doms, uint32 *num_entries)
+{
+ add_chars_to_array(num_entries, doms, global_sam_name);
+ add_chars_to_array(num_entries, doms, "Builtin");
+
+ return True;
+}
+