Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : Data Provider, auth utils
5 : :
6 : : Copyright (C) Sumit Bose <sbose@redhat.com> 2009
7 : :
8 : : This program is free software; you can redistribute it and/or modify
9 : : it under the terms of the GNU General Public License as published by
10 : : the Free Software Foundation; either version 3 of the License, or
11 : : (at your option) any later version.
12 : :
13 : : This program is distributed in the hope that it will be useful,
14 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : GNU General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include "data_provider.h"
23 : :
24 : 0 : bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd)
25 : : {
26 : : dbus_bool_t db_ret;
27 : :
28 [ # # ]: 0 : if (pd->user == NULL) return false;
29 [ # # ]: 0 : if (pd->service == NULL) pd->service = talloc_strdup(pd, "");
30 [ # # ]: 0 : if (pd->tty == NULL) pd->tty = talloc_strdup(pd, "");
31 [ # # ]: 0 : if (pd->ruser == NULL) pd->ruser = talloc_strdup(pd, "");
32 [ # # ]: 0 : if (pd->rhost == NULL) pd->rhost = talloc_strdup(pd, "");
33 : :
34 : :
35 : 0 : db_ret = dbus_message_append_args(msg,
36 : : DBUS_TYPE_INT32, &(pd->cmd),
37 : : DBUS_TYPE_STRING, &(pd->user),
38 : : DBUS_TYPE_STRING, &(pd->domain),
39 : : DBUS_TYPE_STRING, &(pd->service),
40 : : DBUS_TYPE_STRING, &(pd->tty),
41 : : DBUS_TYPE_STRING, &(pd->ruser),
42 : : DBUS_TYPE_STRING, &(pd->rhost),
43 : : DBUS_TYPE_UINT32, &(pd->authtok_type),
44 : : DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
45 : : &(pd->authtok),
46 : : (pd->authtok_size),
47 : : DBUS_TYPE_UINT32, &(pd->newauthtok_type),
48 : : DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
49 : : &(pd->newauthtok),
50 : : pd->newauthtok_size,
51 : : DBUS_TYPE_INT32, &(pd->priv),
52 : : DBUS_TYPE_UINT32, &(pd->cli_pid),
53 : : DBUS_TYPE_INVALID);
54 : :
55 : 0 : return db_ret;
56 : : }
57 : :
58 : 0 : bool dp_unpack_pam_request(DBusMessage *msg, TALLOC_CTX *mem_ctx,
59 : : struct pam_data **new_pd, DBusError *dbus_error)
60 : : {
61 : : dbus_bool_t db_ret;
62 : : int ret;
63 : : struct pam_data pd;
64 : :
65 : 0 : memset(&pd, 0, sizeof(pd));
66 : :
67 : 0 : db_ret = dbus_message_get_args(msg, dbus_error,
68 : : DBUS_TYPE_INT32, &(pd.cmd),
69 : : DBUS_TYPE_STRING, &(pd.user),
70 : : DBUS_TYPE_STRING, &(pd.domain),
71 : : DBUS_TYPE_STRING, &(pd.service),
72 : : DBUS_TYPE_STRING, &(pd.tty),
73 : : DBUS_TYPE_STRING, &(pd.ruser),
74 : : DBUS_TYPE_STRING, &(pd.rhost),
75 : : DBUS_TYPE_UINT32, &(pd.authtok_type),
76 : : DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
77 : : &(pd.authtok),
78 : : &(pd.authtok_size),
79 : : DBUS_TYPE_UINT32, &(pd.newauthtok_type),
80 : : DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
81 : : &(pd.newauthtok),
82 : : &(pd.newauthtok_size),
83 : : DBUS_TYPE_INT32, &(pd.priv),
84 : : DBUS_TYPE_UINT32, &(pd.cli_pid),
85 : : DBUS_TYPE_INVALID);
86 : :
87 [ # # ]: 0 : if (!db_ret) {
88 [ # # ][ # # ]: 0 : DEBUG(1, ("dbus_message_get_args failed.\n"));
[ # # ][ # # ]
[ # # ]
89 : : return false;
90 : : }
91 : :
92 : 0 : ret = copy_pam_data(mem_ctx, &pd, new_pd);
93 [ # # ]: 0 : if (ret != EOK) {
94 [ # # ][ # # ]: 0 : DEBUG(1, ("copy_pam_data failed.\n"));
[ # # ][ # # ]
[ # # ]
95 : : return false;
96 : : }
97 : :
98 [ # # ][ # # ]: 0 : if (pd.authtok_size != 0 && pd.authtok != NULL) {
99 : 0 : memset(pd.authtok, 0, pd.authtok_size);
100 : 0 : pd.authtok_size = 0;
101 : : }
102 : :
103 [ # # ][ # # ]: 0 : if (pd.newauthtok_size != 0 && pd.newauthtok != NULL) {
104 : 0 : memset(pd.newauthtok, 0, pd.newauthtok_size);
105 : : pd.newauthtok_size = 0;
106 : : }
107 : :
108 : : return true;
109 : : }
110 : :
111 : 0 : bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd)
112 : : {
113 : : dbus_bool_t dbret;
114 : : struct response_data *resp;
115 : : DBusMessageIter iter;
116 : : DBusMessageIter array_iter;
117 : : DBusMessageIter struct_iter;
118 : : DBusMessageIter data_iter;
119 : :
120 : 0 : dbus_message_iter_init_append(msg, &iter);
121 : :
122 : : /* Append the PAM status */
123 : 0 : dbret = dbus_message_iter_append_basic(&iter,
124 : 0 : DBUS_TYPE_UINT32, &(pd->pam_status));
125 [ # # ]: 0 : if (!dbret) {
126 : : return false;
127 : : }
128 : :
129 : : /* Create an array of response structures */
130 : 0 : dbret = dbus_message_iter_open_container(&iter,
131 : : DBUS_TYPE_ARRAY, "(uay)",
132 : : &array_iter);
133 [ # # ]: 0 : if (!dbret) {
134 : : return false;
135 : : }
136 : :
137 : 0 : resp = pd->resp_list;
138 [ # # ]: 0 : while (resp != NULL) {
139 : : /* Create a DBUS struct */
140 : 0 : dbret = dbus_message_iter_open_container(&array_iter,
141 : : DBUS_TYPE_STRUCT, NULL,
142 : : &struct_iter);
143 [ # # ]: 0 : if (!dbret) {
144 : : return false;
145 : : }
146 : :
147 : : /* Add the response type */
148 : 0 : dbret = dbus_message_iter_append_basic(&struct_iter,
149 : : DBUS_TYPE_UINT32,
150 : 0 : &(resp->type));
151 [ # # ]: 0 : if (!dbret) {
152 : : return false;
153 : : }
154 : :
155 : : /* Add the response message */
156 : 0 : dbret = dbus_message_iter_open_container(&struct_iter,
157 : : DBUS_TYPE_ARRAY, "y",
158 : : &data_iter);
159 [ # # ]: 0 : if (!dbret) {
160 : : return false;
161 : : }
162 : 0 : dbret = dbus_message_iter_append_fixed_array(&data_iter,
163 : 0 : DBUS_TYPE_BYTE, &(resp->data), resp->len);
164 [ # # ]: 0 : if (!dbret) {
165 : : return false;
166 : : }
167 : 0 : dbret = dbus_message_iter_close_container(&struct_iter, &data_iter);
168 [ # # ]: 0 : if (!dbret) {
169 : : return false;
170 : : }
171 : :
172 : 0 : resp = resp->next;
173 : 0 : dbret = dbus_message_iter_close_container(&array_iter, &struct_iter);
174 [ # # ]: 0 : if (!dbret) {
175 : : return false;
176 : : }
177 : : }
178 : :
179 : : /* Close the struct array */
180 : 0 : dbret = dbus_message_iter_close_container(&iter, &array_iter);
181 [ # # ]: 0 : if (!dbret) {
182 : : return false;
183 : : }
184 : :
185 : : return true;
186 : : }
187 : :
188 : 0 : bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error)
189 : : {
190 : : DBusMessageIter iter;
191 : : DBusMessageIter array_iter;
192 : : DBusMessageIter struct_iter;
193 : : DBusMessageIter sub_iter;
194 : : int type;
195 : : int len;
196 : : const uint8_t *data;
197 : :
198 [ # # ]: 0 : if (!dbus_message_iter_init(msg, &iter)) {
199 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response has no arguments.\n"));
[ # # ][ # # ]
[ # # ]
200 : : return false;
201 : : }
202 : :
203 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
204 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
205 : : return false;
206 : : }
207 : 0 : dbus_message_iter_get_basic(&iter, &(pd->pam_status));
208 : :
209 [ # # ]: 0 : if (!dbus_message_iter_next(&iter)) {
210 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response has too few arguments.\n"));
[ # # ][ # # ]
[ # # ]
211 : : return false;
212 : : }
213 : :
214 : : /* After this point will be an array of pam data */
215 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
216 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
217 [ # # ][ # # ]: 0 : DEBUG(1, ("Type was %c\n", (char)dbus_message_iter_get_arg_type(&iter)));
[ # # ][ # # ]
[ # # ]
218 : : return false;
219 : : }
220 : :
221 [ # # ]: 0 : if (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) {
222 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
223 : : return false;
224 : : }
225 : :
226 : 0 : dbus_message_iter_recurse(&iter, &array_iter);
227 [ # # ]: 0 : while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) {
228 : : /* Read in a pam data struct */
229 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
230 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
231 : : return false;
232 : : }
233 : :
234 : 0 : dbus_message_iter_recurse(&array_iter, &struct_iter);
235 : :
236 : : /* PAM data struct contains a type and a byte-array of data */
237 : :
238 : : /* Get the pam data type */
239 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_UINT32) {
240 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
241 : : return false;
242 : : }
243 : 0 : dbus_message_iter_get_basic(&struct_iter, &type);
244 : :
245 [ # # ]: 0 : if (!dbus_message_iter_next(&struct_iter)) {
246 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
247 : : return false;
248 : : }
249 : :
250 : : /* Get the byte array */
251 [ # # # # ]: 0 : if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_ARRAY ||
252 : 0 : dbus_message_iter_get_element_type(&struct_iter) != DBUS_TYPE_BYTE) {
253 [ # # ][ # # ]: 0 : DEBUG(1, ("pam response format error.\n"));
[ # # ][ # # ]
[ # # ]
254 : : return false;
255 : : }
256 : :
257 : 0 : dbus_message_iter_recurse(&struct_iter, &sub_iter);
258 : 0 : dbus_message_iter_get_fixed_array(&sub_iter, &data, &len);
259 : :
260 [ # # ]: 0 : if (pam_add_response(pd, type, len, data) != EOK) {
261 [ # # ][ # # ]: 0 : DEBUG(1, ("pam_add_response failed.\n"));
[ # # ][ # # ]
[ # # ]
262 : : return false;
263 : : }
264 : 0 : dbus_message_iter_next(&array_iter);
265 : : }
266 : :
267 : : return true;
268 : : }
269 : :
270 : 0 : void dp_id_callback(DBusPendingCall *pending, void *ptr)
271 : : {
272 : : DBusMessage *reply;
273 : : DBusError dbus_error;
274 : : dbus_bool_t ret;
275 : : dbus_uint16_t dp_ver;
276 : : int type;
277 : :
278 : 0 : dbus_error_init(&dbus_error);
279 : :
280 : 0 : reply = dbus_pending_call_steal_reply(pending);
281 [ # # ]: 0 : if (!reply) {
282 : : /* reply should never be null. This function shouldn't be called
283 : : * until reply is valid or timeout has occurred. If reply is NULL
284 : : * here, something is seriously wrong and we should bail out.
285 : : */
286 [ # # ][ # # ]: 0 : DEBUG(0, ("Severe error. A reply callback was called but no"
[ # # ][ # # ]
[ # # ]
287 : : " reply was received and no timeout occurred\n"));
288 : :
289 : : /* FIXME: Destroy this connection ? */
290 : : goto done;
291 : : }
292 : :
293 : 0 : type = dbus_message_get_type(reply);
294 [ # # # ]: 0 : switch (type) {
295 : : case DBUS_MESSAGE_TYPE_METHOD_RETURN:
296 : 0 : ret = dbus_message_get_args(reply, &dbus_error,
297 : : DBUS_TYPE_UINT16, &dp_ver,
298 : : DBUS_TYPE_INVALID);
299 [ # # ]: 0 : if (!ret) {
300 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to parse message\n"));
[ # # ][ # # ]
[ # # ]
301 [ # # ]: 0 : if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
302 : : /* FIXME: Destroy this connection ? */
303 : : goto done;
304 : : }
305 : :
306 [ # # ][ # # ]: 0 : DEBUG(4, ("Got id ack and version (%d) from DP\n", dp_ver));
[ # # ][ # # ]
[ # # ]
307 : :
308 : : break;
309 : :
310 : : case DBUS_MESSAGE_TYPE_ERROR:
311 [ # # ][ # # ]: 0 : DEBUG(0,("The Monitor returned an error [%s]\n",
[ # # ][ # # ]
[ # # ]
312 : : dbus_message_get_error_name(reply)));
313 : : /* Falling through to default intentionally*/
314 : : default:
315 : : /*
316 : : * Timeout or other error occurred or something
317 : : * unexpected happened.
318 : : * It doesn't matter which, because either way we
319 : : * know that this connection isn't trustworthy.
320 : : * We'll destroy it now.
321 : : */
322 : :
323 : : /* FIXME: Destroy this connection ? */
324 : : break;
325 : : }
326 : :
327 : : done:
328 : 0 : dbus_pending_call_unref(pending);
329 : 0 : dbus_message_unref(reply);
330 : 0 : }
331 : :
332 : 0 : int dp_common_send_id(struct sbus_connection *conn, uint16_t version,
333 : : const char *name)
334 : : {
335 : : DBusMessage *msg;
336 : : dbus_bool_t ret;
337 : : int retval;
338 : :
339 : : /* create the message */
340 : 0 : msg = dbus_message_new_method_call(NULL,
341 : : DP_PATH,
342 : : DP_INTERFACE,
343 : : DP_METHOD_REGISTER);
344 [ # # ]: 0 : if (msg == NULL) {
345 [ # # ][ # # ]: 0 : DEBUG(0, ("Out of memory?!\n"));
[ # # ][ # # ]
[ # # ]
346 : : return ENOMEM;
347 : : }
348 : :
349 [ # # ][ # # ]: 0 : DEBUG(4, ("Sending ID to DP: (%d,%s)\n",
[ # # ][ # # ]
[ # # ]
350 : : version, name));
351 : :
352 : 0 : ret = dbus_message_append_args(msg,
353 : : DBUS_TYPE_UINT16, &version,
354 : : DBUS_TYPE_STRING, &name,
355 : : DBUS_TYPE_INVALID);
356 [ # # ]: 0 : if (!ret) {
357 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to build message\n"));
[ # # ][ # # ]
[ # # ]
358 : : return EIO;
359 : : }
360 : :
361 : 0 : retval = sbus_conn_send(conn, msg, 30000, dp_id_callback, NULL, NULL);
362 : :
363 : 0 : dbus_message_unref(msg);
364 : 0 : return retval;
365 : : }
366 : :
|