struct winbindd_request request;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_SIDS2XIDS;
- request.extra_data.data = sids;
+ request.extra_data.data = (char *)sids;
request.extra_len = size;
do_async(mem_ctx, idmap_child(), &request, winbindd_sids2xids_recv,
(void *)cont, private_data);
DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state->pid));
+ if (state->request.extra_len == 0) {
+ DEBUG(0, ("Invalid buffer size!\n"));
+ return WINBINDD_ERROR;
+ }
+
sids = (DOM_SID *)state->request.extra_data.data;
num = state->request.extra_len / sizeof(DOM_SID);
- ids = talloc_zero_array(state->mem_ctx, struct id_map *, num + 1);
+ ids = TALLOC_ZERO_ARRAY(state->mem_ctx, struct id_map *, num + 1);
if ( ! ids) {
DEBUG(0, ("Out of memory!\n"));
return WINBINDD_ERROR;
}
for (i = 0; i < num; i++) {
- ids[i] = talloc(ids, struct id_map);
+ ids[i] = TALLOC_P(ids, struct id_map);
if ( ! ids[i]) {
DEBUG(0, ("Out of memory!\n"));
talloc_free(ids);
}
for (i = 0; i < num; i++) {
- if (ids[i]->mapped) {
+ if (ids[i]->status == ID_MAPPED) {
xids[i].type = ids[i]->xid.type;
xids[i].id = ids[i]->xid.id;
} else {
request.cmd = WINBINDD_DUAL_SID2GID;
sid_to_string(request.data.dual_sid2id.sid, sid);
- DEBUG(7,("idmap_sid2gid_async: Resolving %s to a gid\n",
+ DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
request.data.dual_sid2id.sid));
do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv,
return WINBINDD_OK;
}
-static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
+/********************************************************************
+ This is the second callback after contacting the forest root
+********************************************************************/
+
+static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success,
struct winbindd_response *response,
void *c, void *private_data)
{
(enum lsa_SidType)response->data.sid.type);
}
-void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name,
- const char *name,
+/********************************************************************
+ This is the first callback after contacting our own domain
+********************************************************************/
+
+static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const DOM_SID *sid,
+ enum lsa_SidType type) =
+ (void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
+ DOM_SID sid;
+
+ if (!success) {
+ DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
+ cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ /* Try again using the forest root */
+ struct winbindd_domain *root_domain = find_root_domain();
+ struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data;
+ struct winbindd_request request;
+ char *name_domain, *name_account;
+
+ if ( !root_domain ) {
+ DEBUG(5,("lookupname_recv: unable to determine forest root\n"));
+ cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ return;
+ }
+
+ name_domain = state->request.data.name.dom_name;
+ name_account = state->request.data.name.name;
+
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_LOOKUPNAME;
+ fstrcpy(request.data.name.dom_name, name_domain);
+ fstrcpy(request.data.name.name, name_account);
+
+ do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
+ (void *)cont, private_data);
+
+ return;
+ }
+
+ if (!string_to_sid(&sid, response->data.sid.sid)) {
+ DEBUG(0, ("Could not convert string %s to sid\n",
+ response->data.sid.sid));
+ cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ return;
+ }
+
+ cont(private_data, True, &sid,
+ (enum lsa_SidType)response->data.sid.type);
+}
+
+/********************************************************************
+ The lookup name call first contacts a DC in its own domain
+ and fallbacks to contact a DC in the forest in our domain doesn't
+ know the name.
+********************************************************************/
+
+void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
+ const char *dom_name, const char *name,
void (*cont)(void *private_data, BOOL success,
const DOM_SID *sid,
enum lsa_SidType type),
struct winbindd_request request;
struct winbindd_domain *domain;
- domain = find_lookup_domain_from_name(dom_name);
-
- if (domain == NULL) {
+ if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
DEBUG(5, ("Could not find domain for name %s\n", dom_name));
cont(private_data, False, NULL, SID_NAME_UNKNOWN);
return;
char *p;
/* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
+ state->request.data.name.dom_name[sizeof(state->request.data.name.dom_name)-1]='\0';
/* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
+ state->request.data.name.name[sizeof(state->request.data.name.name)-1]='\0';
/* cope with the name being a fully qualified name */
p = strstr(state->request.data.name.name, lp_winbind_separator());
DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
name_domain, lp_winbind_separator(), name_user));
- /* Lookup name from PDC using lsa_lookup_names() */
+ /* Lookup name from DC using lsa_lookup_names() */
if (!winbindd_lookup_sid_by_name(state->mem_ctx, domain, name_domain,
name_user, &sid, &type)) {
return WINBINDD_ERROR;
{
DOM_SID *sids = NULL;
size_t num_sids = 0;
- char *sidstr;
+ char *sidstr = NULL;
ssize_t len;
size_t i;
uint32 num_aliases;
DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));
sidstr = state->request.extra_data.data;
- if (sidstr == NULL)
+ if (sidstr == NULL) {
sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */
+ if (!sidstr) {
+ DEBUG(0, ("Out of memory\n"));
+ return WINBINDD_ERROR;
+ }
+ }
DEBUG(10, ("Sidlist: %s\n", sidstr));
num_sids = 0;
sids = NULL;
+ sidstr = NULL;
DEBUG(10, ("Got %d aliases\n", num_aliases));
}
- if (!print_sidlist(NULL, sids, num_sids, &sidstr, &len)) {
+ if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) {
DEBUG(0, ("Could not print_sidlist\n"));
state->response.extra_data.data = NULL;
return WINBINDD_ERROR;
}
- state->response.extra_data.data = sidstr;
+ state->response.extra_data.data = NULL;
- if (state->response.extra_data.data != NULL) {
+ if (sidstr) {
+ state->response.extra_data.data = SMB_STRDUP(sidstr);
+ if (!state->response.extra_data.data) {
+ DEBUG(0, ("Out of memory\n"));
+ return WINBINDD_ERROR;
+ }
DEBUG(10, ("aliases_list: %s\n",
(char *)state->response.extra_data.data));
state->response.length += len+1;
{
void (*cont)(void *priv, BOOL succ, const char *acct_name,
const char *full_name, const char *homedir,
- const char *shell, uint32 group_rid) =
+ const char *shell, uint32 gid, uint32 group_rid) =
(void (*)(void *, BOOL, const char *, const char *,
- const char *, const char *, uint32))c;
+ const char *, const char *, uint32, uint32))c;
if (!success) {
DEBUG(5, ("Could not trigger query_user\n"));
- cont(private_data, False, NULL, NULL, NULL, NULL, -1);
+ cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1);
return;
}
response->data.user_info.full_name,
response->data.user_info.homedir,
response->data.user_info.shell,
+ response->data.user_info.primary_gid,
response->data.user_info.group_rid);
}
const char *full_name,
const char *homedir,
const char *shell,
+ gid_t gid,
uint32 group_rid),
void *private_data)
{
struct winbindd_request request;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_DUMP_MAPS;
- request.extra_data.data = data;
+ request.extra_data.data = (char *)data;
request.extra_len = size;
do_async(mem_ctx, idmap_child(), &request, winbindd_dump_id_maps_recv,
(void *)cont, private_data);