winbindd_rpc.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 901 行 · 第 1/2 页

C
901
字号
		return result;	/* Get user handle */	result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,					des_access, user_rid, &user_pol);	if (!NT_STATUS_IS_OK(result))		return result;	/* Query user rids */	result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol, 					   num_groups, &user_groups);	rpccli_samr_close(cli, mem_ctx, &user_pol);	if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)		return result;	(*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);	if (!(*user_grpsids))		return NT_STATUS_NO_MEMORY;	for (i=0;i<(*num_groups);i++) {		sid_copy(&((*user_grpsids)[i]), &domain->sid);		sid_append_rid(&((*user_grpsids)[i]),				user_groups[i].g_rid);	}		return NT_STATUS_OK;}NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,				  TALLOC_CTX *mem_ctx,				  uint32 num_sids, const DOM_SID *sids,				  uint32 *num_aliases, uint32 **alias_rids){	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;	POLICY_HND dom_pol;	DOM_SID2 *sid2;	int i;	struct rpc_pipe_client *cli;	*num_aliases = 0;	*alias_rids = NULL;	DEBUG(3,("rpc: lookup_useraliases\n"));	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);	if (!NT_STATUS_IS_OK(result))		return result;	sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);	if (sid2 == NULL)		return NT_STATUS_NO_MEMORY;	for (i=0; i<num_sids; i++) {		sid_copy(&sid2[i].sid, &sids[i]);		sid2[i].num_auths = sid2[i].sid.num_auths;	}	result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,					       num_sids, sid2,					       num_aliases, alias_rids);	return result;}/* Lookup group membership given a rid.   */static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,				TALLOC_CTX *mem_ctx,				const DOM_SID *group_sid, uint32 *num_names, 				DOM_SID **sid_mem, char ***names, 				uint32 **name_types){        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;        uint32 i, total_names = 0;        POLICY_HND dom_pol, group_pol;        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;	uint32 *rid_mem = NULL;	uint32 group_rid;	unsigned int j;	fstring sid_string;	struct rpc_pipe_client *cli;	DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,		  sid_to_string(sid_string, group_sid)));	if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))		return NT_STATUS_UNSUCCESSFUL;	*num_names = 0;	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);	if (!NT_STATUS_IS_OK(result))		return result;        result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,					des_access, group_rid, &group_pol);        if (!NT_STATUS_IS_OK(result))		return result;        /* Step #1: Get a list of user rids that are the members of the           group. */        result = rpccli_samr_query_groupmem(cli, mem_ctx,					    &group_pol, num_names, &rid_mem,					    name_types);	rpccli_samr_close(cli, mem_ctx, &group_pol);        if (!NT_STATUS_IS_OK(result))		return result;	if (!*num_names) {		names = NULL;		name_types = NULL;		sid_mem = NULL;		return NT_STATUS_OK;	}        /* Step #2: Convert list of rids into list of usernames.  Do this           in bunches of ~1000 to avoid crashing NT4.  It looks like there           is a buffer overflow or something like that lurking around           somewhere. */#define MAX_LOOKUP_RIDS 900        *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);        *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);        *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);	for (j=0;j<(*num_names);j++)		sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);		if (*num_names>0 && (!*names || !*name_types))		return NT_STATUS_NO_MEMORY;        for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {                int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);                uint32 tmp_num_names = 0;                char **tmp_names = NULL;                uint32 *tmp_types = NULL;                /* Lookup a chunk of rids */                result = rpccli_samr_lookup_rids(cli, mem_ctx,						 &dom_pol,						 num_lookup_rids,						 &rid_mem[i],						 &tmp_num_names,						 &tmp_names, &tmp_types);		/* see if we have a real error (and yes the		   STATUS_SOME_UNMAPPED is the one returned from 2k) */		                if (!NT_STATUS_IS_OK(result) &&		    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))			return result;			                /* Copy result into array.  The talloc system will take                   care of freeing the temporary arrays later on. */                memcpy(&(*names)[i], tmp_names, sizeof(char *) *                        tmp_num_names);                memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *                       tmp_num_names);		                total_names += tmp_num_names;        }        *num_names = total_names;	return NT_STATUS_OK;}#ifdef HAVE_LDAP#include <ldap.h>static int get_ldap_seq(const char *server, int port, uint32 *seq){	int ret = -1;	struct timeval to;	const char *attrs[] = {"highestCommittedUSN", NULL};	LDAPMessage *res = NULL;	char **values = NULL;	LDAP *ldp = NULL;	*seq = DOM_SEQUENCE_NONE;	/*	 * Parameterised (5) second timeout on open. This is needed as the	 * search timeout doesn't seem to apply to doing an open as well. JRA.	 */	ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());	if (ldp == NULL)		return -1;	/* Timeout if no response within 20 seconds. */	to.tv_sec = 10;	to.tv_usec = 0;	if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",			   CONST_DISCARD(char **, attrs), 0, &to, &res))		goto done;	if (ldap_count_entries(ldp, res) != 1)		goto done;	values = ldap_get_values(ldp, res, "highestCommittedUSN");	if (!values || !values[0])		goto done;	*seq = atoi(values[0]);	ret = 0;  done:	if (values)		ldap_value_free(values);	if (res)		ldap_msgfree(res);	if (ldp)		ldap_unbind(ldp);	return ret;}/********************************************************************** Get the sequence number for a Windows AD native mode domain using LDAP queries**********************************************************************/static int get_ldap_sequence_number( const char* domain, uint32 *seq){	int ret = -1;	int i, port = LDAP_PORT;	struct ip_service *ip_list = NULL;	int count;		if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {		DEBUG(3, ("Could not look up dc's for domain %s\n", domain));		return False;	}	/* Finally return first DC that we can contact */	for (i = 0; i < count; i++) {		fstring ipstr;		/* since the is an LDAP lookup, default to the LDAP_PORT is		 * not set */		port = (ip_list[i].port!= PORT_NONE) ?			ip_list[i].port : LDAP_PORT;		fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );				if (is_zero_ip(ip_list[i].ip))			continue;		if ( (ret = get_ldap_seq( ipstr, port,  seq)) == 0 )			goto done;		/* add to failed connection cache */		add_failed_connection_entry( domain, ipstr,					     NT_STATUS_UNSUCCESSFUL );	}done:	if ( ret == 0 ) {		DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "			  "number for Domain (%s) from DC (%s:%d)\n", 			domain, inet_ntoa(ip_list[i].ip), port));	}	SAFE_FREE(ip_list);	return ret;}#endif /* HAVE_LDAP *//* find the sequence number for a domain */static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq){	TALLOC_CTX *mem_ctx;	SAM_UNK_CTR ctr;	NTSTATUS result;	POLICY_HND dom_pol;	BOOL got_seq_num = False;	int retry;	struct rpc_pipe_client *cli;	DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));	*seq = DOM_SEQUENCE_NONE;	if (!(mem_ctx = talloc_init("sequence_number[rpc]")))		return NT_STATUS_NO_MEMORY;	retry = 0;#ifdef HAVE_LDAP	if ( domain->native_mode ) 	{		int res;		DEBUG(8,("using get_ldap_seq() to retrieve the "			 "sequence number\n"));		res =  get_ldap_sequence_number( domain->name, seq );		if (res == 0)		{						result = NT_STATUS_OK;			DEBUG(10,("domain_sequence_number: LDAP for "				  "domain %s is %u\n",				  domain->name, *seq));			goto done;		}		DEBUG(10,("domain_sequence_number: failed to get LDAP "			  "sequence number for domain %s\n",			  domain->name ));	}#endif /* HAVE_LDAP */	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);	if (!NT_STATUS_IS_OK(result)) {		goto done;	}	/* Query domain info */	result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);	if (NT_STATUS_IS_OK(result)) {		*seq = ctr.info.inf8.seq_num.low;		got_seq_num = True;		goto seq_num;	}	/* retry with info-level 2 in case the dc does not support info-level 8	 * (like all older samba2 and samba3 dc's - Guenther */	result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);		if (NT_STATUS_IS_OK(result)) {		*seq = ctr.info.inf2.seq_num.low;		got_seq_num = True;	} seq_num:	if (got_seq_num) {		DEBUG(10,("domain_sequence_number: for domain %s is %u\n",			  domain->name, (unsigned)*seq));	} else {		DEBUG(10,("domain_sequence_number: failed to get sequence "			  "number (%u) for domain %s\n",			  (unsigned)*seq, domain->name ));	}  done:	talloc_destroy(mem_ctx);	return result;}/* get a list of trusted domains */static NTSTATUS trusted_domains(struct winbindd_domain *domain,				TALLOC_CTX *mem_ctx,				uint32 *num_domains,				char ***names,				char ***alt_names,				DOM_SID **dom_sids){	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;	uint32 enum_ctx = 0;	struct rpc_pipe_client *cli;	POLICY_HND lsa_policy;	DEBUG(3,("rpc: trusted_domains\n"));	*num_domains = 0;	*names = NULL;	*alt_names = NULL;	*dom_sids = NULL;	result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);	if (!NT_STATUS_IS_OK(result))		return result;	result = STATUS_MORE_ENTRIES;	while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {		uint32 start_idx, num;		char **tmp_names;		DOM_SID *tmp_sids;		int i;		result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,						   &lsa_policy, &enum_ctx,						   &num, &tmp_names,						   &tmp_sids);		if (!NT_STATUS_IS_OK(result) &&		    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))			break;		start_idx = *num_domains;		*num_domains += num;		*names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,					      char *, *num_domains);		*dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,						 DOM_SID, *num_domains);		*alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,						 char *, *num_domains);		if ((*names == NULL) || (*dom_sids == NULL) ||		    (*alt_names == NULL))			return NT_STATUS_NO_MEMORY;		for (i=0; i<num; i++) {			(*names)[start_idx+i] = tmp_names[i];			(*dom_sids)[start_idx+i] = tmp_sids[i];			(*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");		}	}	return result;}/* the rpc backend methods are exposed via this structure */struct winbindd_methods msrpc_methods = {	False,	query_user_list,	enum_dom_groups,	enum_local_groups,	msrpc_name_to_sid,	msrpc_sid_to_name,	query_user,	lookup_usergroups,	msrpc_lookup_useraliases,	lookup_groupmem,	sequence_number,	trusted_domains,};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?