#include "includes.h"
#include "winbindd.h"
-#include "librpc/gen_ndr/cli_wbint.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
+#include "../libcli/security/security.h"
struct wb_getpwsid_state {
- struct winbindd_domain *user_domain;
struct tevent_context *ev;
struct dom_sid sid;
- struct winbind_userinfo *userinfo;
+ struct wbint_userinfo *userinfo;
struct winbindd_pw *pw;
};
static void wb_getpwsid_queryuser_done(struct tevent_req *subreq);
-static void wb_getpwsid_lookupsid_done(struct tevent_req *subreq);
-static void wb_getpwsid_sid2uid_done(struct tevent_req *subreq);
-static void wb_getpwsid_sid2gid_done(struct tevent_req *subreq);
struct tevent_req *wb_getpwsid_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
state->ev = ev;
state->pw = pw;
- state->user_domain = find_domain_from_sid_noinit(user_sid);
- if (state->user_domain == NULL) {
- tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
+ if (dom_sid_in_domain(&global_sid_Unix_Users, user_sid)) {
+ /* unmapped Unix users must be resolved locally */
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return tevent_req_post(req, ev);
}
subreq, struct tevent_req);
struct wb_getpwsid_state *state = tevent_req_data(
req, struct wb_getpwsid_state);
+ struct winbindd_pw *pw = state->pw;
+ struct wbint_userinfo *info;
+ fstring acct_name;
+ const char *output_username = NULL;
+ char *mapped_name = NULL;
+ char *tmp;
NTSTATUS status;
status = wb_queryuser_recv(subreq, state, &state->userinfo);
TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
+ if (tevent_req_nterror(req, status)) {
return;
}
+ info = state->userinfo;
- if ((state->userinfo->acct_name != NULL)
- && (state->userinfo->acct_name[0] != '\0')) {
- /*
- * QueryUser got us a name, let's got directly to the
- * sid2uid step
- */
- subreq = wb_sid2uid_send(state, state->ev,
- &state->userinfo->user_sid);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_getpwsid_sid2uid_done, req);
+ pw->pw_uid = info->uid;
+ pw->pw_gid = info->primary_gid;
+
+ fstrcpy(acct_name, info->acct_name);
+ if (!strlower_m(acct_name)) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
/*
- * QueryUser didn't get us a name, do it via LSA.
+ * TODO:
+ * This function should be called in 'idmap winbind child'. It shouldn't
+ * be a blocking call, but for this we need to add a new function for
+ * winbind.idl. This is a fix which can be backported for now.
*/
- subreq = wb_lookupsid_send(state, state->ev,
- &state->userinfo->user_sid);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_getpwsid_lookupsid_done, req);
-}
-
-static void wb_getpwsid_lookupsid_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_getpwsid_state *state = tevent_req_data(
- req, struct wb_getpwsid_state);
- NTSTATUS status;
- enum lsa_SidType type;
- const char *domain;
-
- status = wb_lookupsid_recv(subreq, state->userinfo, &type, &domain,
- &state->userinfo->acct_name);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- subreq = wb_sid2uid_send(state, state->ev, &state->userinfo->user_sid);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_getpwsid_sid2uid_done, req);
-}
-
-static void wb_getpwsid_sid2uid_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_getpwsid_state *state = tevent_req_data(
- req, struct wb_getpwsid_state);
- NTSTATUS status;
-
- status = wb_sid2uid_recv(subreq, &state->pw->pw_uid);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- subreq = wb_sid2gid_send(state, state->ev,
- &state->userinfo->group_sid);
- if (tevent_req_nomem(subreq, req)) {
+ status = normalize_name_map(state,
+ info->domain_name,
+ acct_name,
+ &mapped_name);
+ if (NT_STATUS_IS_OK(status) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
+ fstrcpy(acct_name, mapped_name);
+ }
+ output_username = fill_domain_username_talloc(state,
+ info->domain_name,
+ acct_name,
+ true);
+ if (output_username == NULL) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- tevent_req_set_callback(subreq, wb_getpwsid_sid2gid_done, req);
-}
-static void wb_getpwsid_sid2gid_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_getpwsid_state *state = tevent_req_data(
- req, struct wb_getpwsid_state);
- NTSTATUS status;
- char *username;
- char *mapped_name;
+ strlcpy(pw->pw_name, output_username, sizeof(pw->pw_name));
- status = wb_sid2gid_recv(subreq, &state->pw->pw_gid);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
+ strlcpy(pw->pw_gecos, info->full_name ? info->full_name : "",
+ sizeof(pw->pw_gecos));
- username = talloc_strdup_lower(state, state->userinfo->acct_name);
- if (tevent_req_nomem(username, req)) {
+ tmp = talloc_sub_specified(
+ state, info->homedir, acct_name,
+ info->primary_group_name, info->domain_name,
+ pw->pw_uid, pw->pw_gid);
+ if (tevent_req_nomem(tmp, req)) {
return;
}
+ strlcpy(pw->pw_dir, tmp, sizeof(pw->pw_dir));
+ TALLOC_FREE(tmp);
- status = normalize_name_map(state, state->user_domain, username,
- &mapped_name);
-
- if (NT_STATUS_IS_OK(status)
- || NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
- /*
- * normalize_name_map did something
- */
- fstrcpy(state->pw->pw_name, mapped_name);
- TALLOC_FREE(mapped_name);
- } else {
- fill_domain_username(state->pw->pw_name,
- state->user_domain->name,
- username, True);
- }
- fstrcpy(state->pw->pw_passwd, "*");
- fstrcpy(state->pw->pw_gecos, state->userinfo->full_name);
-
- if (!fillup_pw_field(lp_template_homedir(), username,
- state->user_domain->name, state->pw->pw_uid,
- state->pw->pw_gid, state->userinfo->homedir,
- state->pw->pw_dir)) {
- DEBUG(5, ("Could not compose homedir\n"));
- tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ tmp = talloc_sub_specified(
+ state, info->shell, acct_name,
+ info->primary_group_name, info->domain_name,
+ pw->pw_uid, pw->pw_gid);
+ if (tevent_req_nomem(tmp, req)) {
return;
}
+ strlcpy(pw->pw_shell, tmp, sizeof(pw->pw_shell));
+ TALLOC_FREE(tmp);
- if (!fillup_pw_field(lp_template_shell(), state->pw->pw_name,
- state->user_domain->name, state->pw->pw_uid,
- state->pw->pw_gid, state->userinfo->shell,
- state->pw->pw_shell)) {
- DEBUG(5, ("Could not compose shell\n"));
- tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
+ strlcpy(pw->pw_passwd, "*", sizeof(pw->pw_passwd));
tevent_req_done(req);
}
NTSTATUS wb_getpwsid_recv(struct tevent_req *req)
{
- NTSTATUS status;
-
- if (tevent_req_is_nterror(req, &status)) {
- return status;
- }
- return NT_STATUS_OK;
+ return tevent_req_simple_recv_ntstatus(req);
}