Copyright (C) Andrew Tridgell 2001
Copyright (C) Volker Lendecke 2005
Copyright (C) Guenther Deschner 2008 (pidl conversion)
-
+
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/>.
*/
static NTSTATUS query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_entries,
- WINBIND_USERINFO **info)
+ struct wbint_userinfo **info)
{
NTSTATUS result;
- POLICY_HND dom_pol;
+ struct policy_handle dom_pol;
unsigned int i, start_idx;
uint32 loop_count;
struct rpc_pipe_client *cli;
*num_entries += num_dom_users;
- *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
+ *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
+ struct wbint_userinfo,
*num_entries);
if (!(*info)) {
(*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
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);
}
uint32 *num_entries,
struct acct_info **info)
{
- POLICY_HND dom_pol;
+ struct policy_handle dom_pol;
NTSTATUS status;
uint32 start = 0;
struct rpc_pipe_client *cli;
uint32 *num_entries,
struct acct_info **info)
{
- POLICY_HND dom_pol;
+ struct policy_handle dom_pol;
NTSTATUS result;
struct rpc_pipe_client *cli;
}
/* 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)
+static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const char *domain_name,
+ const char *name,
+ uint32_t flags,
+ 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;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
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);
-
+ result = winbindd_lookup_names(mem_ctx, domain, 1,
+ (const char **)&full_name, NULL,
+ &sids, &types);
if (!NT_STATUS_IS_OK(result))
return result;
/*
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)
+static 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 = NULL;
NTSTATUS result;
- struct rpc_pipe_client *cli;
- POLICY_HND lsa_policy;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
domain->name ));
- result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+ result = winbindd_lookup_sids(mem_ctx,
+ domain,
+ 1,
+ sid,
+ &domains,
+ &names,
+ &types);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
- nt_errstr(result)));
+ DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %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];
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)
+static 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;
}
}
- result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
- if (!NT_STATUS_IS_OK(result)) {
- return result;
- }
+ result = winbindd_lookup_sids(mem_ctx,
+ domain,
+ num_rids,
+ sids,
+ &domains,
+ names,
+ types);
- 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;
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
- WINBIND_USERINFO *user_info)
+ struct wbint_userinfo *user_info)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND dom_pol, user_pol;
+ struct policy_handle dom_pol, user_pol;
union samr_UserInfo *info = NULL;
uint32 user_rid;
struct netr_SamInfo3 *user;
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_dbg(user_sid)));
sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
sid_compose(&user_info->group_sid, &domain->sid,
user->base.primary_gid);
-
+
user_info->acct_name = talloc_strdup(mem_ctx,
user->base.account_name.string);
user_info->full_name = talloc_strdup(mem_ctx,
user->base.full_name.string);
-
+
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;
}
-
+
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_OpenUser(cli, mem_ctx,
&dom_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
+ SEC_FLAG_MAXIMUM_ALLOWED,
user_rid,
&user_pol);
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;
+ struct policy_handle dom_pol, user_pol;
+ uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
struct samr_RidWithAttributeArray *rid_array = NULL;
unsigned int i;
uint32 user_rid;
}
/* no cache; hit the wire */
-
+
result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
if (!NT_STATUS_IS_OK(result))
return result;
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)
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+
+static 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;
+ struct policy_handle dom_pol;
uint32 num_query_sids = 0;
int i;
struct rpc_pipe_client *cli;
/* 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,
+ const DOM_SID *group_sid,
+ enum lsa_SidType type,
+ 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;
+ struct policy_handle dom_pol, group_pol;
+ uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
uint32 *rid_mem = NULL;
uint32 group_rid;
unsigned int j, r;
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 (r=0; r<tmp_names.count; r++) {
- (*names)[i+r] = CONST_DISCARD(char *, tmp_names.names[r].string);
- (*name_types)[i+r] = tmp_types.ids[r];
+ if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
+ continue;
+ }
+ (*names)[total_names] = fill_domain_username_talloc(
+ mem_ctx, domain->name,
+ tmp_names.names[r].string, true);
+ (*name_types)[total_names] = tmp_types.ids[r];
+ total_names += 1;
}
-
- total_names += tmp_names.count;
}
*num_names = total_names;
TALLOC_CTX *mem_ctx;
union samr_DomainInfo *info = NULL;
NTSTATUS result;
- POLICY_HND dom_pol;
+ struct policy_handle dom_pol;
bool got_seq_num = False;
struct rpc_pipe_client *cli;
&info);
if (NT_STATUS_IS_OK(result)) {
- *seq = info->info2.sequence_num;
+ *seq = info->general.sequence_num;
got_seq_num = True;
}
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 enum_ctx = 0;
struct rpc_pipe_client *cli;
- POLICY_HND lsa_policy;
+ struct policy_handle lsa_policy;
DEBUG(3,("rpc: trusted_domains\n"));
}
/* find the lockout policy for a domain */
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo12 *lockout_policy)
+static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo12 *lockout_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
- POLICY_HND dom_pol;
+ struct policy_handle dom_pol;
union samr_DomainInfo *info = NULL;
DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
}
/* find the password policy for a domain */
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo1 *password_policy)
+static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo1 *password_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
- POLICY_HND dom_pol;
+ struct policy_handle dom_pol;
union samr_DomainInfo *info = NULL;
DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
return result;
}
+typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *pol,
+ int num_sids,
+ const DOM_SID *sids,
+ char ***pdomains,
+ char ***pnames,
+ enum lsa_SidType **ptypes);
+
+NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
+ struct winbindd_domain *domain,
+ uint32_t num_sids,
+ const struct dom_sid *sids,
+ char ***domains,
+ char ***names,
+ enum lsa_SidType **types)
+{
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle lsa_policy;
+ unsigned int orig_timeout;
+ lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
+
+ if (domain->can_do_ncacn_ip_tcp) {
+ status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
+ if (NT_STATUS_IS_OK(status)) {
+ lookup_sids_fn = rpccli_lsa_lookup_sids3;
+ goto lookup;
+ }
+ domain->can_do_ncacn_ip_tcp = false;
+ }
+ status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ lookup:
+ /*
+ * This call can take a long time
+ * allow the server to time out.
+ * 35 seconds should do it.
+ */
+ orig_timeout = rpccli_set_timeout(cli, 35000);
+
+ status = lookup_sids_fn(cli,
+ mem_ctx,
+ &lsa_policy,
+ num_sids,
+ sids,
+ domains,
+ names,
+ types);
+
+ /* And restore our original timeout. */
+ rpccli_set_timeout(cli, orig_timeout);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return status;
+}
+
+typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *pol,
+ int num_names,
+ const char **names,
+ const char ***dom_names,
+ int level,
+ struct dom_sid **sids,
+ enum lsa_SidType **types);
+
+NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
+ struct winbindd_domain *domain,
+ uint32_t num_names,
+ const char **names,
+ const char ***domains,
+ struct dom_sid **sids,
+ enum lsa_SidType **types)
+{
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle lsa_policy;
+ unsigned int orig_timeout;
+ lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
+
+ if (domain->can_do_ncacn_ip_tcp) {
+ status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
+ if (NT_STATUS_IS_OK(status)) {
+ lookup_names_fn = rpccli_lsa_lookup_names4;
+ goto lookup;
+ }
+ domain->can_do_ncacn_ip_tcp = false;
+ }
+ status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ lookup:
+
+ /*
+ * This call can take a long time
+ * allow the server to time out.
+ * 35 seconds should do it.
+ */
+ orig_timeout = rpccli_set_timeout(cli, 35000);
+
+ status = lookup_names_fn(cli,
+ mem_ctx,
+ &lsa_policy,
+ num_names,
+ (const char **) names,
+ domains,
+ 1,
+ sids,
+ types);
+
+ /* And restore our original timeout. */
+ rpccli_set_timeout(cli, orig_timeout);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return status;
+}
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods msrpc_methods = {