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 + -
显示快捷键?