Line data Source code
1 : /*
2 : SSSD
3 :
4 : Authors:
5 : Sumit Bose <sbose@redhat.com>
6 :
7 : Copyright (C) 2016 Red Hat
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "util/util.h"
24 : #include "providers/ad/ad_pac.h"
25 : #include "providers/ad/ad_common.h"
26 : #include "providers/ad/ad_id.h"
27 : #include "providers/ldap/sdap_idmap.h"
28 : #include "providers/ldap/sdap_async_ad.h"
29 :
30 7 : static errno_t find_user_entry(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
31 : struct be_acct_req *ar,
32 : struct ldb_message **_msg)
33 : {
34 7 : const char *user_attrs[] = { SYSDB_NAME, SYSDB_OBJECTCLASS,
35 : SYSDB_PAC_BLOB, SYSDB_PAC_BLOB_EXPIRE,
36 : NULL };
37 : struct ldb_message *msg;
38 : struct ldb_result *res;
39 : char *user_name;
40 : int ret;
41 7 : TALLOC_CTX *tmp_ctx = NULL;
42 :
43 7 : if (dom == NULL || ar == NULL) {
44 1 : DEBUG(SSSDBG_OP_FAILURE, "Missing arguments.\n");
45 1 : return EINVAL;
46 : }
47 :
48 6 : tmp_ctx = talloc_new(NULL);
49 6 : if (tmp_ctx == NULL) {
50 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
51 0 : return ENOMEM;
52 : }
53 :
54 6 : if (ar->extra_value && strcmp(ar->extra_value, EXTRA_NAME_IS_UPN) == 0) {
55 0 : ret = sysdb_search_user_by_upn(tmp_ctx, dom, ar->filter_value,
56 : user_attrs, &msg);
57 : } else {
58 6 : switch (ar->filter_type) {
59 : case BE_FILTER_SECID:
60 0 : ret = sysdb_search_user_by_sid_str(tmp_ctx, dom, ar->filter_value,
61 : user_attrs, &msg);
62 0 : break;
63 : case BE_FILTER_UUID:
64 0 : ret = sysdb_search_object_by_uuid(tmp_ctx, dom, ar->filter_value,
65 : user_attrs, &res);
66 :
67 0 : if (ret == EOK) {
68 0 : if (res->count == 1) {
69 0 : msg = res->msgs[0];
70 : } else {
71 0 : talloc_free(res);
72 0 : DEBUG(SSSDBG_CRIT_FAILURE,
73 : "Search by UUID returned multiple results.\n");
74 0 : ret = EINVAL;
75 0 : goto done;
76 : }
77 : }
78 0 : break;
79 : case BE_FILTER_NAME:
80 :
81 5 : user_name = sss_get_domain_name(tmp_ctx, ar->filter_value, dom);
82 5 : if (user_name == NULL) {
83 0 : DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_name failed.\n");
84 0 : ret = EINVAL;
85 0 : goto done;
86 : } else {
87 5 : ret = sysdb_search_user_by_name(tmp_ctx, dom, user_name,
88 : user_attrs, &msg);
89 : }
90 5 : break;
91 : default:
92 1 : DEBUG(SSSDBG_OP_FAILURE, "Unsupported filter type [%d].\n",
93 : ar->filter_type);
94 1 : ret = EINVAL;
95 1 : goto done;
96 : }
97 : }
98 :
99 5 : if (ret != EOK) {
100 1 : if (ret == ENOENT) {
101 1 : DEBUG(SSSDBG_TRACE_ALL, "No user found with filter [%s].\n",
102 : ar->filter_value);
103 : } else {
104 0 : DEBUG(SSSDBG_OP_FAILURE,
105 : "Looking up user in cache with filter [%s] failed.\n",
106 : ar->filter_value);
107 : }
108 1 : goto done;
109 : }
110 :
111 4 : *_msg = talloc_steal(mem_ctx, msg);
112 4 : ret = EOK;
113 :
114 : done:
115 6 : talloc_free(tmp_ctx);
116 6 : return ret;
117 : }
118 :
119 7 : errno_t check_if_pac_is_available(TALLOC_CTX *mem_ctx,
120 : struct sss_domain_info *dom,
121 : struct be_acct_req *ar,
122 : struct ldb_message **_msg)
123 : {
124 : struct ldb_message *msg;
125 : struct ldb_message_element *el;
126 : uint64_t pac_expires;
127 : time_t now;
128 : int ret;
129 :
130 7 : ret = find_user_entry(mem_ctx, dom, ar, &msg);
131 7 : if (ret != EOK) {
132 3 : DEBUG(SSSDBG_OP_FAILURE, "find_user_entry failed.\n");
133 3 : return ret;
134 : }
135 :
136 4 : el = ldb_msg_find_element(msg, SYSDB_PAC_BLOB);
137 4 : if (el == NULL) {
138 1 : DEBUG(SSSDBG_TRACE_ALL, "No PAC available.\n");
139 1 : talloc_free(msg);
140 1 : return ENOENT;
141 : }
142 :
143 3 : pac_expires = ldb_msg_find_attr_as_uint64(msg, SYSDB_PAC_BLOB_EXPIRE, 0);
144 3 : now = time(NULL);
145 3 : if (pac_expires < now) {
146 2 : DEBUG(SSSDBG_TRACE_FUNC, "PAC avaiable but too old.\n");
147 2 : talloc_free(msg);
148 2 : return ENOENT;
149 : }
150 :
151 1 : if (_msg != NULL) {
152 1 : *_msg = msg;
153 : }
154 :
155 1 : return EOK;
156 : }
157 :
158 2 : errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx,
159 : struct sss_idmap_ctx *idmap_ctx,
160 : struct PAC_LOGON_INFO *logon_info,
161 : char **_user_sid_str,
162 : char **_primary_group_sid_str,
163 : size_t *_num_sids,
164 : char *** _sid_list)
165 : {
166 : int ret;
167 : size_t s;
168 : struct netr_SamInfo3 *info3;
169 2 : char *sid_str = NULL;
170 2 : char *msid_str = NULL;
171 2 : char *user_dom_sid_str = NULL;
172 : size_t user_dom_sid_str_len;
173 : enum idmap_error_code err;
174 2 : hash_table_t *sid_table = NULL;
175 : hash_key_t key;
176 : hash_value_t value;
177 : char *rid_start;
178 2 : char *user_sid_str = NULL;
179 2 : char *primary_group_sid_str = NULL;
180 : size_t c;
181 : size_t num_sids;
182 2 : char **sid_list = NULL;
183 2 : struct hash_iter_context_t *iter = NULL;
184 : hash_entry_t *entry;
185 : TALLOC_CTX *tmp_ctx;
186 :
187 2 : if (idmap_ctx == NULL || logon_info == NULL
188 2 : || _num_sids == NULL || _sid_list == NULL) {
189 0 : DEBUG(SSSDBG_OP_FAILURE, "Missing parameter.\n");
190 0 : return EINVAL;
191 : }
192 :
193 2 : tmp_ctx = talloc_new(NULL);
194 2 : if (tmp_ctx == NULL) {
195 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
196 0 : return ENOMEM;
197 : }
198 :
199 2 : info3 = &logon_info->info3;
200 :
201 2 : ret = sss_hash_create(tmp_ctx,
202 2 : info3->sidcount + info3->base.groups.count + 2,
203 : &sid_table);
204 2 : if (ret != EOK) {
205 0 : DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n");
206 0 : goto done;
207 : }
208 :
209 2 : key.type = HASH_KEY_STRING;
210 2 : value.type = HASH_VALUE_ULONG;
211 :
212 2 : err = sss_idmap_smb_sid_to_sid(idmap_ctx, info3->base.domain_sid,
213 : &user_dom_sid_str);
214 2 : if (err != IDMAP_SUCCESS) {
215 0 : DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n");
216 0 : ret = EFAULT;
217 0 : goto done;
218 : }
219 :
220 2 : user_dom_sid_str_len = strlen(user_dom_sid_str);
221 2 : sid_str = talloc_zero_size(tmp_ctx, user_dom_sid_str_len + 12);
222 2 : if (sid_str == NULL) {
223 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n");
224 0 : ret = ENOMEM;
225 0 : goto done;
226 : }
227 2 : rid_start = sid_str + user_dom_sid_str_len;
228 :
229 2 : memcpy(sid_str, user_dom_sid_str, user_dom_sid_str_len);
230 :
231 2 : memset(rid_start, '\0', 12);
232 2 : ret = snprintf(rid_start, 12, "-%lu",
233 2 : (unsigned long) info3->base.rid);
234 2 : if (ret < 0 || ret > 12) {
235 0 : DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n");
236 0 : ret = EIO;
237 0 : goto done;
238 : }
239 :
240 2 : user_sid_str = talloc_strdup(tmp_ctx, sid_str);
241 2 : if (user_sid_str == NULL) {
242 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
243 0 : ret = ENOMEM;
244 0 : goto done;
245 : }
246 :
247 2 : key.str = sid_str;
248 2 : value.ul = 0;
249 :
250 2 : memset(rid_start, '\0', 12);
251 2 : ret = snprintf(rid_start, 12, "-%lu",
252 2 : (unsigned long) info3->base.primary_gid);
253 2 : if (ret < 0 || ret > 12) {
254 0 : DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n");
255 0 : ret = EIO;
256 0 : goto done;
257 : }
258 :
259 2 : primary_group_sid_str = talloc_strdup(tmp_ctx, sid_str);
260 2 : if (primary_group_sid_str == NULL) {
261 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
262 0 : ret = ENOMEM;
263 0 : goto done;
264 : }
265 :
266 2 : key.str = sid_str;
267 2 : value.ul = 0;
268 :
269 2 : ret = hash_enter(sid_table, &key, &value);
270 2 : if (ret != HASH_SUCCESS) {
271 0 : DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n",
272 : ret, hash_error_string(ret));
273 0 : ret = EIO;
274 0 : goto done;
275 : }
276 :
277 :
278 12 : for (s = 0; s < info3->base.groups.count; s++) {
279 10 : memset(rid_start, '\0', 12);
280 10 : ret = snprintf(rid_start, 12, "-%lu",
281 10 : (unsigned long) info3->base.groups.rids[s].rid);
282 10 : if (ret < 0 || ret > 12) {
283 0 : DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n");
284 0 : ret = EIO;
285 0 : goto done;
286 : }
287 :
288 10 : key.str = sid_str;
289 10 : value.ul = 0;
290 :
291 10 : ret = hash_enter(sid_table, &key, &value);
292 10 : if (ret != HASH_SUCCESS) {
293 0 : DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n",
294 : ret, hash_error_string(ret));
295 0 : ret = EIO;
296 0 : goto done;
297 : }
298 :
299 : }
300 :
301 4 : for(s = 0; s < info3->sidcount; s++) {
302 2 : err = sss_idmap_smb_sid_to_sid(idmap_ctx, info3->sids[s].sid,
303 : &msid_str);
304 2 : if (err != IDMAP_SUCCESS) {
305 0 : DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n");
306 0 : ret = EFAULT;
307 0 : goto done;
308 : }
309 :
310 2 : key.str = msid_str;
311 2 : value.ul = 0;
312 :
313 2 : ret = hash_enter(sid_table, &key, &value);
314 2 : sss_idmap_free_sid(idmap_ctx, msid_str);
315 2 : if (ret != HASH_SUCCESS) {
316 0 : DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n",
317 : ret, hash_error_string(ret));
318 0 : ret = EIO;
319 0 : goto done;
320 : }
321 : }
322 :
323 2 : num_sids = hash_count(sid_table);
324 2 : sid_list = talloc_array(tmp_ctx, char *, num_sids);
325 2 : if (sid_list == NULL) {
326 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
327 0 : ret = ENOMEM;
328 0 : goto done;
329 : }
330 :
331 2 : iter = new_hash_iter_context(sid_table);
332 2 : if (iter == NULL) {
333 0 : DEBUG(SSSDBG_OP_FAILURE, "new_hash_iter_context failed.\n");
334 0 : ret = EINVAL;
335 0 : goto done;
336 : }
337 :
338 2 : c = 0;
339 16 : while ((entry = iter->next(iter)) != NULL) {
340 12 : sid_list[c] = talloc_strdup(sid_list, entry->key.str);
341 12 : if (sid_list[c] == NULL) {
342 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
343 0 : ret = ENOMEM;
344 0 : goto done;
345 : }
346 12 : c++;
347 : }
348 :
349 2 : ret = EOK;
350 :
351 : done:
352 2 : sss_idmap_free_sid(idmap_ctx, user_dom_sid_str);
353 2 : hash_destroy(sid_table);
354 :
355 2 : if (ret == EOK) {
356 2 : *_sid_list = talloc_steal(mem_ctx, sid_list);
357 2 : *_user_sid_str = talloc_steal(mem_ctx, user_sid_str);
358 2 : *_num_sids = num_sids;
359 2 : *_primary_group_sid_str = talloc_steal(mem_ctx, primary_group_sid_str);
360 : }
361 :
362 2 : talloc_free(tmp_ctx);
363 :
364 2 : return ret;
365 : }
366 :
367 1 : errno_t ad_get_pac_data_from_user_entry(TALLOC_CTX *mem_ctx,
368 : struct ldb_message *msg,
369 : struct sss_idmap_ctx *idmap_ctx,
370 : char **_username,
371 : char **user_sid,
372 : char **primary_group_sid,
373 : size_t *num_sids,
374 : char ***group_sids)
375 : {
376 : int ret;
377 : struct ldb_message_element *el;
378 1 : struct PAC_LOGON_INFO *logon_info = NULL;
379 : const char *dummy;
380 1 : TALLOC_CTX *tmp_ctx = NULL;
381 : char *username;
382 :
383 1 : tmp_ctx = talloc_new(NULL);
384 1 : if (tmp_ctx == NULL) {
385 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
386 0 : return ENOMEM;
387 : }
388 :
389 1 : el = ldb_msg_find_element(msg, SYSDB_PAC_BLOB);
390 1 : if (el == NULL) {
391 0 : DEBUG(SSSDBG_OP_FAILURE, "Missing PAC blob.\n");
392 0 : ret = EINVAL;
393 0 : goto done;
394 : }
395 :
396 1 : if (el->num_values != 1) {
397 0 : DEBUG(SSSDBG_OP_FAILURE, "Expected only one PAC blob.");
398 0 : ret = EINVAL;
399 0 : goto done;
400 : }
401 :
402 1 : ret = ad_get_data_from_pac(tmp_ctx, el->values[0].data,
403 1 : el->values[0].length,
404 : &logon_info);
405 1 : if (ret != EOK) {
406 0 : DEBUG(SSSDBG_OP_FAILURE, "get_data_from_pac failed.\n");
407 0 : goto done;
408 : }
409 :
410 1 : dummy = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
411 1 : if (dummy == NULL) {
412 0 : DEBUG(SSSDBG_OP_FAILURE, "Missing user name in cache entry.\n");
413 0 : ret = EINVAL;
414 0 : goto done;
415 : }
416 :
417 1 : username = talloc_strdup(tmp_ctx, dummy);
418 1 : if (username == NULL) {
419 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
420 0 : ret = ENOMEM;
421 0 : goto done;
422 : }
423 :
424 1 : ret = ad_get_sids_from_pac(mem_ctx, idmap_ctx, logon_info,
425 : user_sid, primary_group_sid,
426 : num_sids, group_sids);
427 1 : if (ret != EOK) {
428 0 : DEBUG(SSSDBG_OP_FAILURE, "get_sids_from_pac failed.\n");
429 0 : goto done;
430 : }
431 :
432 1 : *_username = talloc_steal(mem_ctx, username);
433 :
434 1 : ret = EOK;
435 : done:
436 1 : talloc_free(tmp_ctx);
437 :
438 1 : return ret;
439 : }
440 :
441 : struct ad_handle_pac_initgr_state {
442 : struct be_acct_req *ar;
443 : const char *err;
444 : int dp_error;
445 : int sdap_ret;
446 :
447 : size_t num_missing_sids;
448 : char **missing_sids;
449 : size_t num_cached_groups;
450 : char **cached_groups;
451 : char *username;
452 : struct sss_domain_info *user_dom;
453 : };
454 :
455 : static void ad_handle_pac_initgr_lookup_sids_done(struct tevent_req *subreq);
456 :
457 0 : struct tevent_req *ad_handle_pac_initgr_send(TALLOC_CTX *mem_ctx,
458 : struct be_ctx *be_ctx,
459 : struct be_acct_req *ar,
460 : struct sdap_id_ctx *id_ctx,
461 : struct sdap_domain *sdom,
462 : struct sdap_id_conn_ctx *conn,
463 : bool noexist_delete,
464 : struct ldb_message *msg)
465 : {
466 : int ret;
467 : struct ad_handle_pac_initgr_state *state;
468 : struct tevent_req *req;
469 : struct tevent_req *subreq;
470 : char *user_sid;
471 : char *primary_group_sid;
472 : size_t num_sids;
473 : char **group_sids;
474 : bool use_id_mapping;
475 :
476 0 : req = tevent_req_create(mem_ctx, &state,
477 : struct ad_handle_pac_initgr_state);
478 0 : if (req == NULL) {
479 0 : DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
480 0 : return NULL;
481 : }
482 0 : state->user_dom = sdom->dom;
483 :
484 : /* The following variables are currently unused because no sub-request
485 : * returns any of them. But they are needed to allow the same signature as
486 : * sdap_handle_acct_req_recv() from the alternative group-membership
487 : * lookup path. */
488 0 : state->err = NULL;
489 0 : state->dp_error = DP_ERR_OK;
490 0 : state->sdap_ret = EOK;
491 :
492 0 : ret = ad_get_pac_data_from_user_entry(state, msg,
493 0 : id_ctx->opts->idmap_ctx->map,
494 0 : &state->username,
495 : &user_sid, &primary_group_sid,
496 : &num_sids, &group_sids);
497 0 : if (ret != EOK) {
498 0 : DEBUG(SSSDBG_OP_FAILURE, "ad_get_pac_data_from_user_entry failed.\n");
499 0 : goto done;
500 : }
501 :
502 0 : use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
503 0 : id_ctx->opts->idmap_ctx,
504 0 : sdom->dom->name,
505 0 : sdom->dom->domain_id);
506 0 : if (use_id_mapping
507 0 : && sdom->dom->ignore_group_members == false) {
508 : /* In contrast to the tokenGroups based group-membership lookup the
509 : * PAC based approach can be used for sub-domains with id-mapping as
510 : * well because the PAC will only contain groups which are valid in
511 : * the target domain, i.e. it will not contain domain-local groups for
512 : * domains other than the user domain. This means the groups must not
513 : * be looked up immediately to determine if they are domain-local or
514 : * not.
515 : *
516 : * Additionally, as a temporary workaround until
517 : * https://fedorahosted.org/sssd/ticket/2522 is fixed, we also fetch
518 : * the group object if group members are ignored to avoid having to
519 : * transfer and retain members when the fake tokengroups object
520 : * without name is replaced by the full group object.
521 : */
522 :
523 0 : DEBUG(SSSDBG_TRACE_ALL, "Running PAC processing with id-mapping.\n");
524 :
525 0 : ret = sdap_ad_save_group_membership_with_idmapping(state->username,
526 : sdom->dom,
527 0 : id_ctx->opts->idmap_ctx,
528 : num_sids, group_sids);
529 0 : if (ret != EOK) {
530 0 : DEBUG(SSSDBG_OP_FAILURE,
531 : "sdap_ad_save_group_membership_with_idmapping failed.\n");
532 : }
533 :
534 : /* this path only includes cache operation, so we can finish the
535 : * request immediately */
536 0 : goto done;
537 : } else {
538 :
539 0 : DEBUG(SSSDBG_TRACE_ALL, "Running PAC processing with external IDs.\n");
540 :
541 0 : ret = sdap_ad_tokengroups_get_posix_members(state, sdom->dom,
542 : num_sids, group_sids,
543 0 : &state->num_missing_sids,
544 0 : &state->missing_sids,
545 0 : &state->num_cached_groups,
546 0 : &state->cached_groups);
547 0 : if (ret != EOK) {
548 0 : DEBUG(SSSDBG_OP_FAILURE,
549 : "sdap_ad_tokengroups_get_posix_members failed.\n");
550 0 : goto done;
551 : }
552 :
553 : /* download missing SIDs */
554 0 : subreq = sdap_ad_resolve_sids_send(state, be_ctx->ev, id_ctx,
555 : conn,
556 : id_ctx->opts, sdom->dom,
557 0 : state->missing_sids);
558 0 : if (subreq == NULL) {
559 0 : DEBUG(SSSDBG_OP_FAILURE, "sdap_ad_resolve_sids_send failed.\n");
560 0 : ret = ENOMEM;
561 0 : goto done;
562 : }
563 :
564 0 : tevent_req_set_callback(subreq, ad_handle_pac_initgr_lookup_sids_done,
565 : req);
566 :
567 : }
568 :
569 0 : return req;
570 :
571 : done:
572 0 : if (ret == EOK) {
573 0 : tevent_req_done(req);
574 : } else {
575 0 : tevent_req_error(req, ret);
576 : }
577 0 : tevent_req_post(req, be_ctx->ev);
578 :
579 0 : return req;
580 : }
581 :
582 0 : static void ad_handle_pac_initgr_lookup_sids_done(struct tevent_req *subreq)
583 : {
584 : struct ad_handle_pac_initgr_state *state;
585 0 : struct tevent_req *req = NULL;
586 : errno_t ret;
587 : char **cached_groups;
588 : size_t num_cached_groups;
589 :
590 0 : req = tevent_req_callback_data(subreq, struct tevent_req);
591 0 : state = tevent_req_data(req, struct ad_handle_pac_initgr_state);
592 :
593 0 : ret = sdap_ad_resolve_sids_recv(subreq);
594 0 : talloc_zfree(subreq);
595 0 : if (ret != EOK) {
596 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to resolve missing SIDs "
597 : "[%d]: %s\n", ret, strerror(ret));
598 0 : goto done;
599 : }
600 :
601 0 : ret = sdap_ad_tokengroups_get_posix_members(state, state->user_dom,
602 : state->num_missing_sids,
603 : state->missing_sids,
604 : NULL, NULL,
605 : &num_cached_groups,
606 : &cached_groups);
607 0 : if (ret != EOK){
608 0 : DEBUG(SSSDBG_MINOR_FAILURE,
609 : "sdap_ad_tokengroups_get_posix_members failed [%d]: %s\n",
610 : ret, strerror(ret));
611 0 : goto done;
612 : }
613 :
614 0 : state->cached_groups = concatenate_string_array(state,
615 : state->cached_groups,
616 : state->num_cached_groups,
617 : cached_groups,
618 : num_cached_groups);
619 0 : if (state->cached_groups == NULL) {
620 0 : ret = ENOMEM;
621 0 : goto done;
622 : }
623 :
624 : /* update membership of existing groups */
625 0 : ret = sdap_ad_tokengroups_update_members(state->username,
626 0 : state->user_dom->sysdb,
627 : state->user_dom,
628 : state->cached_groups);
629 0 : if (ret != EOK) {
630 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Membership update failed [%d]: %s\n",
631 : ret, strerror(ret));
632 0 : goto done;
633 : }
634 :
635 : done:
636 0 : if (ret != EOK) {
637 0 : tevent_req_error(req, ret);
638 0 : return;
639 : }
640 :
641 0 : tevent_req_done(req);
642 : }
643 :
644 0 : errno_t ad_handle_pac_initgr_recv(struct tevent_req *req,
645 : int *_dp_error, const char **_err,
646 : int *sdap_ret)
647 : {
648 : struct ad_handle_pac_initgr_state *state;
649 :
650 0 : state = tevent_req_data(req, struct ad_handle_pac_initgr_state);
651 :
652 0 : if (_dp_error) {
653 0 : *_dp_error = state->dp_error;
654 : }
655 :
656 0 : if (_err) {
657 0 : *_err = state->err;
658 : }
659 :
660 0 : if (sdap_ret) {
661 0 : *sdap_ret = state->sdap_ret;
662 : }
663 0 : TEVENT_REQ_RETURN_ON_ERROR(req);
664 :
665 0 : return EOK;
666 : }
|