2 Unix SMB/CIFS implementation.
4 Winbind daemon for ntdom nss module
6 Copyright (C) by Tim Potter 2000-2002
7 Copyright (C) Andrew Tridgell 2002
8 Copyright (C) Jelmer Vernooij 2003
9 Copyright (C) Volker Lendecke 2004
10 Copyright (C) Andrew Bartlett 2010
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "../../nsswitch/libwbclient/wbc_async.h"
29 #include "librpc/gen_ndr/messaging.h"
32 #define DBGC_CLASS DBGC_WINBIND
34 static struct winbindd_dispatch_table {
35 enum winbindd_cmd cmd;
36 void (*fn)(struct winbindd_cli_state *state);
37 const char *winbindd_cmd_name;
38 } dispatch_table[] = {
40 /* Enumeration functions */
42 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
47 { WINBINDD_INFO, winbindd_info, "INFO" },
48 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
49 "INTERFACE_VERSION" },
50 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
51 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
52 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
53 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
54 "WINBINDD_PRIV_PIPE_DIR" },
56 /* Credential cache access */
57 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
58 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
62 { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
63 { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
67 { WINBINDD_NUM_CMDS, NULL, "NONE" }
70 struct winbindd_async_dispatch_table {
71 enum winbindd_cmd cmd;
73 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
74 struct tevent_context *ev,
75 struct winbindd_cli_state *cli,
76 struct winbindd_request *request);
77 NTSTATUS (*recv_req)(struct tevent_req *req,
78 struct winbindd_response *presp);
81 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
82 { WINBINDD_PING, "PING",
83 wb_ping_send, wb_ping_recv },
84 { WINBINDD_LOOKUPSID, "LOOKUPSID",
85 winbindd_lookupsid_send, winbindd_lookupsid_recv },
86 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
87 winbindd_lookupname_send, winbindd_lookupname_recv },
88 { WINBINDD_SID_TO_UID, "SID_TO_UID",
89 winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
90 { WINBINDD_SID_TO_GID, "SID_TO_GID",
91 winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
92 { WINBINDD_UID_TO_SID, "UID_TO_SID",
93 winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
94 { WINBINDD_GID_TO_SID, "GID_TO_SID",
95 winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
96 { WINBINDD_GETPWSID, "GETPWSID",
97 winbindd_getpwsid_send, winbindd_getpwsid_recv },
98 { WINBINDD_GETPWNAM, "GETPWNAM",
99 winbindd_getpwnam_send, winbindd_getpwnam_recv },
100 { WINBINDD_GETPWUID, "GETPWUID",
101 winbindd_getpwuid_send, winbindd_getpwuid_recv },
102 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
103 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
104 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
105 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
106 { WINBINDD_GETGROUPS, "GETGROUPS",
107 winbindd_getgroups_send, winbindd_getgroups_recv },
108 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
109 winbindd_show_sequence_send, winbindd_show_sequence_recv },
110 { WINBINDD_GETGRGID, "GETGRGID",
111 winbindd_getgrgid_send, winbindd_getgrgid_recv },
112 { WINBINDD_GETGRNAM, "GETGRNAM",
113 winbindd_getgrnam_send, winbindd_getgrnam_recv },
114 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
115 winbindd_getusersids_send, winbindd_getusersids_recv },
116 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
117 winbindd_lookuprids_send, winbindd_lookuprids_recv },
118 { WINBINDD_SETPWENT, "SETPWENT",
119 winbindd_setpwent_send, winbindd_setpwent_recv },
120 { WINBINDD_GETPWENT, "GETPWENT",
121 winbindd_getpwent_send, winbindd_getpwent_recv },
122 { WINBINDD_ENDPWENT, "ENDPWENT",
123 winbindd_endpwent_send, winbindd_endpwent_recv },
124 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
125 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
126 { WINBINDD_GETDCNAME, "GETDCNAME",
127 winbindd_getdcname_send, winbindd_getdcname_recv },
128 { WINBINDD_SETGRENT, "SETGRENT",
129 winbindd_setgrent_send, winbindd_setgrent_recv },
130 { WINBINDD_GETGRENT, "GETGRENT",
131 winbindd_getgrent_send, winbindd_getgrent_recv },
132 { WINBINDD_ENDGRENT, "ENDGRENT",
133 winbindd_endgrent_send, winbindd_endgrent_recv },
134 { WINBINDD_LIST_USERS, "LIST_USERS",
135 winbindd_list_users_send, winbindd_list_users_recv },
136 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
137 winbindd_list_groups_send, winbindd_list_groups_recv },
138 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
139 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
140 { WINBINDD_PING_DC, "PING_DC",
141 winbindd_ping_dc_send, winbindd_ping_dc_recv },
142 { WINBINDD_PAM_AUTH, "PAM_AUTH",
143 winbindd_pam_auth_send, winbindd_pam_auth_recv },
144 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
145 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
146 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
147 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
148 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
149 winbindd_pam_chng_pswd_auth_crap_send,
150 winbindd_pam_chng_pswd_auth_crap_recv },
152 { 0, NULL, NULL, NULL }
155 static struct winbindd_async_dispatch_table async_priv_table[] = {
156 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
157 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
158 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
159 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
160 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
161 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
162 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
163 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
165 { 0, NULL, NULL, NULL }
168 static void wb_request_done(struct tevent_req *req);
170 void wb_process_request(struct winbindd_cli_state *state)
172 struct winbindd_dispatch_table *table = dispatch_table;
173 struct winbindd_async_dispatch_table *atable;
175 state->mem_ctx = talloc_named(state, 0, "winbind request");
176 if (state->mem_ctx == NULL)
179 /* Remember who asked us. */
180 state->pid = state->request->pid;
182 state->cmd_name = "unknown request";
183 state->recv_fn = NULL;
185 /* Process command */
187 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
188 if (state->request->cmd == atable->cmd) {
193 if ((atable->send_req == NULL) && state->privileged) {
194 for (atable = async_priv_table; atable->send_req;
196 if (state->request->cmd == atable->cmd) {
202 if (atable->send_req != NULL) {
203 struct tevent_req *req;
205 state->cmd_name = atable->cmd_name;
206 state->recv_fn = atable->recv_req;
208 DEBUG(10, ("wb_process_request: Handling async request %d:%s\n",
209 (int)state->pid, state->cmd_name));
211 req = atable->send_req(state->mem_ctx, winbind_event_context(),
212 state, state->request);
214 DEBUG(0, ("wb_process_request: atable->send failed for "
215 "%s\n", atable->cmd_name));
216 request_error(state);
219 tevent_req_set_callback(req, wb_request_done, state);
223 state->response = talloc_zero(state->mem_ctx,
224 struct winbindd_response);
225 if (state->response == NULL) {
226 DEBUG(10, ("talloc failed\n"));
227 winbindd_remove_client(state);
230 state->response->result = WINBINDD_PENDING;
231 state->response->length = sizeof(struct winbindd_response);
233 for (table = dispatch_table; table->fn; table++) {
234 if (state->request->cmd == table->cmd) {
235 DEBUG(10,("wb_process_request: request fn %s\n",
236 table->winbindd_cmd_name ));
237 state->cmd_name = table->winbindd_cmd_name;
244 DEBUG(10,("wb_process_request: unknown request fn number %d\n",
245 (int)state->request->cmd ));
246 request_error(state);
250 static void wb_request_done(struct tevent_req *req)
252 struct winbindd_cli_state *state = tevent_req_callback_data(
253 req, struct winbindd_cli_state);
256 state->response = talloc_zero(state->mem_ctx,
257 struct winbindd_response);
258 if (state->response == NULL) {
259 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
260 (int)state->pid, state->cmd_name));
261 winbindd_remove_client(state);
264 state->response->result = WINBINDD_PENDING;
265 state->response->length = sizeof(struct winbindd_response);
267 status = state->recv_fn(req, state->response);
270 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
271 (int)state->pid, state->cmd_name, nt_errstr(status)));
273 if (!NT_STATUS_IS_OK(status)) {
274 request_error(state);
280 void request_error(struct winbindd_cli_state *state)
282 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
283 state->response->result = WINBINDD_ERROR;
284 request_finished(state);
287 void request_ok(struct winbindd_cli_state *state)
289 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
290 state->response->result = WINBINDD_OK;
291 request_finished(state);