Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : async getpwsid
4 : Copyright (C) Volker Lendecke 2009
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "winbindd.h"
22 : #include "librpc/gen_ndr/ndr_winbind_c.h"
23 : #include "../libcli/security/security.h"
24 : #include "lib/util/string_wrappers.h"
25 : #include "source3/lib/substitute.h"
26 :
27 : struct wb_getpwsid_state {
28 : struct tevent_context *ev;
29 : struct dom_sid sid;
30 : struct wbint_userinfo *userinfo;
31 : struct winbindd_pw *pw;
32 : };
33 :
34 : static void wb_getpwsid_queryuser_done(struct tevent_req *subreq);
35 :
36 102248 : struct tevent_req *wb_getpwsid_send(TALLOC_CTX *mem_ctx,
37 : struct tevent_context *ev,
38 : const struct dom_sid *user_sid,
39 : struct winbindd_pw *pw)
40 : {
41 0 : struct tevent_req *req, *subreq;
42 0 : struct wb_getpwsid_state *state;
43 0 : struct dom_sid_buf buf;
44 :
45 102248 : req = tevent_req_create(mem_ctx, &state, struct wb_getpwsid_state);
46 102248 : if (req == NULL) {
47 0 : return NULL;
48 : }
49 102248 : D_INFO("WB command getpwsid start.\nQuery user SID %s.\n", dom_sid_str_buf(user_sid, &buf));
50 102248 : sid_copy(&state->sid, user_sid);
51 102248 : state->ev = ev;
52 102248 : state->pw = pw;
53 :
54 102248 : if (dom_sid_in_domain(&global_sid_Unix_Users, user_sid)) {
55 : /* unmapped Unix users must be resolved locally */
56 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
57 0 : return tevent_req_post(req, ev);
58 : }
59 :
60 102248 : subreq = wb_queryuser_send(state, ev, &state->sid);
61 102248 : if (tevent_req_nomem(subreq, req)) {
62 0 : return tevent_req_post(req, ev);
63 : }
64 102248 : tevent_req_set_callback(subreq, wb_getpwsid_queryuser_done, req);
65 102248 : return req;
66 : }
67 :
68 102248 : static void wb_getpwsid_queryuser_done(struct tevent_req *subreq)
69 : {
70 102248 : struct tevent_req *req = tevent_req_callback_data(
71 : subreq, struct tevent_req);
72 102248 : struct wb_getpwsid_state *state = tevent_req_data(
73 : req, struct wb_getpwsid_state);
74 102248 : struct winbindd_pw *pw = state->pw;
75 0 : struct wbint_userinfo *info;
76 0 : fstring acct_name;
77 102248 : const char *output_username = NULL;
78 102248 : char *mapped_name = NULL;
79 0 : char *tmp;
80 0 : NTSTATUS status;
81 :
82 102248 : status = wb_queryuser_recv(subreq, state, &state->userinfo);
83 102248 : TALLOC_FREE(subreq);
84 102248 : if (tevent_req_nterror(req, status)) {
85 48 : return;
86 : }
87 102200 : info = state->userinfo;
88 :
89 102200 : pw->pw_uid = info->uid;
90 102200 : pw->pw_gid = info->primary_gid;
91 :
92 102200 : fstrcpy(acct_name, info->acct_name);
93 102200 : if (!strlower_m(acct_name)) {
94 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
95 0 : return;
96 : }
97 :
98 : /*
99 : * TODO:
100 : * This function should be called in 'idmap winbind child'. It shouldn't
101 : * be a blocking call, but for this we need to add a new function for
102 : * winbind.idl. This is a fix which can be backported for now.
103 : */
104 102200 : status = normalize_name_map(state,
105 : info->domain_name,
106 : acct_name,
107 : &mapped_name);
108 102200 : if (NT_STATUS_IS_OK(status) ||
109 102200 : NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
110 0 : fstrcpy(acct_name, mapped_name);
111 : }
112 102200 : output_username = fill_domain_username_talloc(state,
113 : info->domain_name,
114 : acct_name,
115 : true);
116 102200 : if (output_username == NULL) {
117 0 : tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
118 0 : return;
119 : }
120 :
121 102200 : strlcpy(pw->pw_name, output_username, sizeof(pw->pw_name));
122 :
123 102200 : strlcpy(pw->pw_gecos, info->full_name ? info->full_name : "",
124 : sizeof(pw->pw_gecos));
125 :
126 102200 : tmp = talloc_sub_specified(
127 : state, info->homedir, acct_name,
128 : info->primary_group_name, info->domain_name,
129 : pw->pw_uid, pw->pw_gid);
130 102200 : if (tevent_req_nomem(tmp, req)) {
131 0 : return;
132 : }
133 102200 : strlcpy(pw->pw_dir, tmp, sizeof(pw->pw_dir));
134 102200 : TALLOC_FREE(tmp);
135 :
136 102200 : tmp = talloc_sub_specified(
137 : state, info->shell, acct_name,
138 : info->primary_group_name, info->domain_name,
139 : pw->pw_uid, pw->pw_gid);
140 102200 : if (tevent_req_nomem(tmp, req)) {
141 0 : return;
142 : }
143 102200 : strlcpy(pw->pw_shell, tmp, sizeof(pw->pw_shell));
144 102200 : TALLOC_FREE(tmp);
145 :
146 102200 : strlcpy(pw->pw_passwd, "*", sizeof(pw->pw_passwd));
147 :
148 102200 : tevent_req_done(req);
149 : }
150 :
151 102248 : NTSTATUS wb_getpwsid_recv(struct tevent_req *req)
152 : {
153 102248 : NTSTATUS status = tevent_req_simple_recv_ntstatus(req);
154 102248 : D_INFO("WB command getpwsid end.\nReturn status %s.\n", nt_errstr(status));
155 102248 : return status;
156 : }
|