mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
r294: checking in volker's winbindd patches; tested on domain members (Samba and AD) as well as on a Samba DC
(This used to be commit 157d53782d6a7d0b7e30676a674ff2a25a15369c)
This commit is contained in:
parent
1f7900ebda
commit
f7cf0aaa6f
@ -880,6 +880,8 @@ int main(int argc, char **argv)
|
||||
if (!idmap_init(lp_idmap_backend()))
|
||||
return 1;
|
||||
|
||||
generate_wellknown_sids();
|
||||
|
||||
/* Unblock all signals we are interested in as they may have been
|
||||
blocked by the parent process. */
|
||||
|
||||
|
@ -94,6 +94,7 @@ struct winbindd_domain {
|
||||
fstring name; /* Domain name */
|
||||
fstring alt_name; /* alt Domain name (if any) */
|
||||
DOM_SID sid; /* SID for this domain */
|
||||
BOOL initialized; /* Did we already ask for the domain mode? */
|
||||
BOOL native_mode; /* is this a win2k domain in native mode ? */
|
||||
BOOL active_directory; /* is this a win2k active directory ? */
|
||||
BOOL primary; /* is this our primary domain ? */
|
||||
@ -149,6 +150,7 @@ struct winbindd_methods {
|
||||
/* convert one user or group name to a sid */
|
||||
NTSTATUS (*name_to_sid)(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *domain_name,
|
||||
const char *name,
|
||||
DOM_SID *sid,
|
||||
enum SID_NAME_USE *type);
|
||||
@ -157,6 +159,7 @@ struct winbindd_methods {
|
||||
NTSTATUS (*sid_to_name)(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *sid,
|
||||
char **domain_name,
|
||||
char **name,
|
||||
enum SID_NAME_USE *type);
|
||||
|
||||
|
@ -323,48 +323,6 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* convert a single name to a sid in a domain */
|
||||
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *name,
|
||||
DOM_SID *sid,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
ADS_STRUCT *ads;
|
||||
|
||||
DEBUG(3,("ads: name_to_sid\n"));
|
||||
|
||||
ads = ads_cached_connection(domain);
|
||||
|
||||
if (!ads) {
|
||||
domain->last_status = NT_STATUS_SERVER_DISABLED;
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return ads_name_to_sid(ads, name, sid, type);
|
||||
}
|
||||
|
||||
/* convert a sid to a user or group name */
|
||||
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *sid,
|
||||
char **name,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
ADS_STRUCT *ads = NULL;
|
||||
DEBUG(3,("ads: sid_to_name\n"));
|
||||
|
||||
ads = ads_cached_connection(domain);
|
||||
|
||||
if (!ads) {
|
||||
domain->last_status = NT_STATUS_SERVER_DISABLED;
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return ads_sid_to_name(ads, mem_ctx, sid, name, type);
|
||||
}
|
||||
|
||||
|
||||
/* convert a DN to a name, SID and name type
|
||||
this might become a major speed bottleneck if groups have
|
||||
lots of users, in which case we could cache the results
|
||||
@ -1004,8 +962,8 @@ struct winbindd_methods ads_methods = {
|
||||
query_user_list,
|
||||
enum_dom_groups,
|
||||
enum_local_groups,
|
||||
name_to_sid,
|
||||
sid_to_name,
|
||||
msrpc_name_to_sid,
|
||||
msrpc_sid_to_name,
|
||||
query_user,
|
||||
lookup_usergroups,
|
||||
lookup_groupmem,
|
||||
|
@ -595,7 +595,7 @@ static void centry_end(struct cache_entry *centry, const char *format, ...)
|
||||
}
|
||||
|
||||
static void wcache_save_name_to_sid(struct winbindd_domain *domain,
|
||||
NTSTATUS status,
|
||||
NTSTATUS status, const char *domain_name,
|
||||
const char *name, const DOM_SID *sid,
|
||||
enum SID_NAME_USE type)
|
||||
{
|
||||
@ -610,13 +610,13 @@ static void wcache_save_name_to_sid(struct winbindd_domain *domain,
|
||||
centry_put_sid(centry, sid);
|
||||
fstrcpy(uname, name);
|
||||
strupper_m(uname);
|
||||
centry_end(centry, "NS/%s/%s", domain->name, uname);
|
||||
centry_end(centry, "NS/%s/%s", domain_name, uname);
|
||||
DEBUG(10,("wcache_save_name_to_sid: %s -> %s\n", uname, sid_string));
|
||||
centry_free(centry);
|
||||
}
|
||||
|
||||
static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
|
||||
const DOM_SID *sid, const char *name, enum SID_NAME_USE type)
|
||||
const DOM_SID *sid, const char *domain_name, const char *name, enum SID_NAME_USE type)
|
||||
{
|
||||
struct cache_entry *centry;
|
||||
fstring sid_string;
|
||||
@ -626,6 +626,7 @@ static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS sta
|
||||
return;
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
centry_put_uint32(centry, type);
|
||||
centry_put_string(centry, domain_name);
|
||||
centry_put_string(centry, name);
|
||||
}
|
||||
centry_end(centry, "SN/%s", sid_to_string(sid_string, sid));
|
||||
@ -743,10 +744,12 @@ do_query:
|
||||
/* when the backend is consistent we can pre-prime some mappings */
|
||||
wcache_save_name_to_sid(domain, NT_STATUS_OK,
|
||||
(*info)[i].acct_name,
|
||||
domain->name,
|
||||
(*info)[i].user_sid,
|
||||
SID_NAME_USER);
|
||||
wcache_save_sid_to_name(domain, NT_STATUS_OK,
|
||||
(*info)[i].user_sid,
|
||||
domain->name,
|
||||
(*info)[i].acct_name,
|
||||
SID_NAME_USER);
|
||||
wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]);
|
||||
@ -918,6 +921,7 @@ skip_save:
|
||||
/* convert a single name to a sid in a domain */
|
||||
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *domain_name,
|
||||
const char *name,
|
||||
DOM_SID *sid,
|
||||
enum SID_NAME_USE *type)
|
||||
@ -933,7 +937,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
|
||||
fstrcpy(uname, name);
|
||||
strupper_m(uname);
|
||||
centry = wcache_fetch(cache, domain, "NS/%s/%s", domain->name, uname);
|
||||
centry = wcache_fetch(cache, domain, "NS/%s/%s", domain_name, uname);
|
||||
if (!centry)
|
||||
goto do_query;
|
||||
*type = (enum SID_NAME_USE)centry_uint32(centry);
|
||||
@ -969,10 +973,10 @@ do_query:
|
||||
DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n",
|
||||
domain->name ));
|
||||
|
||||
status = domain->backend->name_to_sid(domain, mem_ctx, name, sid, type);
|
||||
status = domain->backend->name_to_sid(domain, mem_ctx, domain_name, name, sid, type);
|
||||
|
||||
/* and save it */
|
||||
wcache_save_name_to_sid(domain, status, name, sid, *type);
|
||||
wcache_save_name_to_sid(domain, status, domain_name, name, sid, *type);
|
||||
|
||||
/* We can't save the sid to name mapping as we don't know the
|
||||
correct case of the name without looking it up */
|
||||
@ -985,6 +989,7 @@ do_query:
|
||||
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *sid,
|
||||
char **domain_name,
|
||||
char **name,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
@ -1001,6 +1006,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
goto do_query;
|
||||
if (NT_STATUS_IS_OK(centry->status)) {
|
||||
*type = (enum SID_NAME_USE)centry_uint32(centry);
|
||||
*domain_name = centry_string(centry, mem_ctx);
|
||||
*name = centry_string(centry, mem_ctx);
|
||||
}
|
||||
status = centry->status;
|
||||
@ -1013,6 +1019,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
|
||||
do_query:
|
||||
*name = NULL;
|
||||
*domain_name = NULL;
|
||||
|
||||
/* If the seq number check indicated that there is a problem
|
||||
* with this DC, then return that status... except for
|
||||
@ -1028,12 +1035,12 @@ do_query:
|
||||
DEBUG(10,("sid_to_name: [Cached] - doing backend query for name for domain %s\n",
|
||||
domain->name ));
|
||||
|
||||
status = domain->backend->sid_to_name(domain, mem_ctx, sid, name, type);
|
||||
status = domain->backend->sid_to_name(domain, mem_ctx, sid, domain_name, name, type);
|
||||
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, False);
|
||||
wcache_save_sid_to_name(domain, status, sid, *name, *type);
|
||||
wcache_save_name_to_sid(domain, status, *name, sid, *type);
|
||||
wcache_save_sid_to_name(domain, status, sid, *domain_name, *name, *type);
|
||||
wcache_save_name_to_sid(domain, status, *domain_name, *name, sid, *type);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -77,6 +77,9 @@ struct winbindd_cm_conn {
|
||||
|
||||
static struct winbindd_cm_conn *cm_conns = NULL;
|
||||
|
||||
static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain,
|
||||
const char *pipe_name,
|
||||
struct winbindd_cm_conn **conn_out);
|
||||
|
||||
/* Choose between anonymous or authenticated connections. We need to use
|
||||
an authenticated connection if DCs have the RestrictAnonymous registry
|
||||
@ -133,6 +136,53 @@ static NTSTATUS setup_schannel(struct cli_state *cli)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
|
||||
fstring dcname, struct in_addr *dc_ip)
|
||||
{
|
||||
struct winbindd_domain *our_domain;
|
||||
NTSTATUS result;
|
||||
struct winbindd_cm_conn *conn;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
fstring tmp;
|
||||
char *p;
|
||||
|
||||
if (IS_DC)
|
||||
return False;
|
||||
|
||||
if (domain->primary)
|
||||
return False;
|
||||
|
||||
if ((our_domain = find_our_domain()) == NULL)
|
||||
return False;
|
||||
|
||||
result = get_connection_from_cache(our_domain, PIPE_NETLOGON, &conn);
|
||||
if (!NT_STATUS_IS_OK(result))
|
||||
return False;
|
||||
|
||||
if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL)
|
||||
return False;
|
||||
|
||||
result = cli_netlogon_getdcname(conn->cli, mem_ctx, domain->name, tmp);
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result))
|
||||
return False;
|
||||
|
||||
/* cli_netlogon_getdcname gives us a name with \\ */
|
||||
p = tmp;
|
||||
if (*p == '\\') p+=1;
|
||||
if (*p == '\\') p+=1;
|
||||
|
||||
fstrcpy(dcname, p);
|
||||
|
||||
if (!resolve_name(dcname, dc_ip, 0x20))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Open a connction to the remote server, cache failures for 30 seconds */
|
||||
|
||||
static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
|
||||
@ -148,15 +198,19 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
|
||||
ZERO_STRUCT(dc_ip);
|
||||
|
||||
fstrcpy(new_conn->domain, domain->name);
|
||||
|
||||
/* connection failure cache has been moved inside of get_dc_name
|
||||
so we can deal with half dead DC's --jerry */
|
||||
|
||||
if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL,
|
||||
new_conn->controller, &dc_ip)) {
|
||||
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
||||
add_failed_connection_entry(domain->name, "", result);
|
||||
return result;
|
||||
if (!get_dc_name_via_netlogon(domain, new_conn->controller, &dc_ip)) {
|
||||
|
||||
/* connection failure cache has been moved inside of
|
||||
get_dc_name so we can deal with half dead DC's --jerry */
|
||||
|
||||
if (!get_dc_name(domain->name, domain->alt_name[0] ?
|
||||
domain->alt_name : NULL,
|
||||
new_conn->controller, &dc_ip)) {
|
||||
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
||||
add_failed_connection_entry(domain->name, "", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialise SMB connection */
|
||||
@ -282,7 +336,7 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
|
||||
failed. This allows existing setups to continue working,
|
||||
while solving the win2003 '100 user' limit for systems that
|
||||
are joined properly */
|
||||
if (NT_STATUS_IS_OK(result)) {
|
||||
if (NT_STATUS_IS_OK(result) && (domain->primary)) {
|
||||
NTSTATUS status = setup_schannel(new_conn->cli);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(3,("schannel refused - continuing without schannel (%s)\n",
|
||||
@ -461,10 +515,16 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
|
||||
|
||||
domain->native_mode = False;
|
||||
domain->active_directory = False;
|
||||
|
||||
if (domain->internal) {
|
||||
domain->initialized = True;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
|
||||
DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
|
||||
domain->name, nt_errstr(result)));
|
||||
domain->initialized = True;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -551,6 +611,8 @@ done:
|
||||
cli_shutdown( conn.cli );
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
domain->initialized = True;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
|
||||
|
||||
/* Get rid and name type from name */
|
||||
|
||||
if (!winbindd_lookup_sid_by_name(domain, name_group, &group_sid,
|
||||
if (!winbindd_lookup_sid_by_name(domain, domain->name, name_group, &group_sid,
|
||||
&name_type)) {
|
||||
DEBUG(1, ("group %s in domain %s does not exist\n",
|
||||
name_group, name_domain));
|
||||
@ -446,17 +446,16 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
|
||||
for (domain = domain_list(); domain != NULL; domain = domain->next) {
|
||||
struct getent_state *domain_state;
|
||||
|
||||
|
||||
/* Create a state record for this domain */
|
||||
|
||||
/* don't add our domaina if we are a PDC or if we
|
||||
are a member of a Samba domain */
|
||||
|
||||
if ( (IS_DC || lp_winbind_trusted_domains_only())
|
||||
&& domain->primary )
|
||||
if ( lp_winbind_trusted_domains_only() && domain->primary )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a state record for this domain */
|
||||
|
||||
if ((domain_state = (struct getent_state *)
|
||||
malloc(sizeof(struct getent_state))) == NULL) {
|
||||
@ -945,12 +944,10 @@ static void add_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
|
||||
if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0)))
|
||||
add_gid_to_array_unique(gid, gids, num);
|
||||
|
||||
/* Don't expand aliases if not explicitly activated -- for now */
|
||||
/* we don't support windows local nested groups if we are a DC.
|
||||
refer to to sid_to_gid() in the smbd server code to see why
|
||||
/* Don't expand aliases if not explicitly activated -- for now
|
||||
-- jerry */
|
||||
|
||||
if (!lp_winbind_nested_groups() || IS_DC)
|
||||
if (!lp_winbind_nested_groups())
|
||||
return;
|
||||
|
||||
/* Add nested group memberships */
|
||||
@ -1021,7 +1018,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
|
||||
|
||||
/* Get rid and name type from name. The following costs 1 packet */
|
||||
|
||||
if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid,
|
||||
if (!winbindd_lookup_sid_by_name(domain, domain->name, name_user, &user_sid,
|
||||
&name_type)) {
|
||||
DEBUG(1, ("user '%s' does not exist\n", name_user));
|
||||
goto done;
|
||||
|
@ -52,6 +52,7 @@ add_expanded_sid(const DOM_SID *sid, char **members, int *num_members)
|
||||
struct winbindd_domain *domain;
|
||||
int i;
|
||||
|
||||
char *domain_name = NULL;
|
||||
char *name = NULL;
|
||||
enum SID_NAME_USE type;
|
||||
|
||||
@ -72,7 +73,7 @@ add_expanded_sid(const DOM_SID *sid, char **members, int *num_members)
|
||||
sid_copy(&dom_sid, sid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
domain = find_domain_from_sid(&dom_sid);
|
||||
domain = find_lookup_domain_from_sid(sid);
|
||||
|
||||
if (domain == NULL) {
|
||||
DEBUG(3, ("Could not find domain for sid %s\n",
|
||||
@ -81,7 +82,7 @@ add_expanded_sid(const DOM_SID *sid, char **members, int *num_members)
|
||||
}
|
||||
|
||||
result = domain->methods->sid_to_name(domain, mem_ctx, sid,
|
||||
&name, &type);
|
||||
&domain_name, &name, &type);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3, ("sid_to_name failed for sid %s\n",
|
||||
@ -92,7 +93,7 @@ add_expanded_sid(const DOM_SID *sid, char **members, int *num_members)
|
||||
DEBUG(10, ("Found name %s, type %d\n", name, type));
|
||||
|
||||
if (type == SID_NAME_USER) {
|
||||
add_member(domain->name, name, members, num_members);
|
||||
add_member(domain_name, name, members, num_members);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -102,7 +103,15 @@ add_expanded_sid(const DOM_SID *sid, char **members, int *num_members)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Expand the domain group */
|
||||
/* Expand the domain group, this must be done via the target domain */
|
||||
|
||||
domain = find_domain_from_sid(sid);
|
||||
|
||||
if (domain == NULL) {
|
||||
DEBUG(3, ("Could not find domain from SID %s\n",
|
||||
sid_string_static(sid)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = domain->methods->lookup_groupmem(domain, mem_ctx,
|
||||
sid, &num_names,
|
||||
@ -221,6 +230,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
/* convert a single name to a sid in a domain */
|
||||
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *domain_name,
|
||||
const char *name,
|
||||
DOM_SID *sid,
|
||||
enum SID_NAME_USE *type)
|
||||
@ -240,6 +250,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *sid,
|
||||
char **domain_name,
|
||||
char **name,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
@ -250,6 +261,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
if (!pdb_get_aliasinfo(sid, &info))
|
||||
return NT_STATUS_NONE_MAPPED;
|
||||
|
||||
*domain_name = talloc_strdup(mem_ctx, domain->name);
|
||||
*name = talloc_strdup(mem_ctx, info.acct_name);
|
||||
*type = SID_NAME_ALIAS;
|
||||
|
||||
@ -300,7 +312,45 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
char ***alt_names,
|
||||
DOM_SID **dom_sids)
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
NTSTATUS nt_status;
|
||||
int enum_ctx = 0;
|
||||
int num_sec_domains;
|
||||
TRUSTDOM **domains;
|
||||
*num_domains = 0;
|
||||
*names = NULL;
|
||||
*alt_names = NULL;
|
||||
*dom_sids = NULL;
|
||||
do {
|
||||
int i;
|
||||
nt_status = secrets_get_trusted_domains(mem_ctx, &enum_ctx, 1,
|
||||
&num_sec_domains,
|
||||
&domains);
|
||||
*names = talloc_realloc(mem_ctx, *names,
|
||||
sizeof(*names) *
|
||||
(num_sec_domains + *num_domains));
|
||||
*alt_names = talloc_realloc(mem_ctx, *alt_names,
|
||||
sizeof(*alt_names) *
|
||||
(num_sec_domains + *num_domains));
|
||||
*dom_sids = talloc_realloc(mem_ctx, *dom_sids,
|
||||
sizeof(**dom_sids) *
|
||||
(num_sec_domains + *num_domains));
|
||||
|
||||
for (i=0; i< num_sec_domains; i++) {
|
||||
if (pull_ucs2_talloc(mem_ctx, &(*names)[*num_domains],
|
||||
domains[i]->name) == -1) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
(*alt_names)[*num_domains] = NULL;
|
||||
(*dom_sids)[*num_domains] = domains[i]->sid;
|
||||
(*num_domains)++;
|
||||
}
|
||||
|
||||
} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
|
||||
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
/* find the domain sid for a domain */
|
||||
|
@ -274,8 +274,9 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
}
|
||||
|
||||
/* convert a single name to a sid in a domain */
|
||||
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *domain_name,
|
||||
const char *name,
|
||||
DOM_SID *sid,
|
||||
enum SID_NAME_USE *type)
|
||||
@ -289,14 +290,14 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
|
||||
DEBUG(3,("rpc: name_to_sid name=%s\n", name));
|
||||
|
||||
full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
|
||||
full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
|
||||
|
||||
if (!full_name) {
|
||||
DEBUG(0, ("talloc_asprintf failed!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain->name ));
|
||||
DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain_name ));
|
||||
|
||||
retry = 0;
|
||||
do {
|
||||
@ -322,9 +323,10 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
/*
|
||||
convert a domain SID to a user or group name
|
||||
*/
|
||||
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *sid,
|
||||
char **domain_name,
|
||||
char **name,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
@ -350,14 +352,9 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
|
||||
if (NT_STATUS_IS_OK(result)) {
|
||||
*type = (enum SID_NAME_USE)types[0];
|
||||
*domain_name = domains[0];
|
||||
*name = names[0];
|
||||
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
|
||||
|
||||
/* Paranoia */
|
||||
if (!strequal(domain->name, domains[0])) {
|
||||
DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -995,8 +992,8 @@ struct winbindd_methods msrpc_methods = {
|
||||
query_user_list,
|
||||
enum_dom_groups,
|
||||
enum_local_groups,
|
||||
name_to_sid,
|
||||
sid_to_name,
|
||||
msrpc_name_to_sid,
|
||||
msrpc_sid_to_name,
|
||||
query_user,
|
||||
lookup_usergroups,
|
||||
lookup_groupmem,
|
||||
|
@ -95,14 +95,14 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
|
||||
DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
|
||||
name_domain, lp_winbind_separator(), name_user));
|
||||
|
||||
if ((domain = find_domain_from_name(name_domain)) == NULL) {
|
||||
if ((domain = find_lookup_domain_from_name(name_domain)) == NULL) {
|
||||
DEBUG(0, ("could not find domain entry for domain %s\n",
|
||||
name_domain));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
/* Lookup name from PDC using lsa_lookup_names() */
|
||||
if (!winbindd_lookup_sid_by_name(domain, name_user, &sid, &type)) {
|
||||
if (!winbindd_lookup_sid_by_name(domain, name_domain, name_user, &sid, &type)) {
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
@ -335,7 +335,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
if ( !winbindd_lookup_sid_by_name(domain, pw->pw_name, &sid, &type) )
|
||||
if ( !winbindd_lookup_sid_by_name(domain, domain->name, pw->pw_name, &sid, &type) )
|
||||
return WINBINDD_ERROR;
|
||||
|
||||
if ( type != SID_NAME_USER )
|
||||
@ -405,7 +405,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
if ( !winbindd_lookup_sid_by_name(domain, grp->gr_name, &sid, &type) )
|
||||
if ( !winbindd_lookup_sid_by_name(domain, domain->name, grp->gr_name, &sid, &type) )
|
||||
return WINBINDD_ERROR;
|
||||
|
||||
if ( type!=SID_NAME_DOM_GRP && type!=SID_NAME_ALIAS )
|
||||
|
@ -153,7 +153,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
|
||||
|
||||
/* Get rid and name type from name */
|
||||
|
||||
if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, &name_type)) {
|
||||
if (!winbindd_lookup_sid_by_name(domain, domain->name, name_user, &user_sid, &name_type)) {
|
||||
DEBUG(1, ("user '%s' does not exist\n", name_user));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
@ -85,13 +85,15 @@ void free_domain_list(void)
|
||||
|
||||
static BOOL is_internal_domain(const DOM_SID *sid)
|
||||
{
|
||||
DOM_SID tmp_sid;
|
||||
extern DOM_SID global_sid_Builtin;
|
||||
|
||||
if (sid_equal(sid, get_global_sam_sid()))
|
||||
if (sid == NULL)
|
||||
return False;
|
||||
|
||||
if (sid_compare_domain(sid, get_global_sam_sid()) == 0)
|
||||
return True;
|
||||
|
||||
string_to_sid(&tmp_sid, "S-1-5-32");
|
||||
if (sid_equal(sid, &tmp_sid))
|
||||
if (sid_compare_domain(sid, &global_sid_Builtin) == 0)
|
||||
return True;
|
||||
|
||||
return False;
|
||||
@ -160,15 +162,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
|
||||
domain->internal = is_internal_domain(sid);
|
||||
domain->sequence_number = DOM_SEQUENCE_NONE;
|
||||
domain->last_seq_check = 0;
|
||||
domain->initialized = False;
|
||||
if (sid) {
|
||||
sid_copy(&domain->sid, sid);
|
||||
}
|
||||
|
||||
/* set flags about native_mode, active_directory */
|
||||
|
||||
if (!domain->internal)
|
||||
set_dc_type_and_flags( domain );
|
||||
|
||||
DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name,
|
||||
domain->active_directory ? "ADS" : "NT4",
|
||||
domain->native_mode ? "native mode" :
|
||||
@ -190,6 +188,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
|
||||
|
||||
static void add_trusted_domains( struct winbindd_domain *domain )
|
||||
{
|
||||
extern struct winbindd_methods cache_methods;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
NTSTATUS result;
|
||||
time_t t;
|
||||
@ -226,7 +225,7 @@ static void add_trusted_domains( struct winbindd_domain *domain )
|
||||
for(i = 0; i < num_domains; i++) {
|
||||
DEBUG(10,("Found domain %s\n", names[i]));
|
||||
add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
|
||||
domain->methods, &dom_sids[i]);
|
||||
&cache_methods, &dom_sids[i]);
|
||||
|
||||
/* if the SID was empty, we better set it now */
|
||||
|
||||
@ -290,16 +289,28 @@ void rescan_trusted_domains( void )
|
||||
/* Look up global info for the winbind daemon */
|
||||
BOOL init_domain_list(void)
|
||||
{
|
||||
extern DOM_SID global_sid_Builtin;
|
||||
extern struct winbindd_methods cache_methods;
|
||||
extern struct winbindd_methods passdb_methods;
|
||||
struct winbindd_domain *domain;
|
||||
|
||||
/* Free existing list */
|
||||
free_domain_list();
|
||||
|
||||
/* Add ourselves as the first entry. */
|
||||
|
||||
if (IS_DC) {
|
||||
domain = add_trusted_domain(get_global_sam_name(), NULL,
|
||||
&passdb_methods, get_global_sam_sid());
|
||||
} else {
|
||||
|
||||
domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL);
|
||||
domain = add_trusted_domain( lp_workgroup(), lp_realm(),
|
||||
&cache_methods, NULL);
|
||||
|
||||
/* set flags about native_mode, active_directory */
|
||||
set_dc_type_and_flags(domain);
|
||||
}
|
||||
|
||||
domain->primary = True;
|
||||
|
||||
/* get any alternate name for the primary domain */
|
||||
@ -320,27 +331,15 @@ BOOL init_domain_list(void)
|
||||
/* do an initial scan for trusted domains */
|
||||
add_trusted_domains(domain);
|
||||
|
||||
/* Don't expand aliases if not explicitly activated -- for now */
|
||||
/* we don't support windows local nested groups if we are a DC.
|
||||
refer to to sid_to_gid() in the smbd server code to see why
|
||||
-- jerry */
|
||||
|
||||
/* Add our local SAM domains */
|
||||
|
||||
if (lp_winbind_nested_groups() || IS_DC) {
|
||||
add_trusted_domain("BUILTIN", NULL, &passdb_methods,
|
||||
&global_sid_Builtin);
|
||||
|
||||
/* Add our local SAM domains */
|
||||
DOM_SID sid;
|
||||
extern struct winbindd_methods passdb_methods;
|
||||
struct winbindd_domain *dom;
|
||||
|
||||
string_to_sid(&sid, "S-1-5-32");
|
||||
|
||||
dom = add_trusted_domain("BUILTIN", NULL, &passdb_methods,
|
||||
&sid);
|
||||
|
||||
dom = add_trusted_domain(get_global_sam_name(), NULL,
|
||||
&passdb_methods,
|
||||
get_global_sam_sid());
|
||||
if (!IS_DC) {
|
||||
add_trusted_domain(get_global_sam_name(), NULL,
|
||||
&passdb_methods, get_global_sam_sid());
|
||||
}
|
||||
|
||||
/* avoid rescanning this right away */
|
||||
@ -369,6 +368,9 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name)
|
||||
for (domain = domain_list(); domain != NULL; domain = domain->next) {
|
||||
if (strequal(domain_name, domain->name) ||
|
||||
(domain->alt_name[0] && strequal(domain_name, domain->alt_name))) {
|
||||
if (!domain->initialized)
|
||||
set_dc_type_and_flags(domain);
|
||||
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
@ -387,8 +389,11 @@ struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid)
|
||||
/* Search through list */
|
||||
|
||||
for (domain = domain_list(); domain != NULL; domain = domain->next) {
|
||||
if (sid_compare_domain(sid, &domain->sid) == 0)
|
||||
if (sid_compare_domain(sid, &domain->sid) == 0) {
|
||||
if (!domain->initialized)
|
||||
set_dc_type_and_flags(domain);
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
@ -414,21 +419,49 @@ struct winbindd_domain *find_our_domain(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the appropriate domain to lookup a name or SID */
|
||||
|
||||
struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid)
|
||||
{
|
||||
/* A DC can't ask the local smbd for remote SIDs, here winbindd is the
|
||||
* one to contact the external DC's. On member servers the internal
|
||||
* domains are different: These are part of the local SAM. */
|
||||
|
||||
if (IS_DC || is_internal_domain(sid))
|
||||
return find_domain_from_sid(sid);
|
||||
|
||||
/* On a member server a query for SID or name can always go to our
|
||||
* primary DC. */
|
||||
|
||||
return find_our_domain();
|
||||
}
|
||||
|
||||
struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name)
|
||||
{
|
||||
if (IS_DC || strequal(domain_name, "BUILTIN") ||
|
||||
strequal(domain_name, get_global_sam_name()))
|
||||
return find_domain_from_name(domain_name);
|
||||
|
||||
return find_our_domain();
|
||||
}
|
||||
|
||||
/* Lookup a sid in a domain from a name */
|
||||
|
||||
BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
|
||||
const char *domain_name,
|
||||
const char *name, DOM_SID *sid,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
NTSTATUS result;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name);
|
||||
mem_ctx = talloc_init("lookup_sid_by_name for %s\\%s\n",
|
||||
domain_name, name);
|
||||
if (!mem_ctx)
|
||||
return False;
|
||||
|
||||
/* Lookup name */
|
||||
result = domain->methods->name_to_sid(domain, mem_ctx, name, sid, type);
|
||||
result = domain->methods->name_to_sid(domain, mem_ctx, domain_name, name, sid, type);
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
@ -457,12 +490,13 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
char *names;
|
||||
char *dom_names;
|
||||
NTSTATUS result;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL rv = False;
|
||||
struct winbindd_domain *domain;
|
||||
|
||||
domain = find_domain_from_sid(sid);
|
||||
domain = find_lookup_domain_from_sid(sid);
|
||||
|
||||
if (!domain) {
|
||||
DEBUG(1,("Can't find domain from sid\n"));
|
||||
@ -474,12 +508,12 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
|
||||
if (!(mem_ctx = talloc_init("winbindd_lookup_name_by_sid")))
|
||||
return False;
|
||||
|
||||
result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type);
|
||||
result = domain->methods->sid_to_name(domain, mem_ctx, sid, &dom_names, &names, type);
|
||||
|
||||
/* Return name and type if successful */
|
||||
|
||||
if ((rv = NT_STATUS_IS_OK(result))) {
|
||||
fstrcpy(dom_name, domain->name);
|
||||
fstrcpy(dom_name, dom_names);
|
||||
fstrcpy(name, names);
|
||||
} else {
|
||||
*type = SID_NAME_UNKNOWN;
|
||||
|
Loading…
x
Reference in New Issue
Block a user