1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

The beginnings of alternative backends for winbindd

This just splits off the dispinfo call behind a methods structure.
I'll split off a few more functions soon, then we will be ready for
LDAP replacement methods
(This used to be commit 0216b0fca1)
This commit is contained in:
Andrew Tridgell 2001-12-01 12:31:43 +00:00
parent c5f4a4b9ad
commit de744cb970
7 changed files with 112 additions and 67 deletions

View File

@ -1,4 +1,4 @@
/* include/config.h.in. Generated automatically from configure.in by autoheader. */
/* include/config.h.in. Generated automatically from configure.in by autoheader 2.13. */
/* Define if on AIX 3.
System headers sometimes define this.

View File

@ -164,6 +164,23 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
}
/*******************************************************************
duplicate a UNISTR2 string into a null terminated char*
using a talloc context
********************************************************************/
char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
{
char *s;
int maxlen = (str->uni_str_len+1)*4;
if (!str->buffer) return NULL;
s = (char *)talloc(ctx, maxlen); /* convervative */
if (!s) return NULL;
pull_ucs2(NULL, s, str->buffer, maxlen, str->uni_str_len*2,
STR_NOALIGN);
return s;
}
/*******************************************************************
Return a number stored in a buffer
********************************************************************/

View File

@ -77,11 +77,33 @@ struct winbindd_state {
extern struct winbindd_state server_state; /* Server information */
/* Structures to hold per domain information */
typedef struct {
char *acct_name;
char *full_name;
uint32 user_rid;
uint32 group_rid; /* primary group */
} WINBIND_DISPINFO;
/* per-domain methods. This is how LDAP vs RPC is selected
This will eventually be the sole entry point to all the methods,
I'm just starting small
*/
struct winbindd_methods {
NTSTATUS (*query_dispinfo)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *start_ndx, uint32 *num_entries,
WINBIND_DISPINFO **info);
};
/* Structures to hold per domain information */
struct winbindd_domain {
fstring name; /* Domain name */
DOM_SID sid; /* SID for this domain */
struct winbindd_methods *methods; /* lookup methods for
this domain (LDAP or
RPC) */
struct winbindd_domain *prev, *next; /* Linked list info */
};

View File

@ -73,7 +73,7 @@ struct winbindd_cm_conn {
POLICY_HND pol;
};
struct winbindd_cm_conn *cm_conns = NULL;
static struct winbindd_cm_conn *cm_conns = NULL;
/* Get a domain controller name. Cache positive and negative lookups so we
don't go to the network too often when something is badly broken. */

View File

@ -152,8 +152,8 @@ void free_getent_state(struct getent_state *state);
BOOL winbindd_param_init(void);
NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *start_ndx, uint16 info_level,
uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
uint32 *start_ndx, uint32 *num_entries,
WINBIND_DISPINFO **info);
BOOL check_domain_env(char *domain_env, char *domain);
void parse_domain_user(char *domuser, fstring domain, fstring user);
#endif /* _PROTO_H_ */

View File

@ -377,12 +377,11 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
{
NTSTATUS status;
uint32 num_entries;
SAM_DISPINFO_1 info1;
SAM_DISPINFO_CTR ctr;
WINBIND_DISPINFO *info;
struct getpwent_user *name_list = NULL;
uint32 group_rid;
BOOL result = False;
TALLOC_CTX *mem_ctx;
struct winbindd_methods *methods;
if (ent->got_all_sam_entries)
return False;
@ -390,10 +389,7 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
if (!(mem_ctx = talloc_init()))
return False;
ZERO_STRUCT(info1);
ZERO_STRUCT(ctr);
ctr.sam.info1 = &info1;
methods = ent->domain->methods;
#if 0
/* Look in cache for entries, else get them direct */
@ -406,14 +402,6 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
}
#endif
/* 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. */
group_rid = DOMAIN_GROUP_RID_USERS;
/* Free any existing user info */
SAFE_FREE(ent->sam_entries);
@ -426,9 +414,9 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
num_entries = 0;
status = winbindd_query_dispinfo(ent->domain, mem_ctx,
&ent->dispinfo_ndx, 1,
&num_entries, &ctr);
status = methods->query_dispinfo(ent->domain, mem_ctx,
&ent->dispinfo_ndx,
&num_entries, &info);
if (num_entries) {
struct getpwent_user *tnl;
@ -447,26 +435,23 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
}
for (i = 0; i < num_entries; i++) {
/* Store account name and gecos */
unistr2_to_ascii(
name_list[ent->num_sam_entries + i].name,
&info1.str[i].uni_acct_name,
sizeof(fstring));
unistr2_to_ascii(
name_list[ent->num_sam_entries + i].gecos,
&info1.str[i].uni_full_name,
sizeof(fstring));
if (!info[i].acct_name) {
fstrcpy(name_list[ent->num_sam_entries + i].name, "");
} else {
fstrcpy(name_list[ent->num_sam_entries + i].name,
info[i].acct_name);
}
if (!info[i].full_name) {
fstrcpy(name_list[ent->num_sam_entries + i].gecos, "");
} else {
fstrcpy(name_list[ent->num_sam_entries + i].gecos,
info[i].full_name);
}
/* User and group ids */
name_list[ent->num_sam_entries + i].user_rid =
info1.sam[i].rid_user;
name_list[ent->num_sam_entries + i].
group_rid = group_rid;
name_list[ent->num_sam_entries+i].user_rid = info[i].user_rid;
name_list[ent->num_sam_entries+i].group_rid = info[i].group_rid;
}
ent->num_sam_entries += num_entries;
@ -615,8 +600,7 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
SAM_DISPINFO_CTR ctr;
SAM_DISPINFO_1 info1;
WINBIND_DISPINFO *info;
uint32 num_entries = 0, total_entries = 0;
char *ted, *extra_data = NULL;
int extra_data_len = 0;
@ -630,14 +614,13 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
/* Enumerate over trusted domains */
ctr.sam.info1 = &info1;
if (domain_list == NULL)
get_domain_info();
for (domain = domain_list; domain; domain = domain->next) {
NTSTATUS status;
uint32 start_ndx = 0;
struct winbindd_methods *methods;
/* Skip domains other than WINBINDD_DOMAIN environment
variable */
@ -646,20 +629,20 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
!check_domain_env(state->request.domain, domain->name))
continue;
methods = domain->methods;
/* Query display info */
do {
int i;
status = winbindd_query_dispinfo(
domain, mem_ctx, &start_ndx,
1, &num_entries, &ctr);
status = methods->query_dispinfo(domain, mem_ctx, &start_ndx,
&num_entries, &info);
if (num_entries == 0)
continue;
/* Allocate some memory for extra data */
total_entries += num_entries;
ted = Realloc(extra_data, sizeof(fstring) *
@ -675,26 +658,22 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
/* Pack user list into extra data fields */
for (i = 0; i < num_entries; i++) {
UNISTR2 *uni_acct_name;
fstring acct_name, name;
/* Convert unistring to ascii */
uni_acct_name = &ctr.sam.info1->str[i].
uni_acct_name;
unistr2_to_ascii(acct_name, uni_acct_name,
sizeof(acct_name) - 1);
if (!info[i].acct_name) {
fstrcpy(acct_name, "");
} else {
fstrcpy(acct_name, info[i].acct_name);
}
slprintf(name, sizeof(name) - 1, "%s%s%s",
domain->name, lp_winbind_separator(),
acct_name);
/* Append to extra data */
memcpy(&extra_data[extra_data_len], name,
strlen(name));
extra_data_len += strlen(name);
extra_data[extra_data_len++] = ',';
}
} while (NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES));

View File

@ -40,9 +40,12 @@ static const fstring name_deadbeef = "<deadbeef>";
/* Globals for domain list stuff */
struct winbindd_domain *domain_list = NULL;
static struct winbindd_methods msrpc_methods = {
winbindd_query_dispinfo
};
/* Given a domain name, return the struct winbindd domain info for it
if it is actually working. */
@ -89,7 +92,8 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
/* Add a trusted domain to our list of domains */
static struct winbindd_domain *add_trusted_domain(char *domain_name,
DOM_SID *domain_sid)
DOM_SID *domain_sid,
struct winbindd_methods *methods)
{
struct winbindd_domain *domain, *tmp;
@ -112,7 +116,8 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
ZERO_STRUCTP(domain);
fstrcpy(domain->name, domain_name);
sid_copy(&domain->sid, domain_sid);
domain->methods = methods;
/* Link to domain list */
DLIST_ADD(domain_list, domain);
@ -150,7 +155,7 @@ BOOL get_domain_info(void)
if (!NT_STATUS_IS_OK(result))
goto done;
add_trusted_domain(lp_workgroup(), &domain_sid);
add_trusted_domain(lp_workgroup(), &domain_sid, &msrpc_methods);
/* Enumerate list of trusted domains */
@ -166,7 +171,7 @@ BOOL get_domain_info(void)
/* Add each domain to the trusted domain list */
for(i = 0; i < num_doms; i++)
add_trusted_domain(domains[i], &sids[i]);
add_trusted_domain(domains[i], &sids[i], &msrpc_methods);
rv = True;
@ -790,14 +795,17 @@ BOOL winbindd_param_init(void)
NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *start_ndx, uint16 info_level,
uint32 *num_entries, SAM_DISPINFO_CTR *ctr)
uint32 *start_ndx, uint32 *num_entries,
WINBIND_DISPINFO **info)
{
CLI_POLICY_HND *hnd;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND dom_pol;
BOOL got_dom_pol = False;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
SAM_DISPINFO_CTR ctr;
SAM_DISPINFO_1 info1;
int i;
/* Get sam handle */
@ -814,11 +822,30 @@ NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
got_dom_pol = True;
/* Query display info */
ctr.sam.info1 = &info1;
/* Query display info level 1 */
result = cli_samr_query_dispinfo(hnd->cli, mem_ctx,
&dom_pol, start_ndx, info_level,
num_entries, 0xffff, ctr);
&dom_pol, start_ndx, 1,
num_entries, 0xffff, &ctr);
/* now map the result into the WINBIND_DISPINFO structure */
(*info) = (WINBIND_DISPINFO *)talloc(mem_ctx, (*num_entries)*sizeof(WINBIND_DISPINFO));
if (!(*info)) {
return NT_STATUS_NO_MEMORY;
}
for (i=0;i<*num_entries;i++) {
(*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[i].uni_acct_name);
(*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[i].uni_full_name);
(*info)[i].user_rid = info1.sam[i].rid_user;
/* 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. */
(*info)[i].group_rid = DOMAIN_GROUP_RID_USERS;
}
done: