diff options
Diffstat (limited to 'source3/nsswitch/winbindd_rpc.c')
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 1111 |
1 files changed, 0 insertions, 1111 deletions
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c deleted file mode 100644 index 6d2dd35080..0000000000 --- a/source3/nsswitch/winbindd_rpc.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind rpc backend functions - - Copyright (C) Tim Potter 2000-2001,2003 - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Volker Lendecke 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "winbindd.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_WINBIND - - -/* Query display info for a domain. This returns enough information plus a - bit extra to give an overview of domain users for the User Manager - application. */ -static NTSTATUS query_user_list(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_entries, - WINBIND_USERINFO **info) -{ - NTSTATUS result; - POLICY_HND dom_pol; - unsigned int i, start_idx; - uint32 loop_count; - struct rpc_pipe_client *cli; - - DEBUG(3,("rpc: query_user_list\n")); - - *num_entries = 0; - *info = NULL; - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("query_user_list: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) - return result; - - i = start_idx = 0; - loop_count = 0; - - do { - uint32 num_dom_users, j; - uint32 max_entries, max_size; - SAM_DISPINFO_CTR ctr; - SAM_DISPINFO_1 info1; - - ZERO_STRUCT( ctr ); - ZERO_STRUCT( info1 ); - ctr.sam.info1 = &info1; - - /* this next bit is copied from net_user_list_internal() */ - - get_query_dispinfo_params(loop_count, &max_entries, - &max_size); - - result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol, - &start_idx, 1, - &num_dom_users, - max_entries, max_size, - &ctr); - - loop_count++; - - *num_entries += num_dom_users; - - *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO, - *num_entries); - - if (!(*info)) { - return NT_STATUS_NO_MEMORY; - } - - for (j = 0; j < num_dom_users; i++, j++) { - fstring username, fullname; - uint32 rid = ctr.sam.info1->sam[j].rid_user; - - unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1); - unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1); - - (*info)[i].acct_name = talloc_strdup(mem_ctx, username ); - (*info)[i].full_name = talloc_strdup(mem_ctx, fullname ); - (*info)[i].homedir = NULL; - (*info)[i].shell = NULL; - sid_compose(&(*info)[i].user_sid, &domain->sid, rid); - - /* For the moment we set the primary group for - every user to be the Domain Users group. - There are serious problems with determining - the actual primary group for large domains. - This should really be made into a 'winbind - force group' smb.conf parameter or - something like that. */ - - sid_compose(&(*info)[i].group_sid, &domain->sid, - DOMAIN_GROUP_RID_USERS); - } - - } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - - return result; -} - -/* list all domain groups */ -static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_entries, - struct acct_info **info) -{ - POLICY_HND dom_pol; - NTSTATUS status; - uint32 start = 0; - struct rpc_pipe_client *cli; - - *num_entries = 0; - *info = NULL; - - DEBUG(3,("rpc: enum_dom_groups\n")); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(status)) - return status; - - do { - struct acct_info *info2 = NULL; - uint32 count = 0; - TALLOC_CTX *mem_ctx2; - - mem_ctx2 = talloc_init("enum_dom_groups[rpc]"); - - /* start is updated by this call. */ - status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol, - &start, - 0xFFFF, /* buffer size? */ - &info2, &count); - - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - talloc_destroy(mem_ctx2); - break; - } - - (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, - struct acct_info, - (*num_entries) + count); - if (! *info) { - talloc_destroy(mem_ctx2); - return NT_STATUS_NO_MEMORY; - } - - memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2)); - (*num_entries) += count; - talloc_destroy(mem_ctx2); - } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); - - return NT_STATUS_OK; -} - -/* List all domain groups */ - -static NTSTATUS enum_local_groups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_entries, - struct acct_info **info) -{ - POLICY_HND dom_pol; - NTSTATUS result; - struct rpc_pipe_client *cli; - - *num_entries = 0; - *info = NULL; - - DEBUG(3,("rpc: enum_local_groups\n")); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) - return result; - - do { - struct acct_info *info2 = NULL; - uint32 count = 0, start = *num_entries; - TALLOC_CTX *mem_ctx2; - - mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]"); - - result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol, - &start, 0xFFFF, &info2, - &count); - - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) - { - talloc_destroy(mem_ctx2); - return result; - } - - (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, - struct acct_info, - (*num_entries) + count); - if (! *info) { - talloc_destroy(mem_ctx2); - return NT_STATUS_NO_MEMORY; - } - - memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2)); - (*num_entries) += count; - talloc_destroy(mem_ctx2); - - } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - - return NT_STATUS_OK; -} - -/* convert a single name to a sid in a domain */ -NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - enum winbindd_cmd original_cmd, - const char *domain_name, - const char *name, - DOM_SID *sid, - enum lsa_SidType *type) -{ - NTSTATUS result; - DOM_SID *sids = NULL; - enum lsa_SidType *types = NULL; - char *full_name = NULL; - struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; - - if (name == NULL || *name=='\0') { - full_name = talloc_asprintf(mem_ctx, "%s", domain_name); - } else if (domain_name == NULL || *domain_name == '\0') { - full_name = talloc_asprintf(mem_ctx, "%s", name); - } else { - 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,("rpc: name_to_sid name=%s\n", full_name)); - - ws_name_return( full_name, WB_REPLACE_CHAR ); - - DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name )); - - result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); - if (!NT_STATUS_IS_OK(result)) - return result; - - result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1, - (const char**) &full_name, NULL, 1, &sids, &types); - - if (!NT_STATUS_IS_OK(result)) - return result; - - /* Return rid and type if lookup successful */ - - sid_copy(sid, &sids[0]); - *type = types[0]; - - return NT_STATUS_OK; -} - -/* - convert a domain SID to a user or group name -*/ -NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *sid, - char **domain_name, - char **name, - enum lsa_SidType *type) -{ - char **domains; - char **names; - enum lsa_SidType *types; - NTSTATUS result; - struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; - - DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid), - domain->name )); - - result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n", - nt_errstr(result))); - return result; - } - - - result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy, - 1, sid, &domains, &names, &types); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n", - nt_errstr(result))); - return result; - } - - *type = (enum lsa_SidType)types[0]; - *domain_name = domains[0]; - *name = names[0]; - - ws_name_replace( *name, WB_REPLACE_CHAR ); - - DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name)); - return NT_STATUS_OK; -} - -NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *sid, - uint32 *rids, - size_t num_rids, - char **domain_name, - char ***names, - enum lsa_SidType **types) -{ - char **domains; - NTSTATUS result; - struct rpc_pipe_client *cli; - POLICY_HND lsa_policy; - DOM_SID *sids; - size_t i; - char **ret_names; - - DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name )); - - if (num_rids) { - sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids); - if (sids == NULL) { - return NT_STATUS_NO_MEMORY; - } - } else { - sids = NULL; - } - - for (i=0; i<num_rids; i++) { - if (!sid_compose(&sids[i], sid, rids[i])) { - return NT_STATUS_INTERNAL_ERROR; - } - } - - result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); - if (!NT_STATUS_IS_OK(result)) { - return result; - } - - result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy, - num_rids, sids, &domains, - names, types); - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { - return result; - } - - ret_names = *names; - for (i=0; i<num_rids; i++) { - if ((*types)[i] != SID_NAME_UNKNOWN) { - ws_name_replace( ret_names[i], WB_REPLACE_CHAR ); - *domain_name = domains[i]; - } - } - - return result; -} - -/* Lookup user information from a rid or username. */ -static NTSTATUS query_user(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *user_sid, - WINBIND_USERINFO *user_info) -{ - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol, user_pol; - SAM_USERINFO_CTR *ctr; - fstring sid_string; - uint32 user_rid; - NET_USER_INFO_3 *user; - struct rpc_pipe_client *cli; - - DEBUG(3,("rpc: query_user sid=%s\n", - sid_to_string(sid_string, user_sid))); - - if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) - return NT_STATUS_UNSUCCESSFUL; - - user_info->homedir = NULL; - user_info->shell = NULL; - user_info->primary_gid = (gid_t)-1; - - /* try netsamlogon cache first */ - - if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) - { - - DEBUG(5,("query_user: Cache lookup succeeded for %s\n", - sid_string_static(user_sid))); - - sid_compose(&user_info->user_sid, &domain->sid, user->user_rid); - sid_compose(&user_info->group_sid, &domain->sid, - user->group_rid); - - user_info->acct_name = unistr2_tdup(mem_ctx, - &user->uni_user_name); - user_info->full_name = unistr2_tdup(mem_ctx, - &user->uni_full_name); - - TALLOC_FREE(user); - - return NT_STATUS_OK; - } - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("query_user: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("query_user: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - /* no cache; hit the wire */ - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) - return result; - - /* Get user handle */ - result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, - &user_pol); - - if (!NT_STATUS_IS_OK(result)) - return result; - - /* Get user info */ - result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol, - 0x15, &ctr); - - rpccli_samr_close(cli, mem_ctx, &user_pol); - - if (!NT_STATUS_IS_OK(result)) - return result; - - sid_compose(&user_info->user_sid, &domain->sid, user_rid); - sid_compose(&user_info->group_sid, &domain->sid, - ctr->info.id21->group_rid); - user_info->acct_name = unistr2_tdup(mem_ctx, - &ctr->info.id21->uni_user_name); - user_info->full_name = unistr2_tdup(mem_ctx, - &ctr->info.id21->uni_full_name); - user_info->homedir = NULL; - user_info->shell = NULL; - user_info->primary_gid = (gid_t)-1; - - return NT_STATUS_OK; -} - -/* Lookup groups a user is a member of. I wish Unix had a call like this! */ -static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *user_sid, - uint32 *num_groups, DOM_SID **user_grpsids) -{ - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol, user_pol; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - DOM_GID *user_groups; - unsigned int i; - fstring sid_string; - uint32 user_rid; - struct rpc_pipe_client *cli; - - DEBUG(3,("rpc: lookup_usergroups sid=%s\n", - sid_to_string(sid_string, user_sid))); - - if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) - return NT_STATUS_UNSUCCESSFUL; - - *num_groups = 0; - *user_grpsids = NULL; - - /* so lets see if we have a cached user_info_3 */ - result = lookup_usergroups_cached(domain, mem_ctx, user_sid, - num_groups, user_grpsids); - - if (NT_STATUS_IS_OK(result)) { - return NT_STATUS_OK; - } - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n", - domain->name)); - - /* Tell the cache manager not to remember this one */ - - return NT_STATUS_SYNCHRONIZATION_REQUIRED; - } - - /* no cache; hit the wire */ - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) - 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 *query_sids; - uint32 num_query_sids = 0; - int i; - struct rpc_pipe_client *cli; - uint32 *alias_rids_query, num_aliases_query; - int rangesize = MAX_SAM_ENTRIES_W2K; - uint32 total_sids = 0; - int num_queries = 1; - - *num_aliases = 0; - *alias_rids = NULL; - - DEBUG(3,("rpc: lookup_useraliases\n")); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) - return result; - - do { - /* prepare query */ - - num_query_sids = MIN(num_sids - total_sids, rangesize); - - DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", - num_queries, num_query_sids)); - - if (num_query_sids) { - query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids); - if (query_sids == NULL) { - return NT_STATUS_NO_MEMORY; - } - } else { - query_sids = NULL; - } - - for (i=0; i<num_query_sids; i++) { - sid_copy(&query_sids[i].sid, &sids[total_sids++]); - query_sids[i].num_auths = query_sids[i].sid.num_auths; - } - - /* do request */ - - result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol, - num_query_sids, query_sids, - &num_aliases_query, - &alias_rids_query); - - if (!NT_STATUS_IS_OK(result)) { - *num_aliases = 0; - *alias_rids = NULL; - TALLOC_FREE(query_sids); - goto done; - } - - /* process output */ - - for (i=0; i<num_aliases_query; i++) { - size_t na = *num_aliases; - if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i], - alias_rids, &na)) { - return NT_STATUS_NO_MEMORY; - } - *num_aliases = na; - } - - TALLOC_FREE(query_sids); - - num_queries++; - - } while (total_sids < num_sids); - - done: - DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries " - "(rangesize: %d)\n", *num_aliases, num_queries, rangesize)); - - 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; - unsigned int orig_timeout; - - DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, - sid_to_string(sid_string, group_sid))); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_OK; - } - - 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. */ - - /* This call can take a long time - allow the server to time out. - 35 seconds should do it. */ - - orig_timeout = cli_set_timeout(cli->cli, 35000); - - result = rpccli_samr_query_groupmem(cli, mem_ctx, - &group_pol, num_names, &rid_mem, - name_types); - - /* And restore our original timeout. */ - cli_set_timeout(cli->cli, orig_timeout); - - 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(struct winbindd_domain *domain, uint32 *seq) -{ - int ret = -1; - fstring ipstr; - - fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr)); - if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) { - DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence " - "number for Domain (%s) from DC (%s)\n", - domain->name, ipstr)); - } - 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; - struct rpc_pipe_client *cli; - - DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name)); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("sequence_number: No incoming trust for domain %s\n", - domain->name)); - *seq = time(NULL); - return NT_STATUS_OK; - } - - *seq = DOM_SEQUENCE_NONE; - - if (!(mem_ctx = talloc_init("sequence_number[rpc]"))) - return NT_STATUS_NO_MEMORY; - -#ifdef HAVE_LDAP - if ( domain->active_directory ) - { - int res; - - DEBUG(8,("using get_ldap_seq() to retrieve the " - "sequence number\n")); - - res = get_ldap_sequence_number( domain, 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; - 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; - 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; -} - -/* find the lockout policy for a domain */ -NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - SAM_UNK_INFO_12 *lockout_policy) -{ - NTSTATUS result; - struct rpc_pipe_client *cli; - POLICY_HND dom_pol; - SAM_UNK_CTR ctr; - - DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name)); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_NOT_SUPPORTED; - } - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *lockout_policy = ctr.info.inf12; - - DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n", - ctr.info.inf12.bad_attempt_lockout)); - - done: - - return result; -} - -/* find the password policy for a domain */ -NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - SAM_UNK_INFO_1 *password_policy) -{ - NTSTATUS result; - struct rpc_pipe_client *cli; - POLICY_HND dom_pol; - SAM_UNK_CTR ctr; - - DEBUG(10,("rpc: fetch password policy for %s\n", domain->name)); - - if ( !winbindd_can_contact_domain( domain ) ) { - DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n", - domain->name)); - return NT_STATUS_NOT_SUPPORTED; - } - - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *password_policy = ctr.info.inf1; - - DEBUG(10,("msrpc_password_policy: min_length_password %d\n", - ctr.info.inf1.min_length_password)); - - done: - - 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, - msrpc_rids_to_names, - query_user, - lookup_usergroups, - msrpc_lookup_useraliases, - lookup_groupmem, - sequence_number, - msrpc_lockout_policy, - msrpc_password_policy, - trusted_domains, -}; |