LCOV - code coverage report
Current view: top level - providers/ad - ad_pac.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 146 315 46.3 %
Date: 2016-06-29 Functions: 4 7 57.1 %

          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             : }

Generated by: LCOV version 1.10