• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/winbindd/
1/*
2   Unix SMB/CIFS implementation.
3   async fill_pwent
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/cli_wbint.h"
23
24struct wb_fill_pwent_state {
25	struct tevent_context *ev;
26	struct wbint_userinfo *info;
27	struct winbindd_pw *pw;
28};
29
30static bool fillup_pw_field(const char *lp_template,
31			    const char *username,
32			    const char *domname,
33			    uid_t uid,
34			    gid_t gid,
35			    const char *in,
36			    fstring out);
37
38static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq);
39static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq);
40
41struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx,
42				      struct tevent_context *ev,
43				      struct wbint_userinfo *info,
44				      struct winbindd_pw *pw)
45{
46	struct tevent_req *req, *subreq;
47	struct wb_fill_pwent_state *state;
48
49	req = tevent_req_create(mem_ctx, &state, struct wb_fill_pwent_state);
50	if (req == NULL) {
51		return NULL;
52	}
53	state->ev = ev;
54	state->info = info;
55	state->pw = pw;
56
57	subreq = wb_sid2uid_send(state, state->ev, &state->info->user_sid);
58	if (tevent_req_nomem(subreq, req)) {
59		return tevent_req_post(req, ev);
60	}
61	tevent_req_set_callback(subreq, wb_fill_pwent_sid2uid_done, req);
62	return req;
63}
64
65static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq)
66{
67	struct tevent_req *req = tevent_req_callback_data(
68		subreq, struct tevent_req);
69	struct wb_fill_pwent_state *state = tevent_req_data(
70		req, struct wb_fill_pwent_state);
71	NTSTATUS status;
72
73	status = wb_sid2uid_recv(subreq, &state->pw->pw_uid);
74	TALLOC_FREE(subreq);
75	if (!NT_STATUS_IS_OK(status)) {
76		tevent_req_nterror(req, status);
77		return;
78	}
79
80	subreq = wb_sid2gid_send(state, state->ev, &state->info->group_sid);
81	if (tevent_req_nomem(subreq, req)) {
82		return;
83	}
84	tevent_req_set_callback(subreq, wb_fill_pwent_sid2gid_done, req);
85}
86
87static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq)
88{
89	struct tevent_req *req = tevent_req_callback_data(
90		subreq, struct tevent_req);
91	struct wb_fill_pwent_state *state = tevent_req_data(
92		req, struct wb_fill_pwent_state);
93	struct winbindd_domain *domain;
94	char *dom_name;
95	fstring user_name, output_username;
96	char *mapped_name = NULL;
97	NTSTATUS status;
98
99	status = wb_sid2gid_recv(subreq, &state->pw->pw_gid);
100	TALLOC_FREE(subreq);
101	if (!NT_STATUS_IS_OK(status)) {
102		tevent_req_nterror(req, status);
103		return;
104	}
105
106	domain = find_domain_from_sid_noinit(&state->info->user_sid);
107	if (domain == NULL) {
108		tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
109		return;
110	}
111	dom_name = domain->name;
112
113	/* Username */
114
115	fstrcpy(user_name, state->info->acct_name);
116	strlower_m(user_name);
117	status = normalize_name_map(state, domain, user_name, &mapped_name);
118
119	/* Basic removal of whitespace */
120	if (NT_STATUS_IS_OK(status)) {
121		fill_domain_username(output_username, dom_name, mapped_name,
122				     true);
123	}
124	/* Complete name replacement */
125	else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
126		fstrcpy(output_username, mapped_name);
127	}
128	/* No change at all */
129	else {
130		fill_domain_username(output_username, dom_name, user_name,
131				     true);
132	}
133
134	fstrcpy(state->pw->pw_name, output_username);
135	fstrcpy(state->pw->pw_gecos, state->info->full_name);
136
137	/* Home directory and shell */
138
139	if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
140			     state->pw->pw_uid, state->pw->pw_gid,
141			     state->info->homedir, state->pw->pw_dir)) {
142		tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
143		return;
144	}
145
146	if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
147			     state->pw->pw_uid, state->pw->pw_gid,
148			     state->info->shell, state->pw->pw_shell)) {
149		tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
150		return;
151	}
152
153	/* Password - set to "*" as we can't generate anything useful here.
154	   Authentication can be done using the pam_winbind module. */
155
156	fstrcpy(state->pw->pw_passwd, "*");
157	tevent_req_done(req);
158}
159
160NTSTATUS wb_fill_pwent_recv(struct tevent_req *req)
161{
162	return tevent_req_simple_recv_ntstatus(req);
163}
164
165static bool fillup_pw_field(const char *lp_template,
166			    const char *username,
167			    const char *domname,
168			    uid_t uid,
169			    gid_t gid,
170			    const char *in,
171			    fstring out)
172{
173	char *templ;
174
175	if (out == NULL)
176		return False;
177
178	/* The substitution of %U and %D in the 'template
179	   homedir' is done by talloc_sub_specified() below.
180	   If we have an in string (which means the value has already
181	   been set in the nss_info backend), then use that.
182	   Otherwise use the template value passed in. */
183
184	if ((in != NULL) && (in[0] != '\0') && (lp_security() == SEC_ADS)) {
185		templ = talloc_sub_specified(talloc_tos(), in,
186					     username, domname,
187					     uid, gid);
188	} else {
189		templ = talloc_sub_specified(talloc_tos(), lp_template,
190					     username, domname,
191					     uid, gid);
192	}
193
194	if (!templ)
195		return False;
196
197	safe_strcpy(out, templ, sizeof(fstring) - 1);
198	TALLOC_FREE(templ);
199
200	return True;
201
202}
203