Commit f7cf0aaa authored by Gerald Carter's avatar Gerald Carter Committed by Gerald (Jerry) Carter
Browse files

r294: checking in volker's winbindd patches; tested on domain members (Samba...

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)
parent 1f7900eb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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. */

+3 −0
Original line number Diff line number Diff line
@@ -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);

+2 −44
Original line number Diff line number Diff line
@@ -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,
+16 −9
Original line number Diff line number Diff line
@@ -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;
}
+71 −9
Original line number Diff line number Diff line
@@ -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,
@@ -149,15 +199,19 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i

	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_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, 
		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 */
	fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
@@ -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", 
@@ -462,9 +516,15 @@ 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;
	}
	
@@ -552,6 +612,8 @@ done:
	
	talloc_destroy(mem_ctx);

	domain->initialized = True;
	
	return;
}

Loading