mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
r6351: This is quite a large and intrusive patch, but there are not many pieces that
can be taken out of it, so I decided to commit this in one lump. It changes the passdb enumerating functions to use ldap paged results where possible. In particular the samr calls querydispinfo, enumdomusers and friends have undergone significant internal changes. I have tested this extensively with rpcclient and a bit with usrmgr.exe. More tests and the merge to trunk will follow later. The code is based on a first implementation by Günther Deschner, but has evolved quite a bit since then. Volker (This used to be commit f0bb44ac58e190e19eb4e92928979b0446e611c9)
This commit is contained in:
parent
496c6f0884
commit
d3d6126d94
@ -1247,53 +1247,6 @@ NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
|
||||
NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
|
||||
const DOM_SID *sid,
|
||||
uint32 start_idx, uint32 max_entries,
|
||||
uint32 *num_aliases,
|
||||
struct acct_info **info)
|
||||
{
|
||||
GROUP_MAP *map;
|
||||
int i, num_maps;
|
||||
enum SID_NAME_USE type = SID_NAME_UNKNOWN;
|
||||
|
||||
if (sid_compare(sid, get_global_sam_sid()) == 0)
|
||||
type = SID_NAME_ALIAS;
|
||||
|
||||
if (sid_compare(sid, &global_sid_Builtin) == 0)
|
||||
type = SID_NAME_WKN_GRP;
|
||||
|
||||
if (!pdb_enum_group_mapping(type, &map, &num_maps, False) ||
|
||||
(num_maps == 0)) {
|
||||
*num_aliases = 0;
|
||||
*info = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (start_idx > num_maps) {
|
||||
*num_aliases = 0;
|
||||
*info = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*num_aliases = num_maps - start_idx;
|
||||
|
||||
if (*num_aliases > max_entries)
|
||||
*num_aliases = max_entries;
|
||||
|
||||
*info = SMB_MALLOC_ARRAY(struct acct_info, *num_aliases);
|
||||
|
||||
for (i=0; i<*num_aliases; i++) {
|
||||
fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name);
|
||||
fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment);
|
||||
sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid);
|
||||
}
|
||||
|
||||
done:
|
||||
SAFE_FREE(map);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
|
||||
const DOM_SID *sid,
|
||||
struct acct_info *info)
|
||||
|
@ -232,6 +232,30 @@ struct acct_info
|
||||
uint32 rid; /* domain-relative RID */
|
||||
};
|
||||
|
||||
struct samr_displayentry {
|
||||
uint32 rid;
|
||||
uint16 acct_flags;
|
||||
const char *account_name;
|
||||
const char *fullname;
|
||||
const char *description;
|
||||
};
|
||||
|
||||
enum pdb_search_type {
|
||||
PDB_USER_SEARCH,
|
||||
PDB_GROUP_SEARCH,
|
||||
PDB_ALIAS_SEARCH
|
||||
};
|
||||
|
||||
struct pdb_search {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
enum pdb_search_type type;
|
||||
struct samr_displayentry *cache;
|
||||
uint32 num_entries;
|
||||
ssize_t cache_size;
|
||||
BOOL search_ended;
|
||||
void *private;
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
Functions to be implemented by the new (v2) passdb API
|
||||
****************************************************************/
|
||||
@ -310,12 +334,6 @@ typedef struct pdb_context
|
||||
NTSTATUS (*pdb_delete_alias)(struct pdb_context *context,
|
||||
const DOM_SID *sid);
|
||||
|
||||
NTSTATUS (*pdb_enum_aliases)(struct pdb_context *context,
|
||||
const DOM_SID *domain_sid,
|
||||
uint32 start_idx, uint32 num_entries,
|
||||
uint32 *num_aliases,
|
||||
struct acct_info **aliases);
|
||||
|
||||
NTSTATUS (*pdb_get_aliasinfo)(struct pdb_context *context,
|
||||
const DOM_SID *sid,
|
||||
struct acct_info *info);
|
||||
@ -352,6 +370,20 @@ typedef struct pdb_context
|
||||
const char ***names,
|
||||
uint32 **attrs);
|
||||
|
||||
BOOL (*pdb_search_users)(struct pdb_context *context,
|
||||
struct pdb_search *search,
|
||||
uint16 acct_flags);
|
||||
BOOL (*pdb_search_groups)(struct pdb_context *context,
|
||||
struct pdb_search *search);
|
||||
BOOL (*pdb_search_aliases)(struct pdb_context *context,
|
||||
struct pdb_search *search,
|
||||
const DOM_SID *sid);
|
||||
BOOL (*pdb_search_next_entry)(struct pdb_context *context,
|
||||
struct pdb_search *search,
|
||||
struct samr_displayentry *entry);
|
||||
void (*pdb_search_end)(struct pdb_context *context,
|
||||
struct pdb_search *search);
|
||||
|
||||
void (*free_fn)(struct pdb_context **);
|
||||
|
||||
TALLOC_CTX *mem_ctx;
|
||||
@ -426,11 +458,6 @@ typedef struct pdb_methods
|
||||
NTSTATUS (*delete_alias)(struct pdb_methods *methods,
|
||||
const DOM_SID *sid);
|
||||
|
||||
NTSTATUS (*enum_aliases)(struct pdb_methods *methods,
|
||||
const DOM_SID *domain_sid,
|
||||
uint32 start_idx, uint32 max_entries,
|
||||
uint32 *num_aliases, struct acct_info **info);
|
||||
|
||||
NTSTATUS (*get_aliasinfo)(struct pdb_methods *methods,
|
||||
const DOM_SID *sid,
|
||||
struct acct_info *info);
|
||||
@ -461,6 +488,20 @@ typedef struct pdb_methods
|
||||
const char ***names,
|
||||
uint32 **attrs);
|
||||
|
||||
BOOL (*search_users)(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
uint16 acct_flags);
|
||||
BOOL (*search_groups)(struct pdb_methods *methods,
|
||||
struct pdb_search *search);
|
||||
BOOL (*search_aliases)(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
const DOM_SID *sid);
|
||||
BOOL (*search_next_entry)(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
struct samr_displayentry *entry);
|
||||
void (*search_end)(struct pdb_methods *methods,
|
||||
struct pdb_search *search);
|
||||
|
||||
void *private_data; /* Private data of some kind */
|
||||
|
||||
void (*free_private_data)(void **);
|
||||
@ -480,27 +521,4 @@ struct pdb_init_function_entry {
|
||||
|
||||
enum sql_search_field { SQL_SEARCH_NONE = 0, SQL_SEARCH_USER_SID = 1, SQL_SEARCH_USER_NAME = 2};
|
||||
|
||||
struct samr_displayentry {
|
||||
uint32 rid;
|
||||
uint16 acct_flags;
|
||||
const char *account_name;
|
||||
const char *fullname;
|
||||
const char *description;
|
||||
};
|
||||
|
||||
enum pdb_search_type {
|
||||
PDB_USER_SEARCH,
|
||||
PDB_GROUP_SEARCH,
|
||||
PDB_ALIAS_SEARCH
|
||||
};
|
||||
|
||||
struct pdb_search {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
enum pdb_search_type type;
|
||||
struct samr_displayentry *cache;
|
||||
uint32 cache_size;
|
||||
BOOL search_ended;
|
||||
void *private;
|
||||
};
|
||||
|
||||
#endif /* _PASSDB_H */
|
||||
|
@ -362,4 +362,7 @@ do { \
|
||||
(*(num)) += 1; \
|
||||
} while (0)
|
||||
|
||||
#define ADD_TO_LARGE_ARRAY(mem_ctx, type, elem, array, num, size) \
|
||||
add_to_large_array((mem_ctx), sizeof(type), &(elem), (void **)(array), (num), (size));
|
||||
|
||||
#endif /* _SMB_MACROS_H */
|
||||
|
@ -185,5 +185,6 @@ struct ldapsam_privates {
|
||||
struct smbldap_state;
|
||||
|
||||
#define LDAP_CONNECT_DEFAULT_TIMEOUT 15
|
||||
#define LDAP_PAGE_SIZE 1024
|
||||
|
||||
#endif /* _SMBLDAP_H */
|
||||
|
@ -856,6 +856,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
|
||||
}
|
||||
|
||||
ldap_state->num_failures = 0;
|
||||
ldap_state->paged_results = False;
|
||||
|
||||
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
|
||||
@ -864,7 +865,8 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
|
||||
}
|
||||
|
||||
DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
|
||||
DEBUGADD(3, ("ldap_connect_system: LDAP server %s support paged results\n", ldap_state->paged_results?"does":"does not"));
|
||||
DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
|
||||
ldap_state->paged_results ? "does" : "does not"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1022,20 +1024,22 @@ static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
|
||||
/*********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
int smbldap_search(struct smbldap_state *ldap_state,
|
||||
const char *base, int scope, const char *filter,
|
||||
const char *attrs[], int attrsonly,
|
||||
LDAPMessage **res)
|
||||
static int smbldap_search_ext(struct smbldap_state *ldap_state,
|
||||
const char *base, int scope, const char *filter,
|
||||
const char *attrs[], int attrsonly,
|
||||
LDAPControl **sctrls, LDAPControl **cctrls,
|
||||
int sizelimit, LDAPMessage **res)
|
||||
{
|
||||
int rc = LDAP_SERVER_DOWN;
|
||||
int attempts = 0;
|
||||
char *utf8_filter;
|
||||
time_t endtime = time(NULL)+lp_ldap_timeout();
|
||||
struct timeval timeout;
|
||||
|
||||
SMB_ASSERT(ldap_state);
|
||||
|
||||
DEBUG(5,("smbldap_search: base => [%s], filter => [%s], scope => [%d]\n",
|
||||
base, filter, scope));
|
||||
DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
|
||||
"scope => [%d]\n", base, filter, scope));
|
||||
|
||||
if (ldap_state->last_rebind.tv_sec > 0) {
|
||||
struct timeval tval;
|
||||
@ -1053,9 +1057,10 @@ int smbldap_search(struct smbldap_state *ldap_state,
|
||||
|
||||
if (sleep_time > 0) {
|
||||
/* we wait for the LDAP replication */
|
||||
DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time));
|
||||
DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
|
||||
"for LDAP replication.\n",sleep_time));
|
||||
smb_msleep(sleep_time);
|
||||
DEBUG(5,("smbldap_search: go on!\n"));
|
||||
DEBUG(5,("smbldap_search_ext: go on!\n"));
|
||||
}
|
||||
ZERO_STRUCT(ldap_state->last_rebind);
|
||||
}
|
||||
@ -1064,13 +1069,138 @@ int smbldap_search(struct smbldap_state *ldap_state,
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Setup timeout for the ldap_search_ext_s call - local and remote. */
|
||||
timeout.tv_sec = lp_ldap_timeout();
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* Setup alarm timeout.... Do we need both of these ? JRA.
|
||||
* Yes, I think we do need both of these. The server timeout only
|
||||
* covers the case where the server's operation takes too long. It
|
||||
* does not cover the case where the request hangs on its way to the
|
||||
* server. The server side timeout is not strictly necessary, it's
|
||||
* just a bit more kind to the server. VL. */
|
||||
|
||||
got_alarm = 0;
|
||||
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
|
||||
alarm(lp_ldap_timeout());
|
||||
/* End setup timeout. */
|
||||
|
||||
while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
|
||||
rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
|
||||
utf8_filter,
|
||||
CONST_DISCARD(char **, attrs),
|
||||
attrsonly, res);
|
||||
|
||||
rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope,
|
||||
utf8_filter,
|
||||
CONST_DISCARD(char **, attrs),
|
||||
attrsonly, sctrls, cctrls, &timeout,
|
||||
sizelimit, res);
|
||||
|
||||
SAFE_FREE(utf8_filter);
|
||||
|
||||
/* Teardown timeout. */
|
||||
CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
|
||||
alarm(0);
|
||||
|
||||
if (got_alarm != 0)
|
||||
return LDAP_TIMELIMIT_EXCEEDED;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int smbldap_search(struct smbldap_state *ldap_state,
|
||||
const char *base, int scope, const char *filter,
|
||||
const char *attrs[], int attrsonly,
|
||||
LDAPMessage **res)
|
||||
{
|
||||
return smbldap_search_ext(ldap_state, base, scope, filter, attrs,
|
||||
attrsonly, NULL, NULL, LDAP_NO_LIMIT, res);
|
||||
}
|
||||
|
||||
int smbldap_search_paged(struct smbldap_state *ldap_state,
|
||||
const char *base, int scope, const char *filter,
|
||||
const char **attrs, int attrsonly, int pagesize,
|
||||
LDAPMessage **res, void **cookie)
|
||||
{
|
||||
LDAPControl pr;
|
||||
LDAPControl **rcontrols;
|
||||
LDAPControl *controls[2] = { NULL, NULL};
|
||||
BerElement *cookie_be = NULL;
|
||||
struct berval *cookie_bv = NULL;
|
||||
int tmp = 0, i, rc;
|
||||
BOOL critical = True;
|
||||
|
||||
*res = NULL;
|
||||
|
||||
DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
|
||||
"scope => [%d], pagesize => [%d]\n",
|
||||
base, filter, scope, pagesize));
|
||||
|
||||
cookie_be = ber_alloc_t(LBER_USE_DER);
|
||||
if (cookie_be == NULL) {
|
||||
DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
|
||||
"NULL\n"));
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* construct cookie */
|
||||
if (*cookie != NULL) {
|
||||
ber_printf(cookie_be, "{iO}", (ber_int_t) pagesize, *cookie);
|
||||
ber_bvfree(*cookie); /* don't need it from last time */
|
||||
*cookie = NULL;
|
||||
} else {
|
||||
ber_printf(cookie_be, "{io}", (ber_int_t) pagesize, "", 0);
|
||||
}
|
||||
ber_flatten(cookie_be, &cookie_bv);
|
||||
|
||||
pr.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
|
||||
pr.ldctl_iscritical = (char) critical;
|
||||
pr.ldctl_value.bv_len = cookie_bv->bv_len;
|
||||
pr.ldctl_value.bv_val = cookie_bv->bv_val;
|
||||
|
||||
controls[0] = ≺
|
||||
controls[1] = NULL;
|
||||
|
||||
rc = smbldap_search_ext(ldap_state, base, scope, filter, attrs,
|
||||
0, controls, NULL, LDAP_NO_LIMIT, res);
|
||||
|
||||
ber_free(cookie_be, 1);
|
||||
ber_bvfree(cookie_bv);
|
||||
|
||||
if (rc != 0) {
|
||||
DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
|
||||
"failed with [%s]\n", filter, ldap_err2string(rc)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
DEBUG(3,("smbldap_search_paged: search was successfull\n"));
|
||||
|
||||
rc = ldap_parse_result(ldap_state->ldap_struct, *res, NULL, NULL,
|
||||
NULL, NULL, &rcontrols, 0);
|
||||
if (rc != 0) {
|
||||
DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
|
||||
"with [%s]\n", ldap_err2string(rc)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rcontrols == NULL)
|
||||
goto done;
|
||||
|
||||
for (i=0; rcontrols[i]; i++) {
|
||||
|
||||
if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) != 0)
|
||||
continue;
|
||||
|
||||
cookie_be = ber_init(&rcontrols[i]->ldctl_value);
|
||||
ber_scanf(cookie_be,"{iO}", &tmp, &cookie_bv);
|
||||
/* the berval is the cookie, but must be freed when it is all
|
||||
done */
|
||||
if (cookie_bv->bv_len)
|
||||
*cookie=ber_bvdup(cookie_bv);
|
||||
else
|
||||
*cookie=NULL;
|
||||
ber_bvfree(cookie_bv);
|
||||
ber_free(cookie_be, 1);
|
||||
break;
|
||||
}
|
||||
ldap_controls_free(rcontrols);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -977,6 +977,56 @@ void *realloc_array(void *p,size_t el_size, unsigned int count)
|
||||
return Realloc(p,el_size*count);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
(Hopefully) efficient array append
|
||||
****************************************************************************/
|
||||
void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
|
||||
void *element, void **array, uint32 *num_elements,
|
||||
ssize_t *array_size)
|
||||
{
|
||||
if (*array_size == -1)
|
||||
return;
|
||||
|
||||
if (*array == NULL) {
|
||||
if (*array_size == 0)
|
||||
*array_size = 128;
|
||||
|
||||
if (mem_ctx != NULL)
|
||||
*array = talloc_array(mem_ctx, element_size,
|
||||
*array_size);
|
||||
else
|
||||
*array = malloc_array(element_size, *array_size);
|
||||
|
||||
if (*array == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (*num_elements == *array_size) {
|
||||
*array_size *= 2;
|
||||
|
||||
if (mem_ctx != NULL)
|
||||
*array = talloc_realloc_array(mem_ctx, *array,
|
||||
element_size,
|
||||
*array_size);
|
||||
else
|
||||
*array = realloc_array(*array, element_size,
|
||||
*array_size);
|
||||
|
||||
if (*array == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy((char *)(*array) + element_size*(*num_elements),
|
||||
element, element_size);
|
||||
*num_elements += 1;
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
*num_elements = 0;
|
||||
*array_size = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Free memory, checks for NULL.
|
||||
Use directly SAFE_FREE()
|
||||
|
@ -207,23 +207,33 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
uint32 *num_entries,
|
||||
struct acct_info **info)
|
||||
{
|
||||
struct acct_info *talloced_info;
|
||||
struct pdb_search *search;
|
||||
struct samr_displayentry *aliases;
|
||||
int i;
|
||||
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* Hmm. One billion aliases should be enough for a start */
|
||||
search = pdb_search_aliases(&domain->sid);
|
||||
if (search == NULL) goto done;
|
||||
|
||||
if (!pdb_enum_aliases(&domain->sid, 0, 1000000000,
|
||||
num_entries, info)) {
|
||||
/* Nothing to report, just exit. */
|
||||
return NT_STATUS_OK;
|
||||
*num_entries = pdb_search_entries(search, 0, 0xffffffff, &aliases);
|
||||
if (*num_entries == 0) goto done;
|
||||
|
||||
*info = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
|
||||
if (*info == NULL) {
|
||||
result = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
talloced_info = (struct acct_info *)TALLOC_MEMDUP(mem_ctx, *info,
|
||||
*num_entries * sizeof(struct acct_info));
|
||||
for (i=0; i<*num_entries; i++) {
|
||||
fstrcpy((*info)[i].acct_name, aliases[i].account_name);
|
||||
fstrcpy((*info)[i].acct_desc, aliases[i].description);
|
||||
(*info)[i].rid = aliases[i].rid;
|
||||
}
|
||||
|
||||
SAFE_FREE(*info);
|
||||
*info = talloced_info;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
result = NT_STATUS_OK;
|
||||
done:
|
||||
pdb_search_destroy(search);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* convert a single name to a sid in a domain */
|
||||
|
@ -246,6 +246,7 @@ typedef struct
|
||||
int ldap_passwd_sync;
|
||||
int ldap_replication_sleep;
|
||||
int ldap_timeout; /* This is initialised in init_globals */
|
||||
int ldap_page_size;
|
||||
BOOL ldap_delete_dn;
|
||||
BOOL bMsAddPrinterWizard;
|
||||
BOOL bDNSproxy;
|
||||
@ -1121,6 +1122,7 @@ static struct parm_struct parm_table[] = {
|
||||
{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
|
||||
{"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
|
||||
{"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
|
||||
{"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
|
||||
{"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
|
||||
|
||||
{N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
|
||||
@ -1512,6 +1514,7 @@ static void init_globals(void)
|
||||
Globals.ldap_delete_dn = False;
|
||||
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
|
||||
Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
|
||||
Globals.ldap_page_size = LDAP_PAGE_SIZE;
|
||||
|
||||
/* This is what we tell the afs client. in reality we set the token
|
||||
* to never expire, though, when this runs out the afs client will
|
||||
@ -1770,6 +1773,7 @@ FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
|
||||
FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
|
||||
FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
|
||||
FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
|
||||
FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
|
||||
FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
|
||||
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
|
||||
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
|
||||
|
@ -549,24 +549,6 @@ static NTSTATUS context_delete_alias(struct pdb_context *context,
|
||||
return context->pdb_methods->delete_alias(context->pdb_methods, sid);
|
||||
}
|
||||
|
||||
static NTSTATUS context_enum_aliases(struct pdb_context *context,
|
||||
const DOM_SID *sid,
|
||||
uint32 start_idx, uint32 max_entries,
|
||||
uint32 *num_aliases,
|
||||
struct acct_info **info)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return context->pdb_methods->enum_aliases(context->pdb_methods,
|
||||
sid, start_idx, max_entries,
|
||||
num_aliases, info);
|
||||
}
|
||||
|
||||
static NTSTATUS context_get_aliasinfo(struct pdb_context *context,
|
||||
const DOM_SID *sid,
|
||||
struct acct_info *info)
|
||||
@ -683,6 +665,68 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
|
||||
rids, names, attrs);
|
||||
}
|
||||
|
||||
static BOOL context_search_users(struct pdb_context *context,
|
||||
struct pdb_search *search, uint16 acct_flags)
|
||||
{
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return context->pdb_methods->search_users(context->pdb_methods,
|
||||
search, acct_flags);
|
||||
}
|
||||
|
||||
static BOOL context_search_groups(struct pdb_context *context,
|
||||
struct pdb_search *search)
|
||||
{
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return context->pdb_methods->search_groups(context->pdb_methods,
|
||||
search);
|
||||
}
|
||||
|
||||
static BOOL context_search_aliases(struct pdb_context *context,
|
||||
struct pdb_search *search,
|
||||
const DOM_SID *sid)
|
||||
{
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return context->pdb_methods->search_aliases(context->pdb_methods,
|
||||
search, sid);
|
||||
}
|
||||
|
||||
static BOOL context_search_next_entry(struct pdb_context *context,
|
||||
struct pdb_search *search,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return context->pdb_methods->search_next_entry(context->pdb_methods,
|
||||
search, entry);
|
||||
}
|
||||
|
||||
static void context_search_end(struct pdb_context *context,
|
||||
struct pdb_search *search)
|
||||
{
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
context->pdb_methods->search_end(context->pdb_methods, search);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Free and cleanup a pdb context, any associated data and anything
|
||||
that the attached modules might have associated.
|
||||
@ -805,7 +849,6 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
|
||||
(*context)->pdb_find_alias = context_find_alias;
|
||||
(*context)->pdb_create_alias = context_create_alias;
|
||||
(*context)->pdb_delete_alias = context_delete_alias;
|
||||
(*context)->pdb_enum_aliases = context_enum_aliases;
|
||||
(*context)->pdb_get_aliasinfo = context_get_aliasinfo;
|
||||
(*context)->pdb_set_aliasinfo = context_set_aliasinfo;
|
||||
(*context)->pdb_add_aliasmem = context_add_aliasmem;
|
||||
@ -814,6 +857,12 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
|
||||
(*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
|
||||
(*context)->pdb_lookup_rids = context_lookup_rids;
|
||||
|
||||
(*context)->pdb_search_users = context_search_users;
|
||||
(*context)->pdb_search_groups = context_search_groups;
|
||||
(*context)->pdb_search_aliases = context_search_aliases;
|
||||
(*context)->pdb_search_next_entry = context_search_next_entry;
|
||||
(*context)->pdb_search_end = context_search_end;
|
||||
|
||||
(*context)->free_fn = free_pdb_context;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@ -1199,22 +1248,6 @@ BOOL pdb_delete_alias(const DOM_SID *sid)
|
||||
|
||||
}
|
||||
|
||||
BOOL pdb_enum_aliases(const DOM_SID *sid, uint32 start_idx, uint32 max_entries,
|
||||
uint32 *num_aliases, struct acct_info **info)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
|
||||
if (!pdb_context) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return NT_STATUS_IS_OK(pdb_context->pdb_enum_aliases(pdb_context, sid,
|
||||
start_idx,
|
||||
max_entries,
|
||||
num_aliases,
|
||||
info));
|
||||
}
|
||||
|
||||
BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
@ -1543,6 +1576,422 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct pdb_search *pdb_search_init(enum pdb_search_type type)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct pdb_search *result;
|
||||
|
||||
mem_ctx = talloc_init("pdb_search");
|
||||
if (mem_ctx == NULL) {
|
||||
DEBUG(0, ("talloc_init failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = TALLOC_P(mem_ctx, struct pdb_search);
|
||||
if (result == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->mem_ctx = mem_ctx;
|
||||
result->type = type;
|
||||
result->cache = NULL;
|
||||
result->num_entries = 0;
|
||||
result->cache_size = 0;
|
||||
result->search_ended = False;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
|
||||
uint16 acct_flags,
|
||||
const char *account_name,
|
||||
const char *fullname,
|
||||
const char *description,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
entry->rid = rid;
|
||||
entry->acct_flags = acct_flags;
|
||||
|
||||
if (account_name != NULL)
|
||||
entry->account_name = talloc_strdup(mem_ctx, account_name);
|
||||
else
|
||||
entry->account_name = "";
|
||||
|
||||
if (fullname != NULL)
|
||||
entry->fullname = talloc_strdup(mem_ctx, fullname);
|
||||
else
|
||||
entry->fullname = "";
|
||||
|
||||
if (description != NULL)
|
||||
entry->description = talloc_strdup(mem_ctx, description);
|
||||
else
|
||||
entry->description = "";
|
||||
}
|
||||
|
||||
static BOOL user_search_in_progress = False;
|
||||
struct user_search {
|
||||
uint16 acct_flags;
|
||||
};
|
||||
|
||||
static BOOL pdb_default_search_users(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
uint16 acct_flags)
|
||||
{
|
||||
struct user_search *state;
|
||||
|
||||
if (user_search_in_progress) {
|
||||
DEBUG(1, ("user search in progress\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!pdb_setsampwent(False, acct_flags)) {
|
||||
DEBUG(5, ("Could not start search\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
user_search_in_progress = True;
|
||||
|
||||
state = TALLOC_P(search->mem_ctx, struct user_search);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
state->acct_flags = acct_flags;
|
||||
|
||||
search->private = state;
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_next_entry_users(struct pdb_search *s,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct user_search *state = s->private;
|
||||
SAM_ACCOUNT *user = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
next:
|
||||
status = pdb_init_sam(&user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Could not pdb_init_sam\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!pdb_getsampwent(user)) {
|
||||
pdb_free_sam(&user);
|
||||
return False;
|
||||
}
|
||||
|
||||
if ((state->acct_flags != 0) &&
|
||||
((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
|
||||
pdb_free_sam(&user);
|
||||
goto next;
|
||||
}
|
||||
|
||||
fill_displayentry(s->mem_ctx, pdb_get_user_rid(user),
|
||||
pdb_get_acct_ctrl(user), pdb_get_username(user),
|
||||
pdb_get_fullname(user), pdb_get_acct_desc(user),
|
||||
entry);
|
||||
|
||||
pdb_free_sam(&user);
|
||||
return True;
|
||||
}
|
||||
|
||||
static void pdb_search_end_users(struct pdb_search *search)
|
||||
{
|
||||
pdb_endsampwent();
|
||||
user_search_in_progress = False;
|
||||
}
|
||||
|
||||
struct group_search {
|
||||
GROUP_MAP *groups;
|
||||
int num_groups, current_group;
|
||||
};
|
||||
|
||||
static BOOL pdb_default_search_groups(struct pdb_methods *methods,
|
||||
struct pdb_search *search)
|
||||
{
|
||||
struct group_search *state;
|
||||
|
||||
state = TALLOC_P(search->mem_ctx, struct group_search);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &state->groups,
|
||||
&state->num_groups, True)) {
|
||||
DEBUG(0, ("Could not enum groups\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
state->current_group = 0;
|
||||
search->private = state;
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_next_entry_group(struct pdb_search *s,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct group_search *state = s->private;
|
||||
uint32 rid;
|
||||
GROUP_MAP *map = &state->groups[state->current_group];
|
||||
|
||||
if (state->current_group == state->num_groups)
|
||||
return False;
|
||||
|
||||
sid_peek_rid(&map->sid, &rid);
|
||||
|
||||
fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
|
||||
entry);
|
||||
|
||||
state->current_group += 1;
|
||||
return True;
|
||||
}
|
||||
|
||||
static void pdb_search_end_groups(struct pdb_search *search)
|
||||
{
|
||||
struct group_search *state = search->private;
|
||||
SAFE_FREE(state->groups);
|
||||
}
|
||||
|
||||
struct alias_search {
|
||||
GROUP_MAP *aliases;
|
||||
int num_aliases, current_alias;
|
||||
};
|
||||
|
||||
static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
const DOM_SID *sid)
|
||||
{
|
||||
struct alias_search *state;
|
||||
enum SID_NAME_USE type = SID_NAME_UNKNOWN;
|
||||
|
||||
if (sid_equal(sid, get_global_sam_sid()))
|
||||
type = SID_NAME_ALIAS;
|
||||
|
||||
if (sid_equal(sid, &global_sid_Builtin))
|
||||
type = SID_NAME_WKN_GRP;
|
||||
|
||||
if (type == SID_NAME_UNKNOWN) {
|
||||
DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
state = TALLOC_P(search->mem_ctx, struct alias_search);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!pdb_enum_group_mapping(type, &state->aliases,
|
||||
&state->num_aliases, False)) {
|
||||
DEBUG(0, ("Could not enum aliases\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
state->current_alias = 0;
|
||||
search->private = state;
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_next_entry_alias(struct pdb_search *s,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct alias_search *state = s->private;
|
||||
uint32 rid;
|
||||
GROUP_MAP *map = &state->aliases[state->current_alias];
|
||||
|
||||
if (state->current_alias == state->num_aliases)
|
||||
return False;
|
||||
|
||||
sid_peek_rid(&map->sid, &rid);
|
||||
|
||||
fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
|
||||
entry);
|
||||
|
||||
state->current_alias += 1;
|
||||
return True;
|
||||
}
|
||||
|
||||
static void pdb_search_end_aliases(struct pdb_search *search)
|
||||
{
|
||||
struct alias_search *state = search->private;
|
||||
SAFE_FREE(state->aliases);
|
||||
}
|
||||
|
||||
static BOOL pdb_default_search_next_entry(struct pdb_methods *pdb_methods,
|
||||
struct pdb_search *search,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
BOOL result = False;
|
||||
switch (search->type) {
|
||||
case PDB_USER_SEARCH:
|
||||
result = pdb_search_next_entry_users(search, entry);
|
||||
break;
|
||||
case PDB_GROUP_SEARCH:
|
||||
result = pdb_search_next_entry_group(search, entry);
|
||||
break;
|
||||
case PDB_ALIAS_SEARCH:
|
||||
result = pdb_search_next_entry_alias(search, entry);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0, ("unknown search type: %d\n", search->type));
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_next_entry(struct pdb_search *search,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
|
||||
if (pdb_context == NULL) return False;
|
||||
|
||||
return pdb_context->pdb_search_next_entry(pdb_context, search, entry);
|
||||
}
|
||||
|
||||
static void pdb_default_search_end(struct pdb_methods *pdb_methods,
|
||||
struct pdb_search *search)
|
||||
{
|
||||
switch (search->type) {
|
||||
case PDB_USER_SEARCH:
|
||||
pdb_search_end_users(search);
|
||||
break;
|
||||
case PDB_GROUP_SEARCH:
|
||||
pdb_search_end_groups(search);
|
||||
break;
|
||||
case PDB_ALIAS_SEARCH:
|
||||
pdb_search_end_aliases(search);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0, ("unknown search type: %d\n", search->type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void pdb_search_end(struct pdb_search *search)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
|
||||
if (pdb_context == NULL) return;
|
||||
|
||||
pdb_context->pdb_search_end(pdb_context, search);
|
||||
}
|
||||
|
||||
static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
|
||||
uint32 idx)
|
||||
{
|
||||
if (idx < search->num_entries)
|
||||
return &search->cache[idx];
|
||||
|
||||
if (search->search_ended)
|
||||
return NULL;
|
||||
|
||||
while (idx >= search->num_entries) {
|
||||
struct samr_displayentry entry;
|
||||
|
||||
if (!pdb_search_next_entry(search, &entry)) {
|
||||
pdb_search_end(search);
|
||||
search->search_ended = True;
|
||||
break;
|
||||
}
|
||||
|
||||
ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
|
||||
entry, &search->cache, &search->num_entries,
|
||||
&search->cache_size);
|
||||
}
|
||||
|
||||
return (search->num_entries > idx) ? &search->cache[idx] : NULL;
|
||||
}
|
||||
|
||||
struct pdb_search *pdb_search_users(uint16 acct_flags)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
struct pdb_search *result;
|
||||
|
||||
if (pdb_context == NULL) return NULL;
|
||||
|
||||
result = pdb_search_init(PDB_USER_SEARCH);
|
||||
if (result == NULL) return NULL;
|
||||
|
||||
if (!pdb_context->pdb_search_users(pdb_context, result, acct_flags)) {
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct pdb_search *pdb_search_groups(void)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
struct pdb_search *result;
|
||||
|
||||
if (pdb_context == NULL) return NULL;
|
||||
|
||||
result = pdb_search_init(PDB_GROUP_SEARCH);
|
||||
if (result == NULL) return NULL;
|
||||
|
||||
if (!pdb_context->pdb_search_groups(pdb_context, result)) {
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
struct pdb_search *result;
|
||||
|
||||
if (pdb_context == NULL) return NULL;
|
||||
|
||||
result = pdb_search_init(PDB_ALIAS_SEARCH);
|
||||
if (result == NULL) return NULL;
|
||||
|
||||
if (!pdb_context->pdb_search_aliases(pdb_context, result, sid)) {
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32 pdb_search_entries(struct pdb_search *search,
|
||||
uint32 start_idx, uint32 max_entries,
|
||||
struct samr_displayentry **result)
|
||||
{
|
||||
struct samr_displayentry *end_entry;
|
||||
uint32 end_idx = start_idx+max_entries-1;
|
||||
|
||||
/* The first entry needs to be searched after the last. Otherwise the
|
||||
* first entry might have moved due to a realloc during the search for
|
||||
* the last entry. */
|
||||
|
||||
end_entry = pdb_search_getentry(search, end_idx);
|
||||
*result = pdb_search_getentry(search, start_idx);
|
||||
|
||||
if (end_entry != NULL)
|
||||
return max_entries;
|
||||
|
||||
if (start_idx >= search->num_entries)
|
||||
return 0;
|
||||
|
||||
return search->num_entries - start_idx;
|
||||
}
|
||||
|
||||
void pdb_search_destroy(struct pdb_search *search)
|
||||
{
|
||||
if (search == NULL)
|
||||
return;
|
||||
|
||||
if (!search->search_ended)
|
||||
pdb_search_end(search);
|
||||
|
||||
talloc_destroy(search->mem_ctx);
|
||||
}
|
||||
|
||||
NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
|
||||
{
|
||||
*methods = TALLOC_P(mem_ctx, struct pdb_methods);
|
||||
@ -1575,7 +2024,6 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
|
||||
(*methods)->find_alias = pdb_default_find_alias;
|
||||
(*methods)->create_alias = pdb_default_create_alias;
|
||||
(*methods)->delete_alias = pdb_default_delete_alias;
|
||||
(*methods)->enum_aliases = pdb_default_enum_aliases;
|
||||
(*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
|
||||
(*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
|
||||
(*methods)->add_aliasmem = pdb_default_add_aliasmem;
|
||||
@ -1583,364 +2031,11 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
|
||||
(*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
|
||||
(*methods)->enum_alias_memberships = pdb_default_alias_memberships;
|
||||
(*methods)->lookup_rids = pdb_default_lookup_rids;
|
||||
(*methods)->search_users = pdb_default_search_users;
|
||||
(*methods)->search_groups = pdb_default_search_groups;
|
||||
(*methods)->search_aliases = pdb_default_search_aliases;
|
||||
(*methods)->search_next_entry = pdb_default_search_next_entry;
|
||||
(*methods)->search_end = pdb_default_search_end;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
struct pdb_search *pdb_search_users(uint16 acct_flags);
|
||||
struct pdb_search *pdb_search_groups(void);
|
||||
struct pdb_search *pdb_search_aliases(const DOM_SID *sid);
|
||||
uint32 pdb_search_entries(struct pdb_search *search, uint32 start_idx, uint32 max_entries, struct samr_displayentry **result);
|
||||
void pdb_search_destroy(struct pdb_search *search);
|
||||
|
||||
static struct pdb_search *pdb_search_init(enum pdb_search_type type)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct pdb_search *result;
|
||||
|
||||
mem_ctx = talloc_init("pdb_search");
|
||||
if (mem_ctx == NULL) {
|
||||
DEBUG(0, ("talloc_init failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = TALLOC_P(mem_ctx, struct pdb_search);
|
||||
if (result == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->mem_ctx = mem_ctx;
|
||||
result->type = type;
|
||||
result->cache = NULL;
|
||||
result->cache_size = 0;
|
||||
result->search_ended = False;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
|
||||
uint16 acct_flags,
|
||||
const char *account_name,
|
||||
const char *fullname,
|
||||
const char *description,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
entry->rid = rid;
|
||||
entry->acct_flags = acct_flags;
|
||||
|
||||
if (account_name != NULL)
|
||||
entry->account_name = talloc_strdup(mem_ctx, account_name);
|
||||
|
||||
if (fullname != NULL)
|
||||
entry->fullname = talloc_strdup(mem_ctx, fullname);
|
||||
|
||||
if (description != NULL)
|
||||
entry->description = talloc_strdup(mem_ctx, description);
|
||||
}
|
||||
|
||||
static BOOL user_search_in_progress = False;
|
||||
struct user_search {
|
||||
uint16 acct_flags;
|
||||
};
|
||||
|
||||
struct pdb_search *pdb_search_users(uint16 acct_flags)
|
||||
{
|
||||
struct pdb_search *result;
|
||||
struct user_search *state;
|
||||
|
||||
if (user_search_in_progress) {
|
||||
DEBUG(1, ("user search in progress\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pdb_setsampwent(False, acct_flags))
|
||||
return NULL;
|
||||
|
||||
user_search_in_progress = True;
|
||||
|
||||
result = pdb_search_init(PDB_USER_SEARCH);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
state = TALLOC_P(result->mem_ctx, struct user_search);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->acct_flags = acct_flags;
|
||||
|
||||
result->private = state;
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_entry_users(struct pdb_search *s, TALLOC_CTX *mem_ctx,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct user_search *state = s->private;
|
||||
SAM_ACCOUNT *user = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
next:
|
||||
status = pdb_init_sam(&user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Could not pdb_init_sam\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!pdb_getsampwent(user)) {
|
||||
pdb_free_sam(&user);
|
||||
return False;
|
||||
}
|
||||
|
||||
if ((state->acct_flags != 0) &&
|
||||
((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
|
||||
pdb_free_sam(&user);
|
||||
goto next;
|
||||
}
|
||||
|
||||
fill_displayentry(mem_ctx, pdb_get_user_rid(user),
|
||||
pdb_get_acct_ctrl(user), pdb_get_username(user),
|
||||
pdb_get_fullname(user), pdb_get_acct_desc(user),
|
||||
entry);
|
||||
|
||||
pdb_free_sam(&user);
|
||||
return True;
|
||||
}
|
||||
|
||||
static void pdb_search_end_users(struct pdb_search *search)
|
||||
{
|
||||
pdb_endsampwent();
|
||||
user_search_in_progress = False;
|
||||
}
|
||||
|
||||
struct group_search {
|
||||
GROUP_MAP *groups;
|
||||
int num_groups, current_group;
|
||||
};
|
||||
|
||||
struct pdb_search *pdb_search_groups(void)
|
||||
{
|
||||
struct pdb_search *result;
|
||||
struct group_search *state;
|
||||
|
||||
result = pdb_search_init(PDB_GROUP_SEARCH);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
state = TALLOC_P(result->mem_ctx, struct group_search);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &state->groups,
|
||||
&state->num_groups, True)) {
|
||||
DEBUG(0, ("Could not enum groups\n"));
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->current_group = 0;
|
||||
result->private = state;
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_entry_group(struct pdb_search *s, TALLOC_CTX *mem_ctx,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct group_search *state = s->private;
|
||||
uint32 rid;
|
||||
GROUP_MAP *map = &state->groups[state->current_group];
|
||||
|
||||
if (state->current_group == state->num_groups)
|
||||
return False;
|
||||
|
||||
sid_peek_rid(&map->sid, &rid);
|
||||
|
||||
fill_displayentry(mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
|
||||
entry);
|
||||
|
||||
state->current_group += 1;
|
||||
return True;
|
||||
}
|
||||
|
||||
static void pdb_search_end_groups(struct pdb_search *search)
|
||||
{
|
||||
struct group_search *state = search->private;
|
||||
SAFE_FREE(state->groups);
|
||||
}
|
||||
|
||||
struct alias_search {
|
||||
GROUP_MAP *aliases;
|
||||
int num_aliases, current_alias;
|
||||
};
|
||||
|
||||
struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
|
||||
{
|
||||
struct pdb_search *result;
|
||||
struct alias_search *state;
|
||||
enum SID_NAME_USE type = SID_NAME_UNKNOWN;
|
||||
DOM_SID builtin_sid;
|
||||
|
||||
if (sid_equal(sid, get_global_sam_sid()))
|
||||
type = SID_NAME_ALIAS;
|
||||
|
||||
string_to_sid(&builtin_sid, "S-1-5-32");
|
||||
|
||||
if (sid_equal(sid, &builtin_sid))
|
||||
type = SID_NAME_WKN_GRP;
|
||||
|
||||
if (type == SID_NAME_UNKNOWN) {
|
||||
DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = pdb_search_init(PDB_ALIAS_SEARCH);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
state = TALLOC_P(result->mem_ctx, struct alias_search);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pdb_enum_group_mapping(type, &state->aliases,
|
||||
&state->num_aliases, False)) {
|
||||
DEBUG(0, ("Could not enum aliases\n"));
|
||||
talloc_destroy(result->mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->current_alias = 0;
|
||||
result->private = state;
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL pdb_search_entry_alias(struct pdb_search *s, TALLOC_CTX *mem_ctx,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct alias_search *state = s->private;
|
||||
uint32 rid;
|
||||
GROUP_MAP *map = &state->aliases[state->current_alias];
|
||||
|
||||
if (state->current_alias == state->num_aliases)
|
||||
return False;
|
||||
|
||||
sid_peek_rid(&map->sid, &rid);
|
||||
|
||||
fill_displayentry(mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
|
||||
entry);
|
||||
|
||||
state->current_alias += 1;
|
||||
return True;
|
||||
}
|
||||
|
||||
static void pdb_search_end_aliases(struct pdb_search *search)
|
||||
{
|
||||
struct alias_search *state = search->private;
|
||||
SAFE_FREE(state->aliases);
|
||||
}
|
||||
|
||||
static BOOL pdb_search_entry(struct pdb_search *search, TALLOC_CTX *mem_ctx,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
BOOL result = False;
|
||||
switch (search->type) {
|
||||
case PDB_USER_SEARCH:
|
||||
result = pdb_search_entry_users(search, mem_ctx, entry);
|
||||
break;
|
||||
case PDB_GROUP_SEARCH:
|
||||
result = pdb_search_entry_group(search, mem_ctx, entry);
|
||||
break;
|
||||
case PDB_ALIAS_SEARCH:
|
||||
result = pdb_search_entry_alias(search, mem_ctx, entry);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0, ("unknown search type: %d\n", search->type));
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void pdb_search_end(struct pdb_search *search)
|
||||
{
|
||||
switch (search->type) {
|
||||
case PDB_USER_SEARCH:
|
||||
pdb_search_end_users(search);
|
||||
break;
|
||||
case PDB_GROUP_SEARCH:
|
||||
pdb_search_end_groups(search);
|
||||
break;
|
||||
case PDB_ALIAS_SEARCH:
|
||||
pdb_search_end_aliases(search);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0, ("unknown search type: %d\n", search->type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
|
||||
uint32 idx)
|
||||
{
|
||||
if (idx < search->cache_size)
|
||||
return &search->cache[idx];
|
||||
|
||||
if (search->search_ended)
|
||||
return NULL;
|
||||
|
||||
while (idx >= search->cache_size) {
|
||||
struct samr_displayentry entry;
|
||||
|
||||
if (!pdb_search_entry(search, search->mem_ctx, &entry)) {
|
||||
pdb_search_end(search);
|
||||
search->search_ended = True;
|
||||
break;
|
||||
}
|
||||
|
||||
ADD_TO_ARRAY(search->mem_ctx, struct samr_displayentry,
|
||||
entry, &search->cache, &search->cache_size);
|
||||
}
|
||||
|
||||
return (search->cache_size > idx) ? &search->cache[idx] : NULL;
|
||||
}
|
||||
|
||||
uint32 pdb_search_entries(struct pdb_search *search,
|
||||
uint32 start_idx, uint32 max_entries,
|
||||
struct samr_displayentry **result)
|
||||
{
|
||||
struct samr_displayentry *end_entry;
|
||||
uint32 end_idx = start_idx+max_entries-1;
|
||||
|
||||
/* The first entry needs to be searched after the last. Otherwise the
|
||||
* first entry might have moved due to a realloc during the search for
|
||||
* the last entry. */
|
||||
|
||||
end_entry = pdb_search_getentry(search, end_idx);
|
||||
*result = pdb_search_getentry(search, start_idx);
|
||||
|
||||
if (end_entry != NULL)
|
||||
return max_entries;
|
||||
|
||||
if (start_idx >= search->cache_size)
|
||||
return 0;
|
||||
|
||||
return search->cache_size - start_idx;
|
||||
}
|
||||
|
||||
void pdb_search_destroy(struct pdb_search *search)
|
||||
{
|
||||
if (search == NULL)
|
||||
return;
|
||||
|
||||
if (!search->search_ended)
|
||||
pdb_search_end(search);
|
||||
|
||||
talloc_destroy(search->mem_ctx);
|
||||
}
|
||||
|
@ -3323,6 +3323,470 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
|
||||
return result;
|
||||
}
|
||||
|
||||
char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
|
||||
{
|
||||
char *filter = NULL;
|
||||
char *escaped = NULL;
|
||||
char *result = NULL;
|
||||
|
||||
asprintf(&filter, "(&%s(objectclass=sambaSamAccount))",
|
||||
lp_ldap_filter());
|
||||
if (filter == NULL) goto done;
|
||||
|
||||
escaped = escape_ldap_string_alloc(username);
|
||||
if (escaped == NULL) goto done;
|
||||
|
||||
filter = realloc_string_sub(filter, "%u", username);
|
||||
result = talloc_strdup(mem_ctx, filter);
|
||||
|
||||
done:
|
||||
SAFE_FREE(filter);
|
||||
SAFE_FREE(escaped);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
|
||||
{
|
||||
int i, num = 0;
|
||||
va_list ap;
|
||||
const char **result;
|
||||
|
||||
va_start(ap, mem_ctx);
|
||||
while (va_arg(ap, const char *) != NULL)
|
||||
num += 1;
|
||||
va_end(ap);
|
||||
|
||||
result = TALLOC_ARRAY(mem_ctx, const char *, num+1);
|
||||
|
||||
va_start(ap, mem_ctx);
|
||||
for (i=0; i<num; i++)
|
||||
result[i] = talloc_strdup(mem_ctx, va_arg(ap, const char*));
|
||||
va_end(ap);
|
||||
|
||||
result[num] = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct ldap_search_state {
|
||||
struct smbldap_state *connection;
|
||||
|
||||
uint16 acct_flags;
|
||||
|
||||
const char *base;
|
||||
int scope;
|
||||
const char *filter;
|
||||
const char **attrs;
|
||||
int attrsonly;
|
||||
void *pagedresults_cookie;
|
||||
|
||||
LDAPMessage *entries, *current_entry;
|
||||
BOOL (*ldap2displayentry)(struct ldap_search_state *state,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
LDAP *ld, LDAPMessage *entry,
|
||||
struct samr_displayentry *result);
|
||||
};
|
||||
|
||||
static BOOL ldapsam_search_firstpage(struct pdb_search *search)
|
||||
{
|
||||
struct ldap_search_state *state = search->private;
|
||||
LDAP *ld = state->connection->ldap_struct;
|
||||
int rc = LDAP_OPERATIONS_ERROR;
|
||||
|
||||
state->entries = NULL;
|
||||
|
||||
if (state->connection->paged_results) {
|
||||
rc = smbldap_search_paged(state->connection, state->base,
|
||||
state->scope, state->filter,
|
||||
state->attrs, state->attrsonly,
|
||||
lp_ldap_page_size(), &state->entries,
|
||||
&state->pagedresults_cookie);
|
||||
}
|
||||
|
||||
if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
|
||||
|
||||
if (state->entries != NULL) {
|
||||
/* Left over from unsuccessful paged attempt */
|
||||
ldap_msgfree(state->entries);
|
||||
state->entries = NULL;
|
||||
}
|
||||
|
||||
rc = smbldap_search(state->connection, state->base,
|
||||
state->scope, state->filter, state->attrs,
|
||||
state->attrsonly, &state->entries);
|
||||
|
||||
if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
|
||||
return False;
|
||||
|
||||
/* Ok, the server was lying. It told us it could do paged
|
||||
* searches when it could not. */
|
||||
state->connection->paged_results = False;
|
||||
}
|
||||
|
||||
state->current_entry = ldap_first_entry(ld, state->entries);
|
||||
|
||||
if (state->current_entry == NULL) {
|
||||
ldap_msgfree(state->entries);
|
||||
state->entries = NULL;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL ldapsam_search_nextpage(struct pdb_search *search)
|
||||
{
|
||||
struct ldap_search_state *state = search->private;
|
||||
LDAP *ld = state->connection->ldap_struct;
|
||||
int rc;
|
||||
|
||||
if (!state->connection->paged_results) {
|
||||
/* There is no next page when there are no paged results */
|
||||
return False;
|
||||
}
|
||||
|
||||
rc = smbldap_search_paged(state->connection, state->base,
|
||||
state->scope, state->filter, state->attrs,
|
||||
state->attrsonly, lp_ldap_page_size(),
|
||||
&state->entries,
|
||||
&state->pagedresults_cookie);
|
||||
|
||||
if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
|
||||
return False;
|
||||
|
||||
state->current_entry = ldap_first_entry(ld, state->entries);
|
||||
|
||||
if (state->current_entry == NULL) {
|
||||
ldap_msgfree(state->entries);
|
||||
state->entries = NULL;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL ldapsam_search_next_entry(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
struct samr_displayentry *entry)
|
||||
{
|
||||
struct ldap_search_state *state = search->private;
|
||||
LDAP *ld = state->connection->ldap_struct;
|
||||
BOOL result;
|
||||
|
||||
retry:
|
||||
if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
|
||||
return False;
|
||||
|
||||
if ((state->entries == NULL) &&
|
||||
!ldapsam_search_nextpage(search))
|
||||
return False;
|
||||
|
||||
result = state->ldap2displayentry(state, search->mem_ctx, ld,
|
||||
state->current_entry, entry);
|
||||
|
||||
if (!result) {
|
||||
char *dn;
|
||||
dn = ldap_get_dn(ld, state->current_entry);
|
||||
DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
|
||||
if (dn != NULL) ldap_memfree(dn);
|
||||
}
|
||||
|
||||
state->current_entry = ldap_next_entry(ld, state->current_entry);
|
||||
|
||||
if (state->current_entry == NULL) {
|
||||
ldap_msgfree(state->entries);
|
||||
state->entries = NULL;
|
||||
}
|
||||
|
||||
if (!result) goto retry;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void ldapsam_search_end(struct pdb_methods *methods,
|
||||
struct pdb_search *search)
|
||||
{
|
||||
struct ldap_search_state *state = search->private;
|
||||
int rc;
|
||||
|
||||
if (state->pagedresults_cookie == NULL)
|
||||
return;
|
||||
|
||||
if (state->entries != NULL)
|
||||
ldap_msgfree(state->entries);
|
||||
|
||||
state->entries = NULL;
|
||||
state->current_entry = NULL;
|
||||
|
||||
if (!state->connection->paged_results)
|
||||
return;
|
||||
|
||||
/* Tell the LDAP server we're not interested in the rest anymore. */
|
||||
|
||||
rc = smbldap_search_paged(state->connection, state->base, state->scope,
|
||||
state->filter, state->attrs,
|
||||
state->attrsonly, 0, &state->entries,
|
||||
&state->pagedresults_cookie);
|
||||
|
||||
if (rc != LDAP_SUCCESS)
|
||||
DEBUG(5, ("Could not end search properly\n"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static BOOL ldapuser2displayentry(struct ldap_search_state *state,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
LDAP *ld, LDAPMessage *entry,
|
||||
struct samr_displayentry *result)
|
||||
{
|
||||
char **vals;
|
||||
DOM_SID sid;
|
||||
uint16 acct_flags;
|
||||
|
||||
vals = ldap_get_values(ld, entry, "sambaAcctFlags");
|
||||
if ((vals == NULL) || (vals[0] == NULL)) {
|
||||
DEBUG(5, ("\"sambaAcctFlags\" not found\n"));
|
||||
return False;
|
||||
}
|
||||
acct_flags = pdb_decode_acct_ctrl(vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
if ((state->acct_flags != 0) &&
|
||||
((state->acct_flags & acct_flags) == 0))
|
||||
return False;
|
||||
|
||||
result->acct_flags = acct_flags;
|
||||
result->account_name = "";
|
||||
result->fullname = "";
|
||||
result->description = "";
|
||||
|
||||
vals = ldap_get_values(ld, entry, "uid");
|
||||
if ((vals == NULL) || (vals[0] == NULL)) {
|
||||
DEBUG(5, ("\"uid\" not found\n"));
|
||||
return False;
|
||||
}
|
||||
pull_utf8_talloc(mem_ctx,
|
||||
CONST_DISCARD(char **, &result->account_name),
|
||||
vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
vals = ldap_get_values(ld, entry, "displayName");
|
||||
if ((vals == NULL) || (vals[0] == NULL))
|
||||
DEBUG(8, ("\"displayName\" not found\n"));
|
||||
else
|
||||
pull_utf8_talloc(mem_ctx,
|
||||
CONST_DISCARD(char **, &result->fullname),
|
||||
vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
vals = ldap_get_values(ld, entry, "description");
|
||||
if ((vals == NULL) || (vals[0] == NULL))
|
||||
DEBUG(8, ("\"description\" not found\n"));
|
||||
else
|
||||
pull_utf8_talloc(mem_ctx,
|
||||
CONST_DISCARD(char **, &result->description),
|
||||
vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
if ((result->account_name == NULL) ||
|
||||
(result->fullname == NULL) ||
|
||||
(result->description == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
vals = ldap_get_values(ld, entry, "sambaSid");
|
||||
if ((vals == NULL) || (vals[0] == NULL)) {
|
||||
DEBUG(0, ("\"objectSid\" not found\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!string_to_sid(&sid, vals[0])) {
|
||||
DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
|
||||
ldap_value_free(vals);
|
||||
return False;
|
||||
}
|
||||
ldap_value_free(vals);
|
||||
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
|
||||
DEBUG(0, ("%s is not our domain\n", vals[0]));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL ldapsam_search_users(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
uint16 acct_flags)
|
||||
{
|
||||
struct ldapsam_privates *ldap_state = methods->private_data;
|
||||
struct ldap_search_state *state;
|
||||
|
||||
state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
state->connection = ldap_state->smbldap_state;
|
||||
|
||||
if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
|
||||
state->base = lp_ldap_user_suffix();
|
||||
else if ((acct_flags != 0) &&
|
||||
((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) != 0))
|
||||
state->base = lp_ldap_machine_suffix();
|
||||
else
|
||||
state->base = lp_ldap_suffix();
|
||||
|
||||
state->acct_flags = acct_flags;
|
||||
state->base = talloc_strdup(search->mem_ctx, state->base);
|
||||
state->scope = LDAP_SCOPE_SUBTREE;
|
||||
state->filter = get_ldap_filter(search->mem_ctx, "*");
|
||||
state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid",
|
||||
"displayName", "description",
|
||||
"sambaAcctFlags", NULL);
|
||||
state->attrsonly = 0;
|
||||
state->pagedresults_cookie = NULL;
|
||||
state->entries = NULL;
|
||||
state->ldap2displayentry = ldapuser2displayentry;
|
||||
|
||||
if ((state->filter == NULL) || (state->attrs == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
search->private = state;
|
||||
|
||||
return ldapsam_search_firstpage(search);
|
||||
}
|
||||
|
||||
static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
LDAP *ld, LDAPMessage *entry,
|
||||
struct samr_displayentry *result)
|
||||
{
|
||||
char **vals;
|
||||
DOM_SID sid;
|
||||
|
||||
result->account_name = "";
|
||||
result->fullname = "";
|
||||
result->description = "";
|
||||
|
||||
vals = ldap_get_values(ld, entry, "cn");
|
||||
if ((vals == NULL) || (vals[0] == NULL)) {
|
||||
DEBUG(5, ("\"cn\" not found\n"));
|
||||
return False;
|
||||
}
|
||||
pull_utf8_talloc(mem_ctx,
|
||||
CONST_DISCARD(char **, &result->account_name),
|
||||
vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
vals = ldap_get_values(ld, entry, "displayName");
|
||||
if ((vals == NULL) || (vals[0] == NULL))
|
||||
DEBUG(8, ("\"displayName\" not found\n"));
|
||||
else
|
||||
pull_utf8_talloc(mem_ctx,
|
||||
CONST_DISCARD(char **, &result->fullname),
|
||||
vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
vals = ldap_get_values(ld, entry, "description");
|
||||
if ((vals == NULL) || (vals[0] == NULL))
|
||||
DEBUG(8, ("\"description\" not found\n"));
|
||||
else
|
||||
pull_utf8_talloc(mem_ctx,
|
||||
CONST_DISCARD(char **, &result->description),
|
||||
vals[0]);
|
||||
ldap_value_free(vals);
|
||||
|
||||
if ((result->account_name == NULL) ||
|
||||
(result->fullname == NULL) ||
|
||||
(result->description == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
vals = ldap_get_values(ld, entry, "sambaSid");
|
||||
if ((vals == NULL) || (vals[0] == NULL)) {
|
||||
DEBUG(0, ("\"objectSid\" not found\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!string_to_sid(&sid, vals[0])) {
|
||||
DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
|
||||
DEBUG(0, ("%s is not our domain\n", vals[0]));
|
||||
return False;
|
||||
}
|
||||
ldap_value_free(vals);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
enum SID_NAME_USE type)
|
||||
{
|
||||
struct ldapsam_privates *ldap_state = methods->private_data;
|
||||
struct ldap_search_state *state;
|
||||
|
||||
state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
|
||||
if (state == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
state->connection = ldap_state->smbldap_state;
|
||||
|
||||
state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix());
|
||||
state->connection = ldap_state->smbldap_state;
|
||||
state->scope = LDAP_SCOPE_SUBTREE;
|
||||
state->filter = talloc_asprintf(search->mem_ctx,
|
||||
"(&(objectclass=sambaGroupMapping)"
|
||||
"(sambaGroupType=%d))", type);
|
||||
state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
|
||||
"displayName", "description", NULL);
|
||||
state->attrsonly = 0;
|
||||
state->pagedresults_cookie = NULL;
|
||||
state->entries = NULL;
|
||||
state->ldap2displayentry = ldapgroup2displayentry;
|
||||
|
||||
if ((state->filter == NULL) || (state->attrs == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
search->private = state;
|
||||
|
||||
return ldapsam_search_firstpage(search);
|
||||
}
|
||||
|
||||
static BOOL ldapsam_search_groups(struct pdb_methods *methods,
|
||||
struct pdb_search *search)
|
||||
{
|
||||
return ldapsam_search_grouptype(methods, search, SID_NAME_DOM_GRP);
|
||||
}
|
||||
|
||||
static BOOL ldapsam_search_aliases(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
const DOM_SID *sid)
|
||||
{
|
||||
if (sid_check_is_domain(sid))
|
||||
return ldapsam_search_grouptype(methods, search,
|
||||
SID_NAME_ALIAS);
|
||||
|
||||
if (sid_check_is_builtin(sid))
|
||||
return ldapsam_search_grouptype(methods, search,
|
||||
SID_NAME_WKN_GRP);
|
||||
|
||||
DEBUG(5, ("Don't know SID %s\n", sid_string_static(sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Housekeeping
|
||||
*********************************************************************/
|
||||
@ -3381,6 +3845,11 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
|
||||
(*pdb_method)->enum_group_members = ldapsam_enum_group_members;
|
||||
(*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
|
||||
(*pdb_method)->lookup_rids = ldapsam_lookup_rids;
|
||||
(*pdb_method)->search_users = ldapsam_search_users;
|
||||
(*pdb_method)->search_groups = ldapsam_search_groups;
|
||||
(*pdb_method)->search_aliases = ldapsam_search_aliases;
|
||||
(*pdb_method)->search_next_entry = ldapsam_search_next_entry;
|
||||
(*pdb_method)->search_end = ldapsam_search_end;
|
||||
|
||||
/* TODO: Setup private data and free */
|
||||
|
||||
|
@ -1516,75 +1516,42 @@ BOOL samr_io_q_query_dispinfo(const char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
|
||||
inits a SAM_DISPINFO_1 structure.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
|
||||
uint32 start_idx, SAM_ACCOUNT *disp_user_info,
|
||||
DOM_SID *domain_sid)
|
||||
NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 **sam,
|
||||
uint32 num_entries, uint32 start_idx,
|
||||
struct samr_displayentry *entries)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
SAM_ACCOUNT *pwd = NULL;
|
||||
ZERO_STRUCTP(sam);
|
||||
|
||||
DEBUG(10, ("init_sam_dispinfo_1: num_entries: %d\n", num_entries));
|
||||
|
||||
if (num_entries==0)
|
||||
return NT_STATUS_OK;
|
||||
|
||||
sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY1, num_entries);
|
||||
if (!sam->sam)
|
||||
*sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_1, num_entries);
|
||||
if (*sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
sam->str=TALLOC_ARRAY(ctx, SAM_STR1, num_entries);
|
||||
if (!sam->str)
|
||||
(*sam)->sam=TALLOC_ARRAY(ctx, SAM_ENTRY1, num_entries);
|
||||
if ((*sam)->sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
ZERO_STRUCTP(sam->sam);
|
||||
ZERO_STRUCTP(sam->str);
|
||||
(*sam)->str=TALLOC_ARRAY(ctx, SAM_STR1, num_entries);
|
||||
if ((*sam)->str == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_entries ; i++) {
|
||||
const char *username;
|
||||
const char *fullname;
|
||||
const char *acct_desc;
|
||||
uint32 user_rid;
|
||||
const DOM_SID *user_sid;
|
||||
fstring user_sid_string, domain_sid_string;
|
||||
init_unistr2(&(*sam)->str[i].uni_acct_name,
|
||||
entries[i].account_name, UNI_FLAGS_NONE);
|
||||
init_unistr2(&(*sam)->str[i].uni_full_name,
|
||||
entries[i].fullname, UNI_FLAGS_NONE);
|
||||
init_unistr2(&(*sam)->str[i].uni_acct_desc,
|
||||
entries[i].description, UNI_FLAGS_NONE);
|
||||
|
||||
DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
|
||||
|
||||
pwd=&disp_user_info[i+start_idx];
|
||||
|
||||
username = pdb_get_username(pwd);
|
||||
fullname = pdb_get_fullname(pwd);
|
||||
acct_desc = pdb_get_acct_desc(pwd);
|
||||
|
||||
if (!username)
|
||||
username = "";
|
||||
|
||||
if (!fullname)
|
||||
fullname = "";
|
||||
|
||||
if (!acct_desc)
|
||||
acct_desc = "";
|
||||
|
||||
user_sid = pdb_get_user_sid(pwd);
|
||||
|
||||
if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
|
||||
DEBUG(0, ("init_sam_dispinfo_1: User %s has SID %s, which conflicts with "
|
||||
"the domain sid %s. Failing operation.\n",
|
||||
username,
|
||||
sid_to_string(user_sid_string, user_sid),
|
||||
sid_to_string(domain_sid_string, domain_sid)));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
init_unistr2(&sam->str[i].uni_acct_name, pdb_get_username(pwd), UNI_FLAGS_NONE);
|
||||
init_unistr2(&sam->str[i].uni_full_name, pdb_get_fullname(pwd), UNI_FLAGS_NONE);
|
||||
init_unistr2(&sam->str[i].uni_acct_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
|
||||
|
||||
init_sam_entry1(&sam->sam[i], start_idx + i + 1,
|
||||
&sam->str[i].uni_acct_name, &sam->str[i].uni_full_name, &sam->str[i].uni_acct_desc,
|
||||
user_rid, pdb_get_acct_ctrl(pwd));
|
||||
|
||||
init_sam_entry1(&(*sam)->sam[i], start_idx+i+1,
|
||||
&(*sam)->str[i].uni_acct_name,
|
||||
&(*sam)->str[i].uni_full_name,
|
||||
&(*sam)->str[i].uni_acct_desc,
|
||||
entries[i].rid, entries[i].acct_flags);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@ -1639,58 +1606,39 @@ static BOOL sam_io_sam_dispinfo_1(const char *desc, SAM_DISPINFO_1 * sam,
|
||||
inits a SAM_DISPINFO_2 structure.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
|
||||
uint32 start_idx, SAM_ACCOUNT *disp_user_info,
|
||||
DOM_SID *domain_sid )
|
||||
NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 **sam,
|
||||
uint32 num_entries, uint32 start_idx,
|
||||
struct samr_displayentry *entries)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
SAM_ACCOUNT *pwd = NULL;
|
||||
ZERO_STRUCTP(sam);
|
||||
|
||||
DEBUG(10, ("init_sam_dispinfo_2: num_entries: %d\n", num_entries));
|
||||
|
||||
if (num_entries==0)
|
||||
return NT_STATUS_OK;
|
||||
|
||||
if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY2, num_entries)))
|
||||
*sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_2, num_entries);
|
||||
if (*sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR2, num_entries)))
|
||||
(*sam)->sam = TALLOC_ARRAY(ctx, SAM_ENTRY2, num_entries);
|
||||
if ((*sam)->sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
ZERO_STRUCTP(sam->sam);
|
||||
ZERO_STRUCTP(sam->str);
|
||||
(*sam)->str=TALLOC_ARRAY(ctx, SAM_STR2, num_entries);
|
||||
if ((*sam)->str == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
uint32 user_rid;
|
||||
const DOM_SID *user_sid;
|
||||
const char *username;
|
||||
const char *acct_desc;
|
||||
fstring user_sid_string, domain_sid_string;
|
||||
init_unistr2(&(*sam)->str[i].uni_srv_name,
|
||||
entries[i].account_name, UNI_FLAGS_NONE);
|
||||
init_unistr2(&(*sam)->str[i].uni_srv_desc,
|
||||
entries[i].description, UNI_FLAGS_NONE);
|
||||
|
||||
DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
|
||||
pwd=&disp_user_info[i+start_idx];
|
||||
|
||||
username = pdb_get_username(pwd);
|
||||
acct_desc = pdb_get_acct_desc(pwd);
|
||||
user_sid = pdb_get_user_sid(pwd);
|
||||
|
||||
if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
|
||||
DEBUG(0, ("init_sam_dispinfo_2: User %s has SID %s, which conflicts with "
|
||||
"the domain sid %s. Failing operation.\n",
|
||||
username,
|
||||
sid_to_string(user_sid_string, user_sid),
|
||||
sid_to_string(domain_sid_string, domain_sid)));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
init_unistr2(&sam->str[i].uni_srv_name, username, UNI_FLAGS_NONE);
|
||||
init_unistr2(&sam->str[i].uni_srv_desc, acct_desc, UNI_FLAGS_NONE);
|
||||
|
||||
init_sam_entry2(&sam->sam[i], start_idx + i + 1,
|
||||
&sam->str[i].uni_srv_name, &sam->str[i].uni_srv_desc,
|
||||
user_rid, pdb_get_acct_ctrl(pwd));
|
||||
init_sam_entry2(&(*sam)->sam[i], start_idx + i + 1,
|
||||
&(*sam)->str[i].uni_srv_name,
|
||||
&(*sam)->str[i].uni_srv_desc,
|
||||
entries[i].rid, entries[i].acct_flags);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@ -1747,37 +1695,39 @@ static BOOL sam_io_sam_dispinfo_2(const char *desc, SAM_DISPINFO_2 * sam,
|
||||
inits a SAM_DISPINFO_3 structure.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
|
||||
uint32 start_idx, DOMAIN_GRP *disp_group_info)
|
||||
NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 **sam,
|
||||
uint32 num_entries, uint32 start_idx,
|
||||
struct samr_displayentry *entries)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
ZERO_STRUCTP(sam);
|
||||
|
||||
DEBUG(5, ("init_sam_dispinfo_3: num_entries: %d\n", num_entries));
|
||||
|
||||
if (num_entries==0)
|
||||
return NT_STATUS_OK;
|
||||
|
||||
if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY3, num_entries)))
|
||||
*sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_3, num_entries);
|
||||
if (*sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR3, num_entries)))
|
||||
if (!((*sam)->sam=TALLOC_ARRAY(ctx, SAM_ENTRY3, num_entries)))
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
ZERO_STRUCTP(sam->sam);
|
||||
ZERO_STRUCTP(sam->str);
|
||||
if (!((*sam)->str=TALLOC_ARRAY(ctx, SAM_STR3, num_entries)))
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
|
||||
|
||||
DEBUG(11, ("init_sam_dispinfo_3: entry: %d\n",i));
|
||||
|
||||
init_unistr2(&sam->str[i].uni_grp_name, grp->name, UNI_FLAGS_NONE);
|
||||
init_unistr2(&sam->str[i].uni_grp_desc, grp->comment, UNI_FLAGS_NONE);
|
||||
init_unistr2(&(*sam)->str[i].uni_grp_name,
|
||||
entries[i].account_name, UNI_FLAGS_NONE);
|
||||
init_unistr2(&(*sam)->str[i].uni_grp_desc,
|
||||
entries[i].description, UNI_FLAGS_NONE);
|
||||
|
||||
init_sam_entry3(&sam->sam[i], start_idx + i + 1, &sam->str[i].uni_grp_name,
|
||||
&sam->str[i].uni_grp_desc, grp->rid);
|
||||
init_sam_entry3(&(*sam)->sam[i], start_idx+i+1,
|
||||
&(*sam)->str[i].uni_grp_name,
|
||||
&(*sam)->str[i].uni_grp_desc,
|
||||
entries[i].rid);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@ -1834,38 +1784,40 @@ static BOOL sam_io_sam_dispinfo_3(const char *desc, SAM_DISPINFO_3 * sam,
|
||||
inits a SAM_DISPINFO_4 structure.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
|
||||
uint32 start_idx, SAM_ACCOUNT *disp_user_info)
|
||||
NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 **sam,
|
||||
uint32 num_entries, uint32 start_idx,
|
||||
struct samr_displayentry *entries)
|
||||
{
|
||||
uint32 len_sam_name;
|
||||
uint32 i;
|
||||
|
||||
SAM_ACCOUNT *pwd = NULL;
|
||||
ZERO_STRUCTP(sam);
|
||||
|
||||
DEBUG(5, ("init_sam_dispinfo_4: num_entries: %d\n", num_entries));
|
||||
|
||||
if (num_entries==0)
|
||||
return NT_STATUS_OK;
|
||||
|
||||
if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY4, num_entries)))
|
||||
*sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_4, num_entries);
|
||||
if (*sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR4, num_entries)))
|
||||
(*sam)->sam = TALLOC_ARRAY(ctx, SAM_ENTRY4, num_entries);
|
||||
if ((*sam)->sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
ZERO_STRUCTP(sam->sam);
|
||||
ZERO_STRUCTP(sam->str);
|
||||
(*sam)->str=TALLOC_ARRAY(ctx, SAM_STR4, num_entries);
|
||||
if ((*sam)->str == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
size_t len_sam_name = strlen(entries[i].account_name);
|
||||
|
||||
DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
|
||||
pwd=&disp_user_info[i+start_idx];
|
||||
|
||||
len_sam_name = strlen(pdb_get_username(pwd));
|
||||
|
||||
init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name);
|
||||
init_sam_entry4(&(*sam)->sam[i], start_idx + i + 1,
|
||||
len_sam_name);
|
||||
|
||||
init_string2(&sam->str[i].acct_name, pdb_get_username(pwd), len_sam_name+1, len_sam_name);
|
||||
init_string2(&(*sam)->str[i].acct_name,
|
||||
entries[i].account_name, len_sam_name+1,
|
||||
len_sam_name);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@ -1921,37 +1873,36 @@ static BOOL sam_io_sam_dispinfo_4(const char *desc, SAM_DISPINFO_4 * sam,
|
||||
inits a SAM_DISPINFO_5 structure.
|
||||
********************************************************************/
|
||||
|
||||
NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
|
||||
uint32 start_idx, DOMAIN_GRP *disp_group_info)
|
||||
NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 **sam,
|
||||
uint32 num_entries, uint32 start_idx,
|
||||
struct samr_displayentry *entries)
|
||||
{
|
||||
uint32 len_sam_name;
|
||||
uint32 i;
|
||||
|
||||
ZERO_STRUCTP(sam);
|
||||
|
||||
DEBUG(5, ("init_sam_dispinfo_5: num_entries: %d\n", num_entries));
|
||||
|
||||
if (num_entries==0)
|
||||
return NT_STATUS_OK;
|
||||
|
||||
if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY5, num_entries)))
|
||||
*sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_5, num_entries);
|
||||
if (*sam == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR5, num_entries)))
|
||||
if (!((*sam)->sam=TALLOC_ARRAY(ctx, SAM_ENTRY5, num_entries)))
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
ZERO_STRUCTP(sam->sam);
|
||||
ZERO_STRUCTP(sam->str);
|
||||
if (!((*sam)->str=TALLOC_ARRAY(ctx, SAM_STR5, num_entries)))
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
|
||||
|
||||
DEBUG(11, ("init_sam_dispinfo_5: entry: %d\n",i));
|
||||
|
||||
len_sam_name = strlen(grp->name);
|
||||
len_sam_name = strlen(entries[i].account_name);
|
||||
|
||||
init_sam_entry5(&sam->sam[i], start_idx + i + 1, len_sam_name);
|
||||
init_string2(&sam->str[i].grp_name, grp->name, len_sam_name+1, len_sam_name);
|
||||
init_sam_entry5(&(*sam)->sam[i], start_idx+i+1, len_sam_name);
|
||||
init_string2(&(*sam)->str[i].grp_name, entries[i].account_name,
|
||||
len_sam_name+1, len_sam_name);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user