diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index a13a293e7af..5e38a84d65b 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -224,7 +224,11 @@ static void msg_shutdown(int msg_type, pid_t src, void *buf, size_t len) terminate(); } -static struct winbindd_dispatch_table dispatch_table[] = { +static struct winbindd_dispatch_table { + enum winbindd_cmd cmd; + void (*fn)(struct winbindd_cli_state *state); + const char *winbindd_cmd_name; +} dispatch_table[] = { /* User functions */ @@ -326,7 +330,7 @@ static void process_request(struct winbindd_cli_state *state) if (state->request.cmd == table->cmd) { DEBUG(10,("process_request: request fn %s\n", table->winbindd_cmd_name )); - state->response.result = table->fn(state); + table->fn(state); break; } } @@ -334,7 +338,7 @@ static void process_request(struct winbindd_cli_state *state) if (!table->fn) { DEBUG(10,("process_request: unknown request fn number %d\n", (int)state->request.cmd )); - state->response.result = WINBINDD_ERROR; + request_error(state); } } @@ -458,7 +462,7 @@ void setup_async_write(struct fd_event *event, void *data, size_t length, static void request_len_recv(void *private, BOOL success); static void request_recv(void *private, BOOL success); -void request_finished(struct winbindd_cli_state *state); +static void request_finished(struct winbindd_cli_state *state); void request_finished_cont(void *private, BOOL success); static void response_main_sent(void *private, BOOL success); static void response_extra_sent(void *private, BOOL success); @@ -510,20 +514,35 @@ static void response_main_sent(void *private, BOOL success) response_extra_sent, state); } -void request_finished(struct winbindd_cli_state *state) +static void request_finished(struct winbindd_cli_state *state) { setup_async_write(&state->fd_event, &state->response, sizeof(state->response), response_main_sent, state); } +void request_error(struct winbindd_cli_state *state) +{ + SMB_ASSERT(state->response.result == WINBINDD_PENDING); + state->response.result = WINBINDD_ERROR; + request_finished(state); +} + +void request_ok(struct winbindd_cli_state *state) +{ + SMB_ASSERT(state->response.result == WINBINDD_PENDING); + state->response.result = WINBINDD_OK; + request_finished(state); +} + void request_finished_cont(void *private, BOOL success) { struct winbindd_cli_state *state = talloc_get_type_abort(private, struct winbindd_cli_state); - if (!success) - state->response.result = WINBINDD_ERROR; - request_finished(state); + if (success) + request_ok(state); + else + request_error(state); } static void request_recv(void *private, BOOL success) @@ -537,9 +556,6 @@ static void request_recv(void *private, BOOL success) } process_request(state); - - if (state->response.result != WINBINDD_PENDING) - request_finished(state); } static void request_len_recv(void *private, BOOL success) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index c8d2ebf686c..d000168b1f6 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -98,12 +98,6 @@ struct winbindd_state { gid_t gid_low, gid_high; /* Range of gids to allocate */ }; -struct winbindd_dispatch_table { - enum winbindd_cmd cmd; - enum winbindd_result (*fn)(struct winbindd_cli_state *state); - const char *winbindd_cmd_name; -}; - extern struct winbindd_state server_state; /* Server information */ typedef struct { diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c index e1ed2d67633..2b0ce8c14d3 100644 --- a/source3/nsswitch/winbindd_dual.c +++ b/source3/nsswitch/winbindd_dual.c @@ -332,6 +332,7 @@ static void async_reply_recv(void *private, BOOL success) if (!success) { DEBUG(5, ("Could not receive async reply\n")); state->response->result = WINBINDD_ERROR; + return; } if (state->response->result == WINBINDD_OK) @@ -420,6 +421,41 @@ void async_domain_request(TALLOC_CTX *mem_ctx, init_child_connection(domain, domain_init_recv, state); } +static void recvfrom_child(void *private, BOOL success) +{ + struct winbindd_cli_state *state = + talloc_get_type_abort(private, struct winbindd_cli_state); + enum winbindd_result result = state->response.result; + + /* This is an optimization: The child has written directly to the + * response buffer. The request itself is still in pending state, + * state that in the result code. */ + + state->response.result = WINBINDD_PENDING; + + if ((!success) || (result != WINBINDD_OK)) { + request_error(state); + return; + } + + request_ok(state); +} + +void sendto_child(struct winbindd_cli_state *state, + struct winbindd_child *child) +{ + async_request(state->mem_ctx, child, &state->request, + &state->response, recvfrom_child, state); +} + +void sendto_domain(struct winbindd_cli_state *state, + struct winbindd_domain *domain) +{ + async_domain_request(state->mem_ctx, domain, + &state->request, &state->response, + recvfrom_child, state); +} + static void domain_init_recv(void *private, BOOL success) { struct domain_request_state *state = diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 1138762cc40..2751f06815f 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -199,7 +199,7 @@ done: /* Return a group structure from a group name */ -enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) +void winbindd_getgrnam(struct winbindd_cli_state *state) { DOM_SID group_sid; struct winbindd_domain *domain; @@ -235,14 +235,16 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(3, ("could not get domain sid for domain %s\n", name_domain)); - return WINBINDD_ERROR; + request_error(state); + return; } /* should we deal with users for our domain? */ if ( lp_winbind_trusted_domains_only() && domain->primary) { DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n", name_domain, name_group)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get rid and name type from name */ @@ -251,7 +253,8 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) name_group, &group_sid, &name_type)) { DEBUG(1, ("group %s in domain %s does not exist\n", name_group, name_domain)); - return WINBINDD_ERROR; + request_error(state); + return; } if ( !((name_type==SID_NAME_DOM_GRP) || @@ -260,12 +263,14 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", name_group, name_type)); - return WINBINDD_ERROR; + request_error(state); + return; } if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid, 0))) { DEBUG(1, ("error converting unix gid to sid\n")); - return WINBINDD_ERROR; + request_error(state); + return; } if (!fill_grent(&state->response.data.gr, name_domain, @@ -273,7 +278,8 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) !fill_grent_mem(domain, &group_sid, name_type, &state->response.data.gr.num_gr_mem, &gr_mem, &gr_mem_len)) { - return WINBINDD_ERROR; + request_error(state); + return; } /* Group membership lives at start of extra data */ @@ -282,13 +288,12 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) state->response.length += gr_mem_len; state->response.extra_data = gr_mem; - - return WINBINDD_OK; + request_ok(state); } /* Return a group structure from a gid number */ -enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) +void winbindd_getgrgid(struct winbindd_cli_state *state) { struct winbindd_domain *domain; DOM_SID group_sid; @@ -304,14 +309,17 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) /* Bug out if the gid isn't in the winbind range */ if ((state->request.data.gid < server_state.gid_low) || - (state->request.data.gid > server_state.gid_high)) - return WINBINDD_ERROR; + (state->request.data.gid > server_state.gid_high)) { + request_error(state); + return; + } /* Get rid from gid */ if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid, 0))) { DEBUG(1, ("could not convert gid %lu to rid\n", (unsigned long)state->request.data.gid)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get name from sid */ @@ -319,7 +327,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) if (!winbindd_lookup_name_by_sid(state->mem_ctx, &group_sid, dom_name, group_name, &name_type)) { DEBUG(1, ("could not lookup sid\n")); - return WINBINDD_ERROR; + request_error(state); + return; } /* Fill in group structure */ @@ -328,7 +337,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) if (!domain) { DEBUG(1,("Can't find domain from sid\n")); - return WINBINDD_ERROR; + request_error(state); + return; } if ( !((name_type==SID_NAME_DOM_GRP) || @@ -337,15 +347,18 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", group_name, name_type)); - return WINBINDD_ERROR; + request_error(state); + return; } if (!fill_grent(&state->response.data.gr, dom_name, group_name, state->request.data.gid) || !fill_grent_mem(domain, &group_sid, name_type, &state->response.data.gr.num_gr_mem, - &gr_mem, &gr_mem_len)) - return WINBINDD_ERROR; + &gr_mem, &gr_mem_len)) { + request_error(state); + return; + } /* Group membership lives at start of extra data */ @@ -353,8 +366,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) state->response.length += gr_mem_len; state->response.extra_data = gr_mem; - - return WINBINDD_OK; + request_ok(state); } /* @@ -363,7 +375,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) /* "Rewind" file pointer for group database enumeration */ -enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) +void winbindd_setgrent(struct winbindd_cli_state *state) { struct winbindd_domain *domain; @@ -371,8 +383,10 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) /* Check user has enabled this */ - if (!lp_winbind_enum_groups()) - return WINBINDD_ERROR; + if (!lp_winbind_enum_groups()) { + request_error(state); + return; + } /* Free old static data if it exists */ @@ -399,7 +413,8 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n")); - return WINBINDD_ERROR; + request_error(state); + return; } ZERO_STRUCTP(domain_state); @@ -412,21 +427,19 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) } state->getgrent_initialized = True; - - return WINBINDD_OK; + request_ok(state); } /* Close file pointer to ntdom group database */ -enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state) +void winbindd_endgrent(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: endgrent\n", (unsigned long)state->pid)); free_getent_state(state->getgrent_state); state->getgrent_initialized = False; state->getgrent_state = NULL; - - return WINBINDD_OK; + request_ok(state); } /* Get the list of domain groups and domain aliases for a domain. We fill in @@ -548,7 +561,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent) #define MAX_GETGRENT_GROUPS 500 -enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) +void winbindd_getgrent(struct winbindd_cli_state *state) { struct getent_state *ent; struct winbindd_gr *group_list = NULL; @@ -559,13 +572,17 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) /* Check user has enabled this */ - if (!lp_winbind_enum_groups()) - return WINBINDD_ERROR; + if (!lp_winbind_enum_groups()) { + request_error(state); + return; + } num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries); - if ((state->response.extra_data = SMB_MALLOC_ARRAY(struct winbindd_gr, num_groups)) == NULL) - return WINBINDD_ERROR; + if ((state->response.extra_data = SMB_MALLOC_ARRAY(struct winbindd_gr, num_groups)) == NULL) { + request_error(state); + return; + } memset(state->response.extra_data, '\0', num_groups * sizeof(struct winbindd_gr) ); @@ -577,8 +594,10 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) if (!state->getgrent_initialized) winbindd_setgrent(state); - if (!(ent = state->getgrent_state)) - return WINBINDD_ERROR; + if (!(ent = state->getgrent_state)) { + request_error(state); + return; + } /* Start sending back groups */ @@ -744,8 +763,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) group_list_ndx = 0; SAFE_FREE(state->response.extra_data); SAFE_FREE(gr_mem_list); - - return WINBINDD_ERROR; + request_error(state); + return; } state->response.extra_data = new_extra_data; @@ -765,12 +784,15 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) done: - return (group_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR; + if (group_list_ndx > 0) + request_ok(state); + else + request_error(state); } /* List domain groups without mapping to unix ids */ -enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) +void winbindd_list_groups(struct winbindd_cli_state *state) { uint32 total_entries = 0; struct winbindd_domain *domain; @@ -821,7 +843,8 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) if (!ted) { DEBUG(0,("failed to enlarge buffer!\n")); SAFE_FREE(extra_data); - return WINBINDD_ERROR; + request_error(state); + return; } else extra_data = ted; @@ -852,7 +875,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) /* No domains may have responded but that's still OK so don't return an error. */ - return WINBINDD_OK; + request_ok(state); } /* Get user supplementary groups. This is much quicker than trying to @@ -881,7 +904,7 @@ static void getgroups_tokensids_recv(void *private, BOOL success, DOM_SID *token_sids, int num_token_sids); static void getgroups_sid2gid_recv(void *private, BOOL success, gid_t gid); -enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) +void winbindd_getgroups(struct winbindd_cli_state *state) { struct getgroups_state *s; @@ -897,7 +920,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) s = TALLOC_P(state->mem_ctx, struct getgroups_state); if (s == NULL) { DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } s->state = state; @@ -907,7 +931,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) &s->domname, &s->username)) { DEBUG(0, ("Could not parse domain user: %s\n", state->request.data.username)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get info for the domain */ @@ -917,21 +942,22 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) if (s->domain == NULL) { DEBUG(7, ("could not find domain entry for domain %s\n", s->domname)); - return WINBINDD_ERROR; + request_error(state); + return; } if ( s->domain->primary && lp_winbind_trusted_domains_only()) { DEBUG(7,("winbindd_getpwnam: My domain -- rejecting " "getgroups() for %s\\%s.\n", s->domname, s->username)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get rid and name type from name. The following costs 1 packet */ winbindd_lookupname_async(state->mem_ctx, s->domname, s->username, getgroups_usersid_recv, s); - return WINBINDD_PENDING; } static void getgroups_usersid_recv(void *private, BOOL success, @@ -941,8 +967,7 @@ static void getgroups_usersid_recv(void *private, BOOL success, if ((!success) || ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER))) { - s->state->response.result = WINBINDD_ERROR; - request_finished(s->state); + request_error(s->state); return; } @@ -961,8 +986,7 @@ static void getgroups_tokensids_recv(void *private, BOOL success, * otherwise it's an error */ if ((!success) || (num_token_sids < 2)) { - s->state->response.result = WINBINDD_ERROR; - request_finished(s->state); + request_error(s->state); return; } @@ -1002,8 +1026,7 @@ static void getgroups_sid2gid_recv(void *private, BOOL success, gid_t gid) s->state->response.data.num_entries = s->num_token_gids; s->state->response.extra_data = s->token_gids; s->state->response.length += s->num_token_gids * sizeof(gid_t); - s->state->response.result = WINBINDD_OK; - request_finished(s->state); + request_ok(s->state); } /* Get user supplementary sids. This is equivalent to the @@ -1021,7 +1044,7 @@ static void getgroups_sid2gid_recv(void *private, BOOL success, gid_t gid) static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, int num_sids); -enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) +void winbindd_getusersids(struct winbindd_cli_state *state) { DOM_SID *user_sid; @@ -1031,18 +1054,19 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) user_sid = TALLOC_P(state->mem_ctx, DOM_SID); if (user_sid == NULL) { DEBUG(1, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } if (!string_to_sid(user_sid, state->request.data.sid)) { DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); - return WINBINDD_ERROR; + request_error(state); + return; } winbindd_gettoken_async(state->mem_ctx, user_sid, getusersids_recv, state); - return WINBINDD_PENDING; } static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, @@ -1053,10 +1077,10 @@ static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, unsigned ofs, ret_size = 0; int i; - state->response.result = WINBINDD_ERROR; - - if (!success) - goto done; + if (!success) { + request_error(state); + return; + } /* work out the response size */ for (i = 0; i < num_sids; i++) { @@ -1066,7 +1090,11 @@ static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, /* build the reply */ ret = SMB_MALLOC(ret_size); - if (!ret) goto done; + if (!ret) { + DEBUG(0, ("malloc failed\n")); + request_error(state); + return; + } ofs = 0; for (i = 0; i < num_sids; i++) { const char *s = sid_string_static(&sids[i]); @@ -1078,13 +1106,10 @@ static void getusersids_recv(void *private, BOOL success, DOM_SID *sids, state->response.data.num_entries = num_sids; state->response.extra_data = ret; state->response.length += ret_size; - state->response.result = WINBINDD_OK; - - done: - request_finished(state); + request_ok(state); } -enum winbindd_result winbindd_getuserdomgroups(struct winbindd_cli_state *state) +void winbindd_getuserdomgroups(struct winbindd_cli_state *state) { DOM_SID user_sid; struct winbindd_domain *domain; @@ -1095,19 +1120,19 @@ enum winbindd_result winbindd_getuserdomgroups(struct winbindd_cli_state *state) if (!string_to_sid(&user_sid, state->request.data.sid)) { DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get info for the domain */ if ((domain = find_domain_from_sid_noinit(&user_sid)) == NULL) { DEBUG(0,("could not find domain entry for sid %s\n", sid_string_static(&user_sid))); - return WINBINDD_ERROR; + request_error(state); + return; } - async_domain_request(state->mem_ctx, domain, &state->request, - &state->response, request_finished_cont, state); - return WINBINDD_PENDING; + sendto_domain(state, domain); } enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain, diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 9cfa4c6fcc4..7a02c8f6293 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -29,15 +29,12 @@ /* Check the machine account password is valid */ -enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state) +void winbindd_check_machine_acct(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid)); - async_domain_request(state->mem_ctx, find_our_domain(), - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_domain(state, find_our_domain()); } enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain, @@ -105,15 +102,12 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } -enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state *state) +void winbindd_list_trusted_domains(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); - async_domain_request(state->mem_ctx, find_our_domain(), - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_domain(state, find_our_domain()); } enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, @@ -159,7 +153,7 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * return WINBINDD_OK; } -enum winbindd_result winbindd_getdcname(struct winbindd_cli_state *state) +void winbindd_getdcname(struct winbindd_cli_state *state) { state->request.domain_name [sizeof(state->request.domain_name)-1] = '\0'; @@ -167,10 +161,7 @@ enum winbindd_result winbindd_getdcname(struct winbindd_cli_state *state) DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid, state->request.domain_name)); - async_domain_request(state->mem_ctx, find_our_domain(), - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_domain(state, find_our_domain()); } enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, @@ -230,7 +221,7 @@ struct sequence_state { static void sequence_recv(void *private, BOOL success); -enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) +void winbindd_show_sequence(struct winbindd_cli_state *state) { struct sequence_state *seq; @@ -241,12 +232,12 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) struct winbindd_domain *domain; domain = find_domain_from_name_noinit( state->request.domain_name); - if (domain == NULL) - return WINBINDD_ERROR; - async_domain_request(state->mem_ctx, domain, - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + if (domain == NULL) { + request_error(state); + return; + } + sendto_domain(state, domain); + return; } /* Ask all domains in sequence, collect the results in sequence_recv */ @@ -254,7 +245,8 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) seq = TALLOC_P(state->mem_ctx, struct sequence_state); if (seq == NULL) { DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } seq->mem_ctx = state->mem_ctx; @@ -262,7 +254,8 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) seq->domain = domain_list(); if (seq->domain == NULL) { DEBUG(0, ("domain list empty\n")); - return WINBINDD_ERROR; + request_error(state); + return; } seq->request = TALLOC_ZERO_P(state->mem_ctx, struct winbindd_request); @@ -273,7 +266,8 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) if ((seq->request == NULL) || (seq->response == NULL) || (seq->extra_data == NULL)) { DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } seq->request->length = sizeof(*seq->request); @@ -283,7 +277,6 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) async_domain_request(state->mem_ctx, seq->domain, seq->request, seq->response, sequence_recv, seq); - return WINBINDD_PENDING; } static void sequence_recv(void *private, BOOL success) @@ -312,13 +305,12 @@ static void sequence_recv(void *private, BOOL success) if (state->domain == NULL) { struct winbindd_cli_state *cli_state = state->cli_state; - cli_state->response.result = WINBINDD_OK; cli_state->response.length = sizeof(cli_state->response) + strlen(state->extra_data) + 1; cli_state->response.extra_data = SMB_STRDUP(state->extra_data); - request_finished(cli_state); + request_ok(cli_state); return; } @@ -355,7 +347,7 @@ struct domain_info_state { static void domain_info_init_recv(void *private, BOOL success); -enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state) +void winbindd_domain_info(struct winbindd_cli_state *state) { struct winbindd_domain *domain; @@ -367,7 +359,8 @@ enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state) if (domain == NULL) { DEBUG(3, ("Did not find domain [%s]\n", state->request.domain_name)); - return WINBINDD_ERROR; + request_error(state); + return; } if (!domain->initialized) { @@ -376,7 +369,8 @@ enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state) istate = TALLOC_P(state->mem_ctx, struct domain_info_state); if (istate == NULL) { DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } istate->cli_state = state; @@ -384,41 +378,6 @@ enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state) init_child_connection(domain, domain_info_init_recv, istate); - return WINBINDD_PENDING; - } - - fstrcpy(state->response.data.domain_info.name, - domain->name); - fstrcpy(state->response.data.domain_info.alt_name, - domain->alt_name); - fstrcpy(state->response.data.domain_info.sid, - sid_string_static(&domain->sid)); - - state->response.data.domain_info.native_mode = - domain->native_mode; - state->response.data.domain_info.active_directory = - domain->active_directory; - state->response.data.domain_info.primary = - domain->primary; - state->response.data.domain_info.sequence_number = - domain->sequence_number; - - return WINBINDD_OK; -} - -static void domain_info_init_recv(void *private, BOOL success) -{ - struct domain_info_state *istate = private; - struct winbindd_cli_state *state = istate->cli_state; - struct winbindd_domain *domain = istate->domain; - - DEBUG(10, ("Got back from child init: %d\n", success)); - - if ((!success) || (!domain->initialized)) { - DEBUG(5, ("Could not init child for domain %s\n", - domain->name)); - state->response.result = WINBINDD_ERROR; - request_finished_cont(state, False); return; } @@ -438,80 +397,111 @@ static void domain_info_init_recv(void *private, BOOL success) state->response.data.domain_info.sequence_number = domain->sequence_number; - state->response.result = WINBINDD_OK; - request_finished_cont(state, True); + request_ok(state); } -enum winbindd_result winbindd_ping(struct winbindd_cli_state - *state) +static void domain_info_init_recv(void *private, BOOL success) +{ + struct domain_info_state *istate = private; + struct winbindd_cli_state *state = istate->cli_state; + struct winbindd_domain *domain = istate->domain; + + DEBUG(10, ("Got back from child init: %d\n", success)); + + if ((!success) || (!domain->initialized)) { + DEBUG(5, ("Could not init child for domain %s\n", + domain->name)); + request_error(state); + return; + } + + fstrcpy(state->response.data.domain_info.name, + domain->name); + fstrcpy(state->response.data.domain_info.alt_name, + domain->alt_name); + fstrcpy(state->response.data.domain_info.sid, + sid_string_static(&domain->sid)); + + state->response.data.domain_info.native_mode = + domain->native_mode; + state->response.data.domain_info.active_directory = + domain->active_directory; + state->response.data.domain_info.primary = + domain->primary; + state->response.data.domain_info.sequence_number = + domain->sequence_number; + + request_ok(state); +} + +void winbindd_ping(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid)); - - return WINBINDD_OK; + request_ok(state); } /* List various tidbits of information */ -enum winbindd_result winbindd_info(struct winbindd_cli_state *state) +void winbindd_info(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid)); state->response.data.info.winbind_separator = *lp_winbind_separator(); fstrcpy(state->response.data.info.samba_version, SAMBA_VERSION_STRING); - - return WINBINDD_OK; + request_ok(state); } /* Tell the client the current interface version */ -enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state) +void winbindd_interface_version(struct winbindd_cli_state *state) { - - DEBUG(3, ("[%5lu]: request interface version\n", (unsigned long)state->pid)); + DEBUG(3, ("[%5lu]: request interface version\n", + (unsigned long)state->pid)); state->response.data.interface_version = WINBIND_INTERFACE_VERSION; - - return WINBINDD_OK; + request_ok(state); } /* What domain are we a member of? */ -enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state) +void winbindd_domain_name(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid)); fstrcpy(state->response.data.domain_name, lp_workgroup()); - - return WINBINDD_OK; + request_ok(state); } /* What's my name again? */ -enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state) +void winbindd_netbios_name(struct winbindd_cli_state *state) { - - DEBUG(3, ("[%5lu]: request netbios name\n", (unsigned long)state->pid)); + DEBUG(3, ("[%5lu]: request netbios name\n", + (unsigned long)state->pid)); fstrcpy(state->response.data.netbios_name, global_myname()); - - return WINBINDD_OK; + request_ok(state); } /* Where can I find the privilaged pipe? */ -enum winbindd_result winbindd_priv_pipe_dir(struct winbindd_cli_state *state) +void winbindd_priv_pipe_dir(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5lu]: request location of privileged pipe\n", (unsigned long)state->pid)); + DEBUG(3, ("[%5lu]: request location of privileged pipe\n", + (unsigned long)state->pid)); state->response.extra_data = SMB_STRDUP(get_winbind_priv_pipe_dir()); - if (!state->response.extra_data) - return WINBINDD_ERROR; + if (!state->response.extra_data) { + DEBUG(0, ("malloc failed\n")); + request_error(state); + return; + } /* must add one to length to copy the 0 for string termination */ - state->response.length += strlen((char *)state->response.extra_data) + 1; + state->response.length += + strlen((char *)state->response.extra_data) + 1; - return WINBINDD_OK; + request_ok(state); } diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 47affa66fbd..4797ba79f4f 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -185,7 +185,7 @@ static void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) Authenticate a user with a clear text password **********************************************************************/ -enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) +void winbindd_pam_auth(struct winbindd_cli_state *state) { struct winbindd_domain *domain; fstring name_domain, name_user; @@ -215,13 +215,11 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) state->request.data.auth.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); - return WINBINDD_ERROR; + request_error(state); + return; } - async_domain_request(state->mem_ctx, domain, - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_domain(state, domain); } enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, @@ -500,7 +498,7 @@ done: Challenge Response Authentication Protocol **********************************************************************/ -enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) +void winbindd_pam_auth_crap(struct winbindd_cli_state *state) { struct winbindd_domain *domain = NULL; const char *domain_name = NULL; @@ -546,10 +544,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) domain = find_auth_domain(domain_name); if (domain != NULL) { - async_domain_request(state->mem_ctx, domain, - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_domain(state, domain); + return; } result = NT_STATUS_NO_SUCH_USER; @@ -560,7 +556,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) state->request.data.auth.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); - return WINBINDD_ERROR; + request_error(state); + return; } @@ -802,7 +799,7 @@ done: /* Change a user password */ -enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) +void winbindd_pam_chauthtok(struct winbindd_cli_state *state) { NTSTATUS result; char *oldpass, *newpass; @@ -816,9 +813,6 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) /* Setup crap */ - if (state == NULL) - return WINBINDD_ERROR; - parse_domain_user(state->request.data.chauthtok.user, domain, user); if (!(contact_domain = find_domain_from_name(domain))) { @@ -858,5 +852,8 @@ done: state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); - return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; + if (NT_STATUS_IS_OK(result)) + request_ok(state); + else + request_error(state); } diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index f8fb5e93c2e..9bad2a6d414 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -32,7 +32,7 @@ static void lookupsid_recv(void *private, BOOL success, const char *dom_name, const char *name, enum SID_NAME_USE type); -enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) +void winbindd_lookupsid(struct winbindd_cli_state *state) { DOM_SID sid; @@ -44,11 +44,11 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) if (!string_to_sid(&sid, state->request.data.sid)) { DEBUG(5, ("%s not a SID\n", state->request.data.sid)); - return WINBINDD_ERROR; + request_error(state); + return; } winbindd_lookupsid_async(state->mem_ctx, &sid, lookupsid_recv, state); - return WINBINDD_PENDING; } static void lookupsid_recv(void *private, BOOL success, @@ -60,16 +60,14 @@ static void lookupsid_recv(void *private, BOOL success, if (!success) { DEBUG(5, ("lookupsid returned an error\n")); - state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); return; } fstrcpy(state->response.data.name.dom_name, dom_name); fstrcpy(state->response.data.name.name, name); state->response.data.name.type = type; - state->response.result = WINBINDD_OK; - request_finished(state); + request_ok(state); } /** @@ -79,7 +77,7 @@ static void lookupsid_recv(void *private, BOOL success, static void lookupname_recv(void *private, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); -enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) +void winbindd_lookupname(struct winbindd_cli_state *state) { char *name_domain, *name_user; char *p; @@ -106,7 +104,6 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) winbindd_lookupname_async(state->mem_ctx, name_domain, name_user, lookupname_recv, state); - return WINBINDD_PENDING; } static void lookupname_recv(void *private, BOOL success, @@ -117,15 +114,13 @@ static void lookupname_recv(void *private, BOOL success, if (!success) { DEBUG(5, ("lookupname returned an error\n")); - state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); return; } sid_to_string(state->response.data.sid.sid, sid); state->response.data.sid.type = type; - state->response.result = WINBINDD_OK; - request_finished(state); + request_ok(state); return; } @@ -146,7 +141,7 @@ struct winbindd_child *idmap_child(void) static void sid2uid_recv(void *private, BOOL success, uid_t uid); -enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) +void winbindd_sid_to_uid(struct winbindd_cli_state *state) { DOM_SID sid; NTSTATUS result; @@ -159,13 +154,15 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) if (idmap_proxyonly()) { DEBUG(8, ("IDMAP proxy only\n")); - return WINBINDD_ERROR; + request_error(state); + return; } if (!string_to_sid(&sid, state->request.data.sid)) { DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Query only the local tdb, everything else might possibly block */ @@ -174,11 +171,11 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) ID_QUERY_ONLY|ID_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { - return WINBINDD_OK; + request_ok(state); + return; } winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state); - return WINBINDD_PENDING; } static void sid2uid_recv(void *private, BOOL success, uid_t uid) @@ -189,14 +186,12 @@ static void sid2uid_recv(void *private, BOOL success, uid_t uid) if (!success) { DEBUG(5, ("Could not convert sid %s\n", state->request.data.sid)); - state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); return; } - state->response.result = WINBINDD_OK; state->response.data.uid = uid; - request_finished(state); + request_ok(state); } /* Convert a sid to a gid. We assume we only have one rid attached to the @@ -204,7 +199,7 @@ static void sid2uid_recv(void *private, BOOL success, uid_t uid) static void sid2gid_recv(void *private, BOOL success, gid_t gid); -enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) +void winbindd_sid_to_gid(struct winbindd_cli_state *state) { DOM_SID sid; NTSTATUS result; @@ -217,13 +212,15 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) if (idmap_proxyonly()) { DEBUG(8, ("IDMAP proxy only\n")); - return WINBINDD_ERROR; + request_error(state); + return; } if (!string_to_sid(&sid, state->request.data.sid)) { DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Query only the local tdb, everything else might possibly block */ @@ -232,11 +229,11 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) ID_QUERY_ONLY|ID_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { - return WINBINDD_OK; + request_ok(state); + return; } winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state); - return WINBINDD_PENDING; } static void sid2gid_recv(void *private, BOOL success, gid_t gid) @@ -247,14 +244,12 @@ static void sid2gid_recv(void *private, BOOL success, gid_t gid) if (!success) { DEBUG(5, ("Could not convert sid %s\n", state->request.data.sid)); - state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); return; } - state->response.result = WINBINDD_OK; state->response.data.gid = gid; - request_finished(state); + request_ok(state); } /* Convert a uid to a sid */ @@ -274,7 +269,7 @@ static void uid2sid_lookupname_recv(void *private, BOOL success, enum SID_NAME_USE type); static void uid2sid_idmap_set_mapping_recv(void *private, BOOL success); -enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) +void winbindd_uid_to_sid(struct winbindd_cli_state *state) { DOM_SID sid; NTSTATUS status; @@ -285,7 +280,8 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) if (idmap_proxyonly()) { DEBUG(8, ("IDMAP proxy only\n")); - return WINBINDD_ERROR; + request_error(state); + return; } status = idmap_uid_to_sid(&sid, state->request.data.uid, @@ -294,20 +290,23 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) if (NT_STATUS_IS_OK(status)) { sid_to_string(state->response.data.sid.sid, &sid); state->response.data.sid.type = SID_NAME_USER; - return WINBINDD_OK; + request_ok(state); + return; } if (is_in_uid_range(state->request.data.uid)) { /* This is winbind's, so we should better have succeeded * above. */ - return WINBINDD_ERROR; + request_error(state); + return; } /* The only chance that this is correct is that winbind trusted * domains only = yes, and the user exists in nss and the domain. */ if (!lp_winbind_trusted_domains_only()) { - return WINBINDD_ERROR; + request_error(state); + return; } /* The only chance that this is correct is that winbind trusted @@ -316,7 +315,8 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) uid2sid_state = TALLOC_ZERO_P(state->mem_ctx, struct uid2sid_state); if (uid2sid_state == NULL) { DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } uid2sid_state->cli_state = state; @@ -324,7 +324,6 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) winbindd_uid2name_async(state->mem_ctx, state->request.data.uid, uid2sid_uid2name_recv, uid2sid_state); - return WINBINDD_PENDING; } static void uid2sid_uid2name_recv(void *private, BOOL success, @@ -339,8 +338,7 @@ static void uid2sid_uid2name_recv(void *private, BOOL success, fstrcpy(state->name, username); if (!success) { - state->cli_state->response.result = WINBINDD_ERROR; - request_finished(state->cli_state); + request_error(state->cli_state); return; } @@ -357,8 +355,7 @@ static void uid2sid_lookupname_recv(void *private, BOOL success, unid_t id; if ((!success) || (type != SID_NAME_USER)) { - state->cli_state->response.result = WINBINDD_ERROR; - request_finished(state->cli_state); + request_error(state->cli_state); return; } @@ -379,8 +376,7 @@ static void uid2sid_idmap_set_mapping_recv(void *private, BOOL success) sid_to_string(state->cli_state->response.data.sid.sid, &state->sid); state->cli_state->response.data.sid.type = state->type; - state->cli_state->response.result = WINBINDD_OK; - request_finished(state->cli_state); + request_ok(state->cli_state); } /* Convert a gid to a sid */ @@ -400,7 +396,7 @@ static void gid2sid_lookupname_recv(void *private, BOOL success, enum SID_NAME_USE type); static void gid2sid_idmap_set_mapping_recv(void *private, BOOL success); -enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) +void winbindd_gid_to_sid(struct winbindd_cli_state *state) { DOM_SID sid; NTSTATUS status; @@ -411,7 +407,8 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) if (idmap_proxyonly()) { DEBUG(8, ("IDMAP proxy only\n")); - return WINBINDD_ERROR; + request_error(state); + return; } status = idmap_gid_to_sid(&sid, state->request.data.gid, @@ -420,20 +417,23 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) if (NT_STATUS_IS_OK(status)) { sid_to_string(state->response.data.sid.sid, &sid); state->response.data.sid.type = SID_NAME_USER; - return WINBINDD_OK; + request_ok(state); + return; } if (is_in_gid_range(state->request.data.gid)) { /* This is winbind's, so we should better have succeeded * above. */ - return WINBINDD_ERROR; + request_error(state); + return; } /* The only chance that this is correct is that winbind trusted * domains only = yes, and the user exists in nss and the domain. */ if (!lp_winbind_trusted_domains_only()) { - return WINBINDD_ERROR; + request_error(state); + return; } /* The only chance that this is correct is that winbind trusted @@ -442,7 +442,8 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) gid2sid_state = TALLOC_ZERO_P(state->mem_ctx, struct gid2sid_state); if (gid2sid_state == NULL) { DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; + request_error(state); + return; } gid2sid_state->cli_state = state; @@ -450,7 +451,6 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) winbindd_gid2name_async(state->mem_ctx, state->request.data.gid, gid2sid_gid2name_recv, gid2sid_state); - return WINBINDD_PENDING; } static void gid2sid_gid2name_recv(void *private, BOOL success, @@ -465,8 +465,7 @@ static void gid2sid_gid2name_recv(void *private, BOOL success, fstrcpy(state->name, username); if (!success) { - state->cli_state->response.result = WINBINDD_ERROR; - request_finished(state->cli_state); + request_error(state->cli_state); return; } @@ -484,8 +483,7 @@ static void gid2sid_lookupname_recv(void *private, BOOL success, if ((!success) || ((type != SID_NAME_DOM_GRP) && (type!=SID_NAME_ALIAS))) { - state->cli_state->response.result = WINBINDD_ERROR; - request_finished(state->cli_state); + request_error(state->cli_state); return; } @@ -505,22 +503,19 @@ static void gid2sid_idmap_set_mapping_recv(void *private, BOOL success) sid_to_string(state->cli_state->response.data.sid.sid, &state->sid); state->cli_state->response.data.sid.type = state->type; - state->cli_state->response.result = WINBINDD_OK; - request_finished(state->cli_state); + request_ok(state->cli_state); } -enum winbindd_result winbindd_allocate_rid(struct winbindd_cli_state *state) +void winbindd_allocate_rid(struct winbindd_cli_state *state) { if ( !state->privileged ) { DEBUG(2, ("winbindd_allocate_rid: non-privileged access " "denied!\n")); - return WINBINDD_ERROR; + request_error(state); + return; } - async_request(state->mem_ctx, idmap_child(), - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_child(state, idmap_child()); } enum winbindd_result winbindd_dual_allocate_rid(struct winbindd_domain *domain, @@ -538,18 +533,16 @@ enum winbindd_result winbindd_dual_allocate_rid(struct winbindd_domain *domain, return WINBINDD_OK; } -enum winbindd_result winbindd_allocate_rid_and_gid(struct winbindd_cli_state *state) +void winbindd_allocate_rid_and_gid(struct winbindd_cli_state *state) { if ( !state->privileged ) { DEBUG(2, ("winbindd_allocate_rid: non-privileged access " "denied!\n")); - return WINBINDD_ERROR; + request_error(state); + return; } - async_request(state->mem_ctx, idmap_child(), - &state->request, &state->response, - request_finished_cont, state); - return WINBINDD_PENDING; + sendto_child(state, idmap_child()); } enum winbindd_result winbindd_dual_allocate_rid_and_gid(struct winbindd_domain *domain, diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index d8d7dbb5023..55b63a81827 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -189,8 +189,7 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state, return; error: - s->state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); } static void getpwsid_queryuser_recv(void *private, BOOL success, @@ -203,8 +202,7 @@ static void getpwsid_queryuser_recv(void *private, BOOL success, if (!success) { DEBUG(5, ("Could not query user %s\\%s\n", s->domain->name, s->username)); - s->state->response.result = WINBINDD_ERROR; - request_finished(s->state); + request_error(s->state); return; } @@ -225,8 +223,7 @@ static void getpwsid_sid2uid_recv(void *private, BOOL success, uid_t uid) if (!success) { DEBUG(5, ("Could not query user's %s\\%s uid\n", s->domain->name, s->username)); - s->state->response.result = WINBINDD_ERROR; - request_finished(s->state); + request_error(s->state); return; } @@ -244,12 +241,10 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) char *homedir; char *shell; - s->state->response.result = WINBINDD_ERROR; - if (!success) { DEBUG(5, ("Could not query user's %s\\%s\n gid", s->domain->name, s->username)); - goto done; + goto failed; } s->gid = gid; @@ -274,7 +269,7 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) s->domain->name, pw->pw_uid, pw->pw_gid); if (homedir == NULL) { DEBUG(5, ("Could not compose homedir\n")); - goto done; + goto failed; } safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1); SAFE_FREE(homedir); @@ -283,7 +278,7 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) s->domain->name, pw->pw_uid, pw->pw_gid); if (shell == NULL) { DEBUG(5, ("Could not compose shell\n")); - goto done; + goto failed; } safe_strcpy(pw->pw_shell, shell, sizeof(pw->pw_shell) - 1); SAFE_FREE(shell); @@ -293,10 +288,11 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1); - s->state->response.result = WINBINDD_OK; + request_ok(s->state); + return; - done: - request_finished(s->state); + failed: + request_error(s->state); } /* Return a password structure from a username. */ @@ -304,7 +300,7 @@ static void getpwsid_sid2gid_recv(void *private, BOOL success, gid_t gid) static void getpwnam_name2sid_recv(void *private, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type); -enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) +void winbindd_getpwnam(struct winbindd_cli_state *state) { struct winbindd_domain *domain; fstring domname, username; @@ -319,7 +315,8 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) username)) { DEBUG(0, ("Could not parse domain user: %s\n", state->request.data.username)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get info for the domain */ @@ -329,20 +326,21 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) if (domain == NULL) { DEBUG(7, ("could not find domain entry for domain %s\n", domname)); - return WINBINDD_ERROR; + request_error(state); + return; } if ( strequal(domname, lp_workgroup()) && lp_winbind_trusted_domains_only() ) { DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", domname, username)); - return WINBINDD_ERROR; + request_error(state); + return; } /* Get rid and name type from name. The following costs 1 packet */ winbindd_lookupname_async(state->mem_ctx, domname, username, getpwnam_name2sid_recv, state); - return WINBINDD_PENDING; } static void getpwnam_name2sid_recv(void *private, BOOL success, @@ -353,15 +351,13 @@ static void getpwnam_name2sid_recv(void *private, BOOL success, if (!success) { DEBUG(5, ("Could not lookup name for user %s\n", state->request.data.username)); - state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); return; } if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) { DEBUG(5, ("%s is not a user\n", state->request.data.username)); - state->response.result = WINBINDD_ERROR; - request_finished(state); + request_error(state); return; } @@ -370,7 +366,7 @@ static void getpwnam_name2sid_recv(void *private, BOOL success, /* Return a password structure given a uid number */ -enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) +void winbindd_getpwuid(struct winbindd_cli_state *state) { DOM_SID user_sid; NTSTATUS status; @@ -378,8 +374,10 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Bug out if the uid isn't in the winbind range */ if ((state->request.data.uid < server_state.uid_low ) || - (state->request.data.uid > server_state.uid_high)) - return WINBINDD_ERROR; + (state->request.data.uid > server_state.uid_high)) { + request_error(state); + return; + } DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid, (unsigned long)state->request.data.uid)); @@ -390,11 +388,11 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("Could not find SID for uid %lu\n", (unsigned long)state->request.data.uid)); - return WINBINDD_ERROR; + request_error(state); + return; } winbindd_getpwsid(state, &user_sid); - return WINBINDD_PENDING; } /* @@ -403,7 +401,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Rewind file pointer for ntdom passwd database */ -enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) +void winbindd_setpwent(struct winbindd_cli_state *state) { struct winbindd_domain *domain; @@ -411,8 +409,10 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) /* Check user has enabled this */ - if (!lp_winbind_enum_users()) - return WINBINDD_ERROR; + if (!lp_winbind_enum_users()) { + request_error(state); + return; + } /* Free old static data if it exists */ @@ -451,8 +451,11 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) /* Create a state record for this domain */ - if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) - return WINBINDD_ERROR; + if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { + DEBUG(0, ("malloc failed\n")); + request_error(state); + return; + } ZERO_STRUCTP(domain_state); @@ -464,21 +467,19 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) } state->getpwent_initialized = True; - - return WINBINDD_OK; + request_ok(state); } /* Close file pointer to ntdom passwd database */ -enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state) +void winbindd_endpwent(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid)); free_getent_state(state->getpwent_state); state->getpwent_initialized = False; state->getpwent_state = NULL; - - return WINBINDD_OK; + request_ok(state); } /* Get partial list of domain users for a domain. We fill in the sam_entries, @@ -572,7 +573,7 @@ static BOOL get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) #define MAX_GETPWENT_USERS 500 -enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) +void winbindd_getpwent(struct winbindd_cli_state *state) { struct getent_state *ent; struct winbindd_pw *user_list; @@ -582,15 +583,19 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) /* Check user has enabled this */ - if (!lp_winbind_enum_users()) - return WINBINDD_ERROR; + if (!lp_winbind_enum_users()) { + request_error(state); + return; + } /* Allocate space for returning a chunk of users */ num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries); - if ((state->response.extra_data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) - return WINBINDD_ERROR; + if ((state->response.extra_data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) { + request_error(state); + return; + } memset(state->response.extra_data, 0, num_users * sizeof(struct winbindd_pw)); @@ -600,8 +605,10 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) if (!state->getpwent_initialized) winbindd_setpwent(state); - if (!(ent = state->getpwent_state)) - return WINBINDD_ERROR; + if (!(ent = state->getpwent_state)) { + request_error(state); + return; + } /* Start sending back users */ @@ -664,12 +671,15 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) /* Out of domains */ - return (user_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR; + if (user_list_ndx > 0) + request_ok(state); + else + request_error(state); } /* List domain users without mapping to unix ids */ -enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) +void winbindd_list_users(struct winbindd_cli_state *state) { struct winbindd_domain *domain; WINBIND_USERINFO *info; @@ -756,5 +766,8 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) done: - return rv; + if (rv == WINBINDD_OK) + request_ok(state); + else + request_error(state); } diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c index f199ebcb437..2e03becd5af 100644 --- a/source3/nsswitch/winbindd_wins.c +++ b/source3/nsswitch/winbindd_wins.c @@ -132,7 +132,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) /* Get hostname from IP */ -enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) +void winbindd_wins_byip(struct winbindd_cli_state *state) { fstring response; int i, count, maxlen, size; @@ -151,7 +151,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) size = strlen(state->request.data.winsreq); if (size > maxlen) { SAFE_FREE(status); - return WINBINDD_ERROR; + request_error(state); + return; } fstrcat(response,state->request.data.winsreq); fstrcat(response,"\t"); @@ -162,7 +163,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) size = sizeof(status[i].name) + strlen(response); if (size > maxlen) { SAFE_FREE(status); - return WINBINDD_ERROR; + request_error(state); + return; } fstrcat(response, status[i].name); fstrcat(response, " "); @@ -173,12 +175,12 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) SAFE_FREE(status); } fstrcpy(state->response.data.winsresp,response); - return WINBINDD_OK; + request_ok(state); } /* Get IP from hostname */ -enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state) +void winbindd_wins_byname(struct winbindd_cli_state *state) { struct in_addr *ip_list; int i, count, maxlen, size; @@ -200,7 +202,8 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state) size = strlen(addr); if (size > maxlen) { SAFE_FREE(ip_list); - return WINBINDD_ERROR; + request_error(state); + return; } if (i != 0) { /* Clear out the newline character */ @@ -215,15 +218,18 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state) size = strlen(state->request.data.winsreq) + strlen(response); if (size > maxlen) { SAFE_FREE(ip_list); - return WINBINDD_ERROR; + request_error(state); + return; } fstrcat(response,state->request.data.winsreq); fstrcat(response,"\n"); SAFE_FREE(ip_list); - } else - return WINBINDD_ERROR; + } else { + request_error(state); + return; + } fstrcpy(state->response.data.winsresp,response); - return WINBINDD_OK; + request_ok(state); }