LCOV - code coverage report
Current view: top level - providers/ipa - ipa_id.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 640 0.0 %
Date: 2016-06-29 Functions: 0 27 0.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     IPA Identity Backend Module
       5             : 
       6             :     Authors:
       7             :         Jan Zeleny <jzeleny@redhat.com>
       8             : 
       9             :     Copyright (C) 2011 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include <errno.h>
      26             : 
      27             : #include "util/util.h"
      28             : #include "db/sysdb.h"
      29             : #include "providers/ldap/ldap_common.h"
      30             : #include "providers/ldap/sdap_async.h"
      31             : #include "providers/ipa/ipa_id.h"
      32             : 
      33             : static struct tevent_req *
      34             : ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev,
      35             :                              struct ipa_id_ctx *ipa_ctx,
      36             :                              struct be_acct_req *ar);
      37             : 
      38             : static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error);
      39             : 
      40           0 : static bool is_object_overridable(struct be_acct_req *ar)
      41             : {
      42           0 :     bool ret = false;
      43             : 
      44           0 :     switch (ar->entry_type & BE_REQ_TYPE_MASK) {
      45             :     case BE_REQ_USER:
      46             :     case BE_REQ_GROUP:
      47             :     case BE_REQ_INITGROUPS:
      48             :     case BE_REQ_BY_SECID:
      49             :     case BE_REQ_USER_AND_GROUP:
      50             :     case BE_REQ_BY_UUID:
      51             :     case BE_REQ_BY_CERT:
      52           0 :         ret = true;
      53           0 :         break;
      54             :     default:
      55           0 :         break;
      56             :     }
      57             : 
      58           0 :     return ret;
      59             : }
      60             : 
      61             : struct ipa_resolve_user_list_state {
      62             :     struct tevent_context *ev;
      63             :     struct ipa_id_ctx *ipa_ctx;
      64             :     struct ldb_message_element *users;
      65             :     const char *domain_name;
      66             :     size_t user_idx;
      67             : 
      68             :     int dp_error;
      69             : };
      70             : 
      71             : static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req);
      72             : static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq);
      73             : 
      74             : static struct tevent_req *
      75           0 : ipa_resolve_user_list_send(TALLOC_CTX *memctx, struct tevent_context *ev,
      76             :                            struct ipa_id_ctx *ipa_ctx,
      77             :                            const char *domain_name,
      78             :                            struct ldb_message_element *users)
      79             : {
      80             :     int ret;
      81             :     struct tevent_req *req;
      82             :     struct ipa_resolve_user_list_state *state;
      83             : 
      84           0 :     req = tevent_req_create(memctx, &state,
      85             :                             struct ipa_resolve_user_list_state);
      86           0 :     if (req == NULL) {
      87           0 :         DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
      88           0 :         return NULL;
      89             :     }
      90             : 
      91           0 :     state->ev = ev;
      92           0 :     state->ipa_ctx = ipa_ctx;
      93           0 :     state->domain_name = domain_name;
      94           0 :     state->users = users;
      95           0 :     state->user_idx = 0;
      96           0 :     state->dp_error = DP_ERR_FATAL;
      97             : 
      98           0 :     ret = ipa_resolve_user_list_get_user_step(req);
      99           0 :     if (ret == EAGAIN) {
     100           0 :         return req;
     101           0 :     } else if (ret == EOK) {
     102           0 :         state->dp_error = DP_ERR_OK;
     103           0 :         tevent_req_done(req);
     104             :     } else {
     105           0 :         DEBUG(SSSDBG_OP_FAILURE,
     106             :               "ipa_resolve_user_list_get_user_step failed.\n");
     107           0 :         tevent_req_error(req, ret);
     108             :     }
     109           0 :     tevent_req_post(req, ev);
     110           0 :     return req;
     111             : }
     112             : 
     113           0 : static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req)
     114             : {
     115             :     int ret;
     116             :     struct tevent_req *subreq;
     117             :     struct be_acct_req *ar;
     118           0 :     struct ipa_resolve_user_list_state *state = tevent_req_data(req,
     119             :                                             struct ipa_resolve_user_list_state);
     120             : 
     121           0 :     if (state->user_idx >= state->users->num_values) {
     122           0 :         return EOK;
     123             :     }
     124             : 
     125           0 :     ret = get_be_acct_req_for_user_name(state,
     126           0 :                             (char *) state->users->values[state->user_idx].data,
     127             :                             state->domain_name, &ar);
     128           0 :     if (ret != EOK) {
     129           0 :         DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_user_name failed.\n");
     130           0 :         return ret;
     131             :     }
     132             : 
     133           0 :     DEBUG(SSSDBG_TRACE_ALL, "Trying to resolve user [%s].\n", ar->filter_value);
     134             : 
     135           0 :     subreq = ipa_id_get_account_info_send(state, state->ev, state->ipa_ctx, ar);
     136           0 :     if (subreq == NULL) {
     137           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct_req_send failed.\n");
     138           0 :         return ENOMEM;
     139             :     }
     140             : 
     141           0 :     tevent_req_set_callback(subreq, ipa_resolve_user_list_get_user_done, req);
     142             : 
     143           0 :     return EAGAIN;
     144             : }
     145             : 
     146           0 : static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq)
     147             : {
     148           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     149             :                                                 struct tevent_req);
     150           0 :     struct ipa_resolve_user_list_state *state = tevent_req_data(req,
     151             :                                             struct ipa_resolve_user_list_state);
     152             :     int ret;
     153             : 
     154           0 :     ret = ipa_id_get_account_info_recv(subreq, &state->dp_error);
     155           0 :     talloc_zfree(subreq);
     156           0 :     if (ret != EOK) {
     157           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct request failed: %d\n", ret);
     158           0 :         goto done;
     159             :     }
     160             : 
     161           0 :     state->user_idx++;
     162             : 
     163           0 :     ret = ipa_resolve_user_list_get_user_step(req);
     164           0 :     if (ret == EAGAIN) {
     165           0 :         return;
     166             :     }
     167           0 :     if (ret != EOK) {
     168           0 :         DEBUG(SSSDBG_OP_FAILURE,
     169             :               "ipa_resolve_user_list_get_user_step failed.\n");
     170             :     }
     171             : 
     172             : done:
     173           0 :     if (ret == EOK) {
     174           0 :         state->dp_error = DP_ERR_OK;
     175           0 :         tevent_req_done(req);
     176             :     } else {
     177           0 :         if (state->dp_error == DP_ERR_OK) {
     178           0 :             state->dp_error = DP_ERR_FATAL;
     179             :         }
     180           0 :         tevent_req_error(req, ret);
     181             :     }
     182           0 :     return;
     183             : }
     184             : 
     185           0 : static int ipa_resolve_user_list_recv(struct tevent_req *req, int *dp_error)
     186             : {
     187           0 :     struct ipa_resolve_user_list_state *state = tevent_req_data(req,
     188             :                                             struct ipa_resolve_user_list_state);
     189             : 
     190           0 :     if (dp_error) {
     191           0 :         *dp_error = state->dp_error;
     192             :     }
     193             : 
     194           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     195             : 
     196           0 :     return EOK;
     197             : }
     198             : 
     199             : struct ipa_initgr_get_overrides_state {
     200             :     struct tevent_context *ev;
     201             :     struct ipa_id_ctx *ipa_ctx;
     202             :     struct sss_domain_info *user_dom;
     203             :     const char *realm;
     204             : 
     205             :     struct ldb_message **groups;
     206             :     size_t group_count;
     207             :     const char *groups_id_attr;
     208             :     size_t group_idx;
     209             :     struct be_acct_req *ar;
     210             : 
     211             :     int dp_error;
     212             : };
     213             : 
     214             : static int ipa_initgr_get_overrides_step(struct tevent_req *req);
     215             : 
     216             : struct tevent_req *
     217           0 : ipa_initgr_get_overrides_send(TALLOC_CTX *memctx,
     218             :                              struct tevent_context *ev,
     219             :                              struct ipa_id_ctx *ipa_ctx,
     220             :                              struct sss_domain_info *user_dom,
     221             :                              size_t groups_count,
     222             :                              struct ldb_message **groups,
     223             :                              const char *groups_id_attr)
     224             : {
     225             :     int ret;
     226             :     struct tevent_req *req;
     227             :     struct ipa_initgr_get_overrides_state *state;
     228             : 
     229           0 :     req = tevent_req_create(memctx, &state,
     230             :                             struct ipa_initgr_get_overrides_state);
     231           0 :     if (req == NULL) {
     232           0 :         DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
     233           0 :         return NULL;
     234             :     }
     235           0 :     state->ev = ev;
     236           0 :     state->ipa_ctx = ipa_ctx;
     237           0 :     state->user_dom = user_dom;
     238           0 :     state->groups = groups;
     239           0 :     state->group_count = groups_count;
     240           0 :     state->group_idx = 0;
     241           0 :     state->ar = NULL;
     242           0 :     state->realm = dp_opt_get_string(state->ipa_ctx->ipa_options->basic,
     243             :                                      IPA_KRB5_REALM);
     244           0 :     if (state->realm == NULL) {
     245           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
     246           0 :         ret = EINVAL;
     247           0 :         goto done;
     248             :     }
     249           0 :     state->groups_id_attr = talloc_strdup(state, groups_id_attr);
     250           0 :     if (state->groups_id_attr == NULL) {
     251           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
     252           0 :         ret = ENOMEM;
     253           0 :         goto done;
     254             :     }
     255             : 
     256           0 :     ret = ipa_initgr_get_overrides_step(req);
     257             : done:
     258           0 :     if (ret == EOK) {
     259           0 :         tevent_req_done(req);
     260           0 :         tevent_req_post(req, ev);
     261           0 :     } else if (ret != EAGAIN) {
     262           0 :         tevent_req_error(req, ret);
     263           0 :         tevent_req_post(req, ev);
     264             :     }
     265             : 
     266           0 :     return req;
     267             : }
     268             : 
     269             : static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq);
     270             : 
     271           0 : static int ipa_initgr_get_overrides_step(struct tevent_req *req)
     272             : {
     273             :     int ret;
     274             :     struct tevent_req *subreq;
     275             :     const char *ipa_uuid;
     276           0 :     struct ipa_initgr_get_overrides_state *state = tevent_req_data(req,
     277             :                                         struct ipa_initgr_get_overrides_state);
     278             : 
     279           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     280             :           "Processing group %zu/%zu\n", state->group_idx, state->group_count);
     281             : 
     282           0 :     if (state->group_idx >= state->group_count) {
     283           0 :         return EOK;
     284             :     }
     285             : 
     286           0 :     ipa_uuid = ldb_msg_find_attr_as_string(state->groups[state->group_idx],
     287             :                                            state->groups_id_attr, NULL);
     288           0 :     if (ipa_uuid == NULL) {
     289             :         /* This should never happen, the search filter used to get the list
     290             :          * of groups includes "uuid=*"
     291             :          */
     292           0 :         DEBUG(SSSDBG_OP_FAILURE,
     293             :               "The group %s has no UUID attribute %s, error!\n",
     294             :               ldb_dn_get_linearized(state->groups[state->group_idx]->dn),
     295             :               state->groups_id_attr);
     296           0 :         return EINVAL;
     297             :     }
     298             : 
     299           0 :     talloc_free(state->ar); /* Avoid spiking memory with many groups */
     300             : 
     301           0 :     if (strcmp(state->groups_id_attr, SYSDB_UUID) == 0) {
     302           0 :         ret = get_be_acct_req_for_uuid(state, ipa_uuid,
     303           0 :                                        state->user_dom->name, &state->ar);
     304           0 :         if (ret != EOK) {
     305           0 :             DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n");
     306           0 :             return ret;
     307             :         }
     308           0 :     } else if (strcmp(state->groups_id_attr, SYSDB_SID_STR) == 0) {
     309           0 :         ret = get_be_acct_req_for_sid(state, ipa_uuid,
     310           0 :                                       state->user_dom->name, &state->ar);
     311           0 :         if (ret != EOK) {
     312           0 :             DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n");
     313           0 :             return ret;
     314             :         }
     315             :     } else {
     316           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported groups ID type [%s].\n",
     317             :                                    state->groups_id_attr);
     318           0 :         return EINVAL;
     319             :     }
     320             : 
     321           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Fetching group %s\n", ipa_uuid);
     322             : 
     323           0 :     subreq = ipa_get_ad_override_send(state, state->ev,
     324           0 :                                       state->ipa_ctx->sdap_id_ctx,
     325           0 :                                       state->ipa_ctx->ipa_options,
     326             :                                       state->realm,
     327           0 :                                       state->ipa_ctx->view_name,
     328             :                                       state->ar);
     329           0 :     if (subreq == NULL) {
     330           0 :         DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
     331           0 :         return ENOMEM;
     332             :     }
     333           0 :     tevent_req_set_callback(subreq,
     334             :                             ipa_initgr_get_overrides_override_done, req);
     335           0 :     return EAGAIN;
     336             : }
     337             : 
     338           0 : static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq)
     339             : {
     340           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     341             :                                                 struct tevent_req);
     342           0 :     struct ipa_initgr_get_overrides_state *state = tevent_req_data(req,
     343             :                                         struct ipa_initgr_get_overrides_state);
     344             :     int ret;
     345           0 :     struct sysdb_attrs *override_attrs = NULL;
     346             : 
     347           0 :     ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state,
     348             :                                    &override_attrs);
     349           0 :     talloc_zfree(subreq);
     350           0 :     if (ret != EOK) {
     351           0 :         DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
     352           0 :         tevent_req_error(req, ret);
     353           0 :         return;
     354             :     }
     355             : 
     356           0 :     if (is_default_view(state->ipa_ctx->view_name)) {
     357           0 :         ret = sysdb_apply_default_override(state->user_dom, override_attrs,
     358           0 :                                        state->groups[state->group_idx]->dn);
     359             :     } else {
     360           0 :         ret = sysdb_store_override(state->user_dom,
     361           0 :                                    state->ipa_ctx->view_name,
     362             :                                    SYSDB_MEMBER_GROUP,
     363             :                                    override_attrs,
     364           0 :                                    state->groups[state->group_idx]->dn);
     365             :     }
     366           0 :     talloc_free(override_attrs);
     367           0 :     if (ret != EOK) {
     368           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n");
     369           0 :         tevent_req_error(req, ret);
     370           0 :         return;
     371             :     }
     372             : 
     373           0 :     state->group_idx++;
     374             : 
     375           0 :     ret = ipa_initgr_get_overrides_step(req);
     376           0 :     if (ret == EAGAIN) {
     377           0 :         return;
     378           0 :     } else if (ret != EOK) {
     379           0 :         tevent_req_error(req, ret);
     380           0 :         return;
     381             :     }
     382             : 
     383           0 :     tevent_req_done(req);
     384             : }
     385             : 
     386           0 : int ipa_initgr_get_overrides_recv(struct tevent_req *req, int *dp_error)
     387             : {
     388           0 :     struct ipa_initgr_get_overrides_state *state = tevent_req_data(req,
     389             :                                         struct ipa_initgr_get_overrides_state);
     390             : 
     391           0 :     if (dp_error) {
     392           0 :         *dp_error = state->dp_error;
     393             :     }
     394             : 
     395           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     396           0 :     return EOK;
     397             : }
     398             : 
     399             : /* Given a user name, retrieve an array of group UUIDs of groups that have
     400             :  * no overrideDN attribute but do have an UUID attribute.
     401             :  */
     402           0 : static errno_t ipa_id_get_group_uuids(TALLOC_CTX *mem_ctx,
     403             :                                       struct sysdb_ctx *sysdb,
     404             :                                       size_t *_msgs_count,
     405             :                                       struct ldb_message ***_msgs)
     406             : {
     407             :     const char *filter;
     408             :     TALLOC_CTX *tmp_ctx;
     409           0 :     char **uuid_list = NULL;
     410             :     errno_t ret;
     411             :     struct ldb_dn *base_dn;
     412           0 :     const char *attrs[] = { SYSDB_UUID, NULL };
     413             :     size_t msgs_count;
     414             :     struct ldb_message **msgs;
     415             : 
     416           0 :     tmp_ctx = talloc_new(mem_ctx);
     417           0 :     if (tmp_ctx == NULL) {
     418           0 :         return ENOMEM;
     419             :     }
     420             : 
     421           0 :     filter = talloc_asprintf(tmp_ctx,
     422             :                              "(&(objectclass=%s)(!(%s=*))(%s=*))",
     423             :                              SYSDB_GROUP_CLASS, SYSDB_OVERRIDE_DN,
     424             :                              SYSDB_UUID);
     425           0 :     if (filter == NULL) {
     426           0 :         ret = ENOMEM;
     427           0 :         goto done;
     428             :     }
     429             : 
     430           0 :     base_dn = sysdb_base_dn(sysdb, tmp_ctx);
     431           0 :     if (base_dn == NULL) {
     432           0 :         ret = ENOMEM;
     433           0 :         goto done;
     434             :     }
     435             : 
     436           0 :     ret = sysdb_search_entry(tmp_ctx, sysdb, base_dn,
     437             :                              LDB_SCOPE_SUBTREE, filter, attrs,
     438             :                              &msgs_count, &msgs);
     439           0 :     if (ret == ENOENT) {
     440           0 :         DEBUG(SSSDBG_TRACE_FUNC,
     441             :               "No groups without %s in sysdb\n", SYSDB_OVERRIDE_DN);
     442           0 :         ret = EOK;
     443           0 :         goto done;
     444           0 :     } else if (ret != EOK) {
     445           0 :         goto done;
     446             :     }
     447             : 
     448           0 :     uuid_list = talloc_zero_array(tmp_ctx, char *, msgs_count);
     449           0 :     if (uuid_list == NULL) {
     450           0 :         goto done;
     451             :     }
     452             : 
     453           0 :     *_msgs_count = msgs_count;
     454           0 :     *_msgs = talloc_steal(mem_ctx, msgs);
     455           0 :     ret = EOK;
     456             : done:
     457           0 :     talloc_free(tmp_ctx);
     458           0 :     return ret;
     459             : }
     460             : 
     461             : struct ipa_id_get_account_info_state {
     462             :     struct tevent_context *ev;
     463             :     struct ipa_id_ctx *ipa_ctx;
     464             :     struct sdap_id_ctx *ctx;
     465             :     struct sdap_id_op *op;
     466             :     struct sysdb_ctx *sysdb;
     467             :     struct sss_domain_info *domain;
     468             :     struct be_acct_req *ar;
     469             :     struct be_acct_req *orig_ar;
     470             :     const char *realm;
     471             : 
     472             :     struct sysdb_attrs *override_attrs;
     473             :     struct ldb_message *obj_msg;
     474             :     struct ldb_message_element *ghosts;
     475             : 
     476             :     struct ldb_message **user_groups;
     477             :     size_t group_cnt;
     478             :     size_t group_idx;
     479             : 
     480             :     int dp_error;
     481             : };
     482             : 
     483             : static void ipa_id_get_account_info_connected(struct tevent_req *subreq);
     484             : static void ipa_id_get_account_info_got_override(struct tevent_req *subreq);
     485             : static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req,
     486             :                                                         struct be_acct_req *ar);
     487             : static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq);
     488             : static void ipa_id_get_account_info_done(struct tevent_req *subreq);
     489             : static void ipa_id_get_user_list_done(struct tevent_req *subreq);
     490             : 
     491             : static struct tevent_req *
     492           0 : ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev,
     493             :                              struct ipa_id_ctx *ipa_ctx,
     494             :                              struct be_acct_req *ar)
     495             : {
     496             :     int ret;
     497             :     struct tevent_req *req;
     498             :     struct tevent_req *subreq;
     499             :     struct ipa_id_get_account_info_state *state;
     500             : 
     501           0 :     req = tevent_req_create(memctx, &state,
     502             :                             struct ipa_id_get_account_info_state);
     503           0 :     if (req == NULL) {
     504           0 :         DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
     505           0 :         return NULL;
     506             :     }
     507             : 
     508           0 :     state->ev = ev;
     509           0 :     state->ipa_ctx = ipa_ctx;
     510           0 :     state->ctx = ipa_ctx->sdap_id_ctx;
     511           0 :     state->dp_error = DP_ERR_FATAL;
     512             : 
     513           0 :     state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache);
     514           0 :     if (state->op == NULL) {
     515           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n");
     516           0 :         ret = ENOMEM;
     517           0 :         goto fail;
     518             :     }
     519             : 
     520           0 :     state->domain = find_domain_by_name(state->ctx->be->domain,
     521             :                                         ar->domain, true);
     522           0 :     if (state->domain == NULL) {
     523           0 :         DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n");
     524           0 :         ret = ENOMEM;
     525           0 :         goto fail;
     526             :     }
     527           0 :     state->sysdb = state->domain->sysdb;
     528           0 :     state->ar = ar;
     529           0 :     state->realm = dp_opt_get_string(state->ipa_ctx->ipa_options->basic,
     530             :                                      IPA_KRB5_REALM);
     531           0 :     if (state->realm == NULL) {
     532           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
     533           0 :         ret = EINVAL;
     534           0 :         goto fail;
     535             :     }
     536             : 
     537             :     /* We can skip the override lookup and go directly to the original object
     538             :      * if
     539             :      * - the lookup is by SID
     540             :      * - there is no view set of it is the default view
     541             :      * - if the EXTRA_INPUT_MAYBE_WITH_VIEW flag is not set
     542             :      */
     543           0 :     if (is_default_view(state->ipa_ctx->view_name)
     544           0 :             || state->ar->filter_type == BE_FILTER_SECID
     545           0 :             || state->ar->extra_value == NULL
     546           0 :             || strcmp(state->ar->extra_value,
     547             :                       EXTRA_INPUT_MAYBE_WITH_VIEW) != 0
     548           0 :             || ! is_object_overridable(state->ar)) {
     549           0 :         ret = ipa_id_get_account_info_get_original_step(req, ar);
     550           0 :         if (ret != EOK) {
     551           0 :             DEBUG(SSSDBG_OP_FAILURE,
     552             :                   "ipa_subdomain_account_get_original_step failed.\n");
     553           0 :             goto fail;
     554             :         }
     555             :     } else {
     556           0 :         subreq = sdap_id_op_connect_send(state->op, state, &ret);
     557           0 :         if (subreq == NULL) {
     558           0 :             DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed.\n");
     559           0 :             goto fail;
     560             :         }
     561           0 :         tevent_req_set_callback(subreq, ipa_id_get_account_info_connected, req);
     562             :     }
     563             : 
     564           0 :     return req;
     565             : 
     566             : fail:
     567           0 :     tevent_req_error(req, ret);
     568           0 :     tevent_req_post(req, ev);
     569           0 :     return req;
     570             : }
     571             : 
     572           0 : static void ipa_id_get_account_info_connected(struct tevent_req *subreq)
     573             : {
     574           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     575             :                                                 struct tevent_req);
     576           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     577             :                                           struct ipa_id_get_account_info_state);
     578           0 :     int dp_error = DP_ERR_FATAL;
     579             :     int ret;
     580             : 
     581           0 :     ret = sdap_id_op_connect_recv(subreq, &dp_error);
     582           0 :     talloc_zfree(subreq);
     583           0 :     if (ret != EOK) {
     584           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect request failed.\n");
     585           0 :         goto fail;
     586             :     }
     587             : 
     588           0 :     subreq = ipa_get_ad_override_send(state, state->ev, state->ctx,
     589           0 :                                       state->ipa_ctx->ipa_options, state->realm,
     590           0 :                                       state->ipa_ctx->view_name, state->ar);
     591           0 :     if (subreq == NULL) {
     592           0 :         DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
     593           0 :         ret = ENOMEM;
     594           0 :         goto fail;
     595             :     }
     596             : 
     597           0 :     tevent_req_set_callback(subreq, ipa_id_get_account_info_got_override, req);
     598             : 
     599           0 :     return;
     600             : 
     601             : fail:
     602           0 :     state->dp_error = dp_error;
     603           0 :     tevent_req_error(req, ret);
     604           0 :     return;
     605             : }
     606             : 
     607           0 : static void ipa_id_get_account_info_got_override(struct tevent_req *subreq)
     608             : {
     609           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     610             :                                                 struct tevent_req);
     611           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     612             :                                           struct ipa_id_get_account_info_state);
     613           0 :     int dp_error = DP_ERR_FATAL;
     614             :     int ret;
     615           0 :     const char *anchor = NULL;
     616             :     char *anchor_domain;
     617             :     char *ipa_uuid;
     618             : 
     619           0 :     ret = ipa_get_ad_override_recv(subreq, &dp_error, state,
     620             :                                    &state->override_attrs);
     621           0 :     talloc_zfree(subreq);
     622           0 :     if (ret != EOK) {
     623           0 :         DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
     624           0 :         goto fail;
     625             :     }
     626             : 
     627           0 :     if (state->override_attrs != NULL) {
     628           0 :         ret = sysdb_attrs_get_string(state->override_attrs,
     629             :                                      SYSDB_OVERRIDE_ANCHOR_UUID,
     630             :                                      &anchor);
     631           0 :         if (ret != EOK) {
     632           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
     633           0 :             goto fail;
     634             :         }
     635             : 
     636           0 :         ret = split_ipa_anchor(state, anchor, &anchor_domain, &ipa_uuid);
     637           0 :         if (ret != EOK) {
     638           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     639             :                   "Unsupported override anchor [%s].\n", anchor);
     640           0 :             ret = EINVAL;
     641           0 :             goto fail;
     642             :         }
     643             : 
     644           0 :         if (strcmp(state->ar->domain, anchor_domain) == 0) {
     645             : 
     646           0 :             state->orig_ar = state->ar;
     647             : 
     648           0 :             ret = get_be_acct_req_for_uuid(state, ipa_uuid,
     649           0 :                                            state->ar->domain,
     650             :                                            &state->ar);
     651           0 :             if (ret != EOK) {
     652           0 :                 DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_uuid failed.\n");
     653           0 :                 goto fail;
     654             :             }
     655             : 
     656           0 :             if ((state->orig_ar->entry_type & BE_REQ_TYPE_MASK)
     657             :                                                          == BE_REQ_INITGROUPS) {
     658           0 :                 DEBUG(SSSDBG_TRACE_ALL,
     659             :                       "Switching back to BE_REQ_INITGROUPS.\n");
     660           0 :                 state->ar->entry_type = BE_REQ_INITGROUPS;
     661           0 :                 state->ar->filter_type = BE_FILTER_UUID;
     662           0 :                 state->ar->attr_type = BE_ATTR_CORE;
     663             :             }
     664             : 
     665             :         } else {
     666           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     667             :                   "Anchor from a different domain [%s], expected [%s]. " \
     668             :                   "This is currently not supported, continue lookup in " \
     669             :                   "local IPA domain.\n",
     670             :                   anchor_domain, state->ar->domain);
     671             :         }
     672             :     }
     673             : 
     674           0 :     ret = ipa_id_get_account_info_get_original_step(req, state->ar);
     675           0 :     if (ret != EOK) {
     676           0 :         DEBUG(SSSDBG_OP_FAILURE,
     677             :               "ipa_subdomain_account_get_original_step failed.\n");
     678           0 :         goto fail;
     679             :     }
     680             : 
     681           0 :     return;
     682             : 
     683             : fail:
     684           0 :     state->dp_error = dp_error;
     685           0 :     tevent_req_error(req, ret);
     686           0 :     return;
     687             : }
     688             : 
     689           0 : static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req,
     690             :                                                          struct be_acct_req *ar)
     691             : {
     692           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     693             :                                           struct ipa_id_get_account_info_state);
     694             :     struct tevent_req *subreq;
     695             : 
     696           0 :     subreq = sdap_handle_acct_req_send(state, state->ctx->be, ar,
     697           0 :                                        state->ipa_ctx->sdap_id_ctx,
     698           0 :                                        state->ipa_ctx->sdap_id_ctx->opts->sdom,
     699           0 :                                        state->ipa_ctx->sdap_id_ctx->conn, true);
     700           0 :     if (subreq == NULL) {
     701           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct_req_send failed.\n");
     702           0 :         return ENOMEM;
     703             :     }
     704           0 :     tevent_req_set_callback(subreq, ipa_id_get_account_info_orig_done, req);
     705             : 
     706           0 :     return EOK;
     707             : }
     708             : 
     709             : static void ipa_id_get_user_groups_done(struct tevent_req *subreq);
     710             : 
     711           0 : static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq)
     712             : {
     713           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     714             :                                                 struct tevent_req);
     715           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     716             :                                           struct ipa_id_get_account_info_state);
     717           0 :     int dp_error = DP_ERR_FATAL;
     718             :     int ret;
     719             :     const char *uuid;
     720             :     const char *class;
     721             :     enum sysdb_member_type type;
     722             : 
     723           0 :     ret = sdap_handle_acct_req_recv(subreq, &dp_error, NULL, NULL);
     724           0 :     talloc_zfree(subreq);
     725           0 :     if (ret != EOK) {
     726           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct request failed: %d\n", ret);
     727           0 :         goto fail;
     728             :     }
     729             : 
     730           0 :     if (! is_object_overridable(state->ar)) {
     731           0 :         state->dp_error = DP_ERR_OK;
     732           0 :         tevent_req_done(req);
     733           0 :         return;
     734             :     }
     735             : 
     736           0 :     ret = get_object_from_cache(state, state->domain, state->ar,
     737             :                                 &state->obj_msg);
     738           0 :     if (ret == ENOENT) {
     739           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Object not found, ending request\n");
     740           0 :         state->dp_error = DP_ERR_OK;
     741           0 :         tevent_req_done(req);
     742           0 :         return;
     743           0 :     } else if (ret != EOK) {
     744           0 :         DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n");
     745           0 :         goto fail;
     746             :     }
     747             : 
     748           0 :     class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS,
     749             :                                         NULL);
     750           0 :     if (class == NULL) {
     751           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n");
     752           0 :         ret = EINVAL;
     753           0 :         goto fail;
     754             :     }
     755             : 
     756             : 
     757           0 :     if (!is_default_view(state->ipa_ctx->view_name)) {
     758             : 
     759           0 :         if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_GROUP
     760           0 :                 || ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_UUID
     761           0 :                         && strcmp(class, SYSDB_GROUP_CLASS) == 0)) {
     762             :             /* check for ghost members because ghost members are not allowed
     763             :              * if a view other than the default view is applied.*/
     764           0 :             state->ghosts = ldb_msg_find_element(state->obj_msg, SYSDB_GHOST);
     765           0 :         } else if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == \
     766             :                         BE_REQ_INITGROUPS) {
     767             :             /* Get UUID list of groups that have no overrideDN set. */
     768           0 :             ret = ipa_id_get_group_uuids(state, state->sysdb,
     769             :                                          &state->group_cnt,
     770             :                                          &state->user_groups);
     771           0 :             if (ret != EOK) {
     772           0 :                 DEBUG(SSSDBG_OP_FAILURE, "Cannot get UUID list: %d\n", ret);
     773           0 :                 goto fail;
     774             :             }
     775             :         }
     776             :     }
     777             : 
     778             : 
     779           0 :     if (state->override_attrs == NULL) {
     780           0 :         uuid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_UUID, NULL);
     781           0 :         if (uuid == NULL) {
     782           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a UUID.\n");
     783           0 :             ret = EINVAL;
     784           0 :             goto fail;
     785             :         }
     786             : 
     787           0 :         ret = get_be_acct_req_for_uuid(state, uuid, state->domain->name,
     788             :                                        &state->ar);
     789           0 :         if (ret != EOK) {
     790           0 :             DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n");
     791           0 :             goto fail;
     792             :         }
     793             : 
     794           0 :         subreq = ipa_get_ad_override_send(state, state->ev,
     795           0 :                                           state->ipa_ctx->sdap_id_ctx,
     796           0 :                                           state->ipa_ctx->ipa_options,
     797             :                                           state->realm,
     798           0 :                                           state->ipa_ctx->view_name,
     799             :                                           state->ar);
     800           0 :         if (subreq == NULL) {
     801           0 :             DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
     802           0 :             ret = ENOMEM;
     803           0 :             goto fail;
     804             :         }
     805           0 :         tevent_req_set_callback(subreq, ipa_id_get_account_info_done, req);
     806           0 :         return;
     807             :     } else {
     808           0 :         if (strcmp(class, SYSDB_USER_CLASS) == 0) {
     809           0 :             type = SYSDB_MEMBER_USER;
     810             :         } else {
     811           0 :             type = SYSDB_MEMBER_GROUP;
     812             :         }
     813             : 
     814           0 :         ret = sysdb_store_override(state->domain, state->ipa_ctx->view_name,
     815             :                                    type,
     816           0 :                                    state->override_attrs, state->obj_msg->dn);
     817           0 :         if (ret != EOK) {
     818           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n");
     819           0 :             goto fail;
     820             :         }
     821             :     }
     822             : 
     823           0 :     if (state->ghosts != NULL) {
     824             :         /* Resolve ghost members */
     825           0 :         subreq = ipa_resolve_user_list_send(state, state->ev,
     826             :                                             state->ipa_ctx,
     827           0 :                                             state->domain->name,
     828             :                                             state->ghosts);
     829           0 :         if (subreq == NULL) {
     830           0 :             DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n");
     831           0 :             ret = ENOMEM;
     832           0 :             goto fail;
     833             :         }
     834           0 :         tevent_req_set_callback(subreq, ipa_id_get_user_list_done, req);
     835           0 :         return;
     836             :     }
     837             : 
     838           0 :     if (state->user_groups != NULL) {
     839           0 :         subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx,
     840             :                                               state->domain, state->group_cnt,
     841             :                                               state->user_groups,
     842             :                                               SYSDB_UUID);
     843           0 :         if (subreq == NULL) {
     844           0 :             DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n");
     845           0 :             ret = ENOMEM;
     846           0 :             goto fail;
     847             :         }
     848           0 :         tevent_req_set_callback(subreq, ipa_id_get_user_groups_done, req);
     849           0 :         return;
     850             :     }
     851             : 
     852           0 :     state->dp_error = DP_ERR_OK;
     853           0 :     tevent_req_done(req);
     854           0 :     return;
     855             : 
     856             : fail:
     857           0 :     state->dp_error = dp_error;
     858           0 :     tevent_req_error(req, ret);
     859           0 :     return;
     860             : }
     861             : 
     862           0 : static void ipa_id_get_account_info_done(struct tevent_req *subreq)
     863             : {
     864           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     865             :                                                 struct tevent_req);
     866           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     867             :                                           struct ipa_id_get_account_info_state);
     868           0 :     int dp_error = DP_ERR_FATAL;
     869             :     int ret;
     870             :     const char *class;
     871             :     enum sysdb_member_type type;
     872             : 
     873           0 :     ret = ipa_get_ad_override_recv(subreq, &dp_error, state,
     874             :                                    &state->override_attrs);
     875           0 :     talloc_zfree(subreq);
     876           0 :     if (ret != EOK) {
     877           0 :         DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
     878           0 :         goto fail;
     879             :     }
     880             : 
     881           0 :     class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS,
     882             :                                         NULL);
     883           0 :     if (class == NULL) {
     884           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n");
     885           0 :         ret = EINVAL;
     886           0 :         goto fail;
     887             :     }
     888             : 
     889           0 :     if (strcmp(class, SYSDB_USER_CLASS) == 0) {
     890           0 :         type = SYSDB_MEMBER_USER;
     891             :     } else {
     892           0 :         type = SYSDB_MEMBER_GROUP;
     893             :     }
     894             : 
     895           0 :     ret = sysdb_store_override(state->domain, state->ipa_ctx->view_name,
     896             :                                type,
     897           0 :                                state->override_attrs, state->obj_msg->dn);
     898           0 :     if (ret != EOK) {
     899           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n");
     900           0 :         goto fail;
     901             :     }
     902             : 
     903           0 :     if (state->ghosts != NULL) {
     904             :         /* Resolve ghost members */
     905           0 :         subreq = ipa_resolve_user_list_send(state, state->ev,
     906             :                                             state->ipa_ctx,
     907           0 :                                             state->domain->name,
     908             :                                             state->ghosts);
     909           0 :         if (subreq == NULL) {
     910           0 :             DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n");
     911           0 :             ret = ENOMEM;
     912           0 :             goto fail;
     913             :         }
     914           0 :         tevent_req_set_callback(subreq, ipa_id_get_user_list_done, req);
     915           0 :         return;
     916             :     }
     917             : 
     918           0 :     if (state->user_groups != NULL) {
     919           0 :         subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx,
     920             :                                                state->domain, state->group_cnt,
     921             :                                                state->user_groups,
     922             :                                                SYSDB_UUID);
     923           0 :         if (subreq == NULL) {
     924           0 :             DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n");
     925           0 :             ret = ENOMEM;
     926           0 :             goto fail;
     927             :         }
     928           0 :         tevent_req_set_callback(subreq, ipa_id_get_user_groups_done, req);
     929           0 :         return;
     930             :     }
     931             : 
     932           0 :     state->dp_error = DP_ERR_OK;
     933           0 :     tevent_req_done(req);
     934           0 :     return;
     935             : 
     936             : fail:
     937           0 :     state->dp_error = dp_error;
     938           0 :     tevent_req_error(req, ret);
     939           0 :     return;
     940             : }
     941             : 
     942           0 : static void ipa_id_get_user_list_done(struct tevent_req *subreq)
     943             : {
     944           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     945             :                                                 struct tevent_req);
     946           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     947             :                                           struct ipa_id_get_account_info_state);
     948           0 :     int dp_error = DP_ERR_FATAL;
     949             :     int ret;
     950             : 
     951           0 :     ret = ipa_resolve_user_list_recv(subreq, &dp_error);
     952           0 :     talloc_zfree(subreq);
     953           0 :     if (ret != EOK) {
     954           0 :         DEBUG(SSSDBG_OP_FAILURE, "IPA resolve user list %d\n", ret);
     955           0 :         goto fail;
     956             :     }
     957             : 
     958           0 :     state->dp_error = DP_ERR_OK;
     959           0 :     tevent_req_done(req);
     960           0 :     return;
     961             : 
     962             : fail:
     963           0 :     state->dp_error = dp_error;
     964           0 :     tevent_req_error(req, ret);
     965           0 :     return;
     966             : }
     967             : 
     968           0 : static void ipa_id_get_user_groups_done(struct tevent_req *subreq)
     969             : {
     970           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     971             :                                                 struct tevent_req);
     972           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     973             :                                           struct ipa_id_get_account_info_state);
     974           0 :     int dp_error = DP_ERR_FATAL;
     975             :     int ret;
     976             : 
     977           0 :     ret = ipa_initgr_get_overrides_recv(subreq, &dp_error);
     978           0 :     talloc_zfree(subreq);
     979           0 :     if (ret != EOK) {
     980           0 :         DEBUG(SSSDBG_OP_FAILURE, "IPA resolve user groups %d\n", ret);
     981           0 :         goto fail;
     982             :     }
     983             : 
     984           0 :     state->dp_error = DP_ERR_OK;
     985           0 :     tevent_req_done(req);
     986           0 :     return;
     987             : 
     988             : fail:
     989           0 :     state->dp_error = dp_error;
     990           0 :     tevent_req_error(req, ret);
     991           0 :     return;
     992             : }
     993             : 
     994           0 : static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error)
     995             : {
     996           0 :     struct ipa_id_get_account_info_state *state = tevent_req_data(req,
     997             :                                           struct ipa_id_get_account_info_state);
     998             : 
     999           0 :     if (dp_error) {
    1000           0 :         *dp_error = state->dp_error;
    1001             :     }
    1002             : 
    1003           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
    1004             : 
    1005           0 :     return EOK;
    1006             : }
    1007             : 
    1008             : /* Request for netgroups
    1009             :  * - first start here and then go to ipa_netgroups.c
    1010             :  */
    1011             : struct ipa_id_get_netgroup_state {
    1012             :     struct tevent_context *ev;
    1013             :     struct ipa_id_ctx *ctx;
    1014             :     struct sdap_id_op *op;
    1015             :     struct sysdb_ctx *sysdb;
    1016             :     struct sss_domain_info *domain;
    1017             : 
    1018             :     const char *name;
    1019             :     int timeout;
    1020             : 
    1021             :     char *filter;
    1022             :     const char **attrs;
    1023             : 
    1024             :     size_t count;
    1025             :     struct sysdb_attrs **netgroups;
    1026             : 
    1027             :     int dp_error;
    1028             : };
    1029             : 
    1030             : static void ipa_id_get_netgroup_connected(struct tevent_req *subreq);
    1031             : static void ipa_id_get_netgroup_done(struct tevent_req *subreq);
    1032             : 
    1033           0 : static struct tevent_req *ipa_id_get_netgroup_send(TALLOC_CTX *memctx,
    1034             :                                                    struct tevent_context *ev,
    1035             :                                                    struct ipa_id_ctx *ipa_ctx,
    1036             :                                                    const char *name)
    1037             : {
    1038             :     struct tevent_req *req;
    1039             :     struct ipa_id_get_netgroup_state *state;
    1040             :     struct tevent_req *subreq;
    1041             :     struct sdap_id_ctx *ctx;
    1042             :     char *clean_name;
    1043             :     int ret;
    1044             : 
    1045           0 :     ctx = ipa_ctx->sdap_id_ctx;
    1046             : 
    1047           0 :     req = tevent_req_create(memctx, &state, struct ipa_id_get_netgroup_state);
    1048           0 :     if (!req) return NULL;
    1049             : 
    1050           0 :     state->ev = ev;
    1051           0 :     state->ctx = ipa_ctx;
    1052           0 :     state->dp_error = DP_ERR_FATAL;
    1053             : 
    1054           0 :     state->op = sdap_id_op_create(state, ctx->conn->conn_cache);
    1055           0 :     if (!state->op) {
    1056           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
    1057           0 :         ret = ENOMEM;
    1058           0 :         goto fail;
    1059             :     }
    1060             : 
    1061           0 :     state->sysdb = ctx->be->domain->sysdb;
    1062           0 :     state->domain = ctx->be->domain;
    1063           0 :     state->name = name;
    1064           0 :     state->timeout = dp_opt_get_int(ctx->opts->basic, SDAP_SEARCH_TIMEOUT);
    1065             : 
    1066           0 :     ret = sss_filter_sanitize(state, name, &clean_name);
    1067           0 :     if (ret != EOK) {
    1068           0 :         goto fail;
    1069             :     }
    1070             : 
    1071           0 :     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
    1072           0 :                             ctx->opts->netgroup_map[IPA_AT_NETGROUP_NAME].name,
    1073             :                             clean_name,
    1074           0 :                             ctx->opts->netgroup_map[IPA_OC_NETGROUP].name);
    1075           0 :     if (!state->filter) {
    1076           0 :         DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n");
    1077           0 :         ret = ENOMEM;
    1078           0 :         goto fail;
    1079             :     }
    1080           0 :     talloc_zfree(clean_name);
    1081             : 
    1082           0 :     ret = build_attrs_from_map(state, ctx->opts->netgroup_map,
    1083             :                                IPA_OPTS_NETGROUP, NULL,
    1084           0 :                                &state->attrs, NULL);
    1085           0 :     if (ret != EOK) goto fail;
    1086             : 
    1087           0 :     subreq = sdap_id_op_connect_send(state->op, state, &ret);
    1088           0 :     if (!subreq) {
    1089           0 :         goto fail;
    1090             :     }
    1091           0 :     tevent_req_set_callback(subreq, ipa_id_get_netgroup_connected, req);
    1092             : 
    1093           0 :     return req;
    1094             : 
    1095             : fail:
    1096           0 :     tevent_req_error(req, ret);
    1097           0 :     tevent_req_post(req, ev);
    1098           0 :     return req;
    1099             : }
    1100             : 
    1101           0 : static void ipa_id_get_netgroup_connected(struct tevent_req *subreq)
    1102             : {
    1103           0 :     struct tevent_req *req =
    1104           0 :                     tevent_req_callback_data(subreq, struct tevent_req);
    1105           0 :     struct ipa_id_get_netgroup_state *state =
    1106           0 :                     tevent_req_data(req, struct ipa_id_get_netgroup_state);
    1107           0 :     int dp_error = DP_ERR_FATAL;
    1108             :     int ret;
    1109           0 :     struct sdap_id_ctx *sdap_ctx = state->ctx->sdap_id_ctx;
    1110             : 
    1111           0 :     ret = sdap_id_op_connect_recv(subreq, &dp_error);
    1112           0 :     talloc_zfree(subreq);
    1113             : 
    1114           0 :     if (ret != EOK) {
    1115           0 :         state->dp_error = dp_error;
    1116           0 :         tevent_req_error(req, ret);
    1117           0 :         return;
    1118             :     }
    1119             : 
    1120           0 :     subreq = ipa_get_netgroups_send(state, state->ev, state->sysdb,
    1121             :                                     state->domain, sdap_ctx->opts,
    1122           0 :                                     state->ctx->ipa_options,
    1123             :                                     sdap_id_op_handle(state->op),
    1124           0 :                                     state->attrs, state->filter,
    1125             :                                     state->timeout);
    1126           0 :     if (!subreq) {
    1127           0 :         tevent_req_error(req, ENOMEM);
    1128           0 :         return;
    1129             :     }
    1130           0 :     tevent_req_set_callback(subreq, ipa_id_get_netgroup_done, req);
    1131             : 
    1132           0 :     return;
    1133             : }
    1134             : 
    1135           0 : static void ipa_id_get_netgroup_done(struct tevent_req *subreq)
    1136             : {
    1137           0 :     struct tevent_req *req =
    1138           0 :                     tevent_req_callback_data(subreq, struct tevent_req);
    1139           0 :     struct ipa_id_get_netgroup_state *state =
    1140           0 :                     tevent_req_data(req, struct ipa_id_get_netgroup_state);
    1141           0 :     int dp_error = DP_ERR_FATAL;
    1142             :     int ret;
    1143             : 
    1144           0 :     ret = ipa_get_netgroups_recv(subreq, state,
    1145             :                                  &state->count, &state->netgroups);
    1146           0 :     talloc_zfree(subreq);
    1147           0 :     ret = sdap_id_op_done(state->op, ret, &dp_error);
    1148             : 
    1149           0 :     if (dp_error == DP_ERR_OK && ret != EOK) {
    1150             :         /* retry */
    1151           0 :         subreq = sdap_id_op_connect_send(state->op, state, &ret);
    1152           0 :         if (!subreq) {
    1153           0 :             tevent_req_error(req, ret);
    1154           0 :             return;
    1155             :         }
    1156           0 :         tevent_req_set_callback(subreq, ipa_id_get_netgroup_connected, req);
    1157           0 :         return;
    1158             :     }
    1159             : 
    1160           0 :     if (ret && ret != ENOENT) {
    1161           0 :         state->dp_error = dp_error;
    1162           0 :         tevent_req_error(req, ret);
    1163           0 :         return;
    1164             :     }
    1165             : 
    1166           0 :     if (ret == EOK && state->count > 1) {
    1167           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
    1168             :               "Found more than one netgroup with the name [%s].\n",
    1169             :                   state->name);
    1170           0 :         tevent_req_error(req, EINVAL);
    1171           0 :         return;
    1172             :     }
    1173             : 
    1174           0 :     if (ret == ENOENT) {
    1175           0 :         ret = sysdb_delete_netgroup(state->domain, state->name);
    1176           0 :         if (ret != EOK && ret != ENOENT) {
    1177           0 :             tevent_req_error(req, ret);
    1178           0 :             return;
    1179             :         }
    1180             :     }
    1181             : 
    1182           0 :     state->dp_error = DP_ERR_OK;
    1183           0 :     tevent_req_done(req);
    1184           0 :     return;
    1185             : }
    1186             : 
    1187           0 : static int ipa_id_get_netgroup_recv(struct tevent_req *req, int *dp_error)
    1188             : {
    1189           0 :     struct ipa_id_get_netgroup_state *state =
    1190           0 :                     tevent_req_data(req, struct ipa_id_get_netgroup_state);
    1191             : 
    1192           0 :     if (dp_error) {
    1193           0 :         *dp_error = state->dp_error;
    1194             :     }
    1195             : 
    1196           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
    1197             : 
    1198           0 :     return EOK;
    1199             : }
    1200             : 
    1201             : enum ipa_account_info_type {
    1202             :     IPA_ACCOUNT_INFO_SUBDOMAIN,
    1203             :     IPA_ACCOUNT_INFO_NETGROUP,
    1204             :     IPA_ACCOUNT_INFO_OTHER
    1205             : };
    1206             : 
    1207             : static enum ipa_account_info_type
    1208           0 : ipa_decide_account_info_type(struct be_acct_req *data, struct be_ctx *be_ctx)
    1209             : {
    1210           0 :     if (strcasecmp(data->domain, be_ctx->domain->name) != 0) {
    1211           0 :         return IPA_ACCOUNT_INFO_SUBDOMAIN;
    1212           0 :     } else if ((data->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) {
    1213           0 :         return IPA_ACCOUNT_INFO_NETGROUP;
    1214             :     }
    1215             : 
    1216           0 :     return IPA_ACCOUNT_INFO_OTHER;
    1217             : }
    1218             : 
    1219             : struct ipa_account_info_handler_state {
    1220             :     enum ipa_account_info_type type;
    1221             :     struct dp_reply_std reply;
    1222             : };
    1223             : 
    1224             : static void ipa_account_info_handler_done(struct tevent_req *subreq);
    1225             : 
    1226             : struct tevent_req *
    1227           0 : ipa_account_info_handler_send(TALLOC_CTX *mem_ctx,
    1228             :                               struct ipa_id_ctx *id_ctx,
    1229             :                               struct be_acct_req *data,
    1230             :                               struct dp_req_params *params)
    1231             : {
    1232             :     struct ipa_account_info_handler_state *state;
    1233           0 :     struct tevent_req *subreq = NULL;
    1234             :     struct tevent_req *req;
    1235             :     errno_t ret;
    1236             : 
    1237           0 :     req = tevent_req_create(mem_ctx, &state,
    1238             :                             struct ipa_account_info_handler_state);
    1239           0 :     if (req == NULL) {
    1240           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
    1241           0 :         return NULL;
    1242             :     }
    1243             : 
    1244           0 :     state->type = ipa_decide_account_info_type(data, params->be_ctx);
    1245             : 
    1246           0 :     if (sdap_is_enum_request(data)) {
    1247           0 :         DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
    1248           0 :         ret = EOK;
    1249           0 :         goto immediately;
    1250             :     }
    1251             : 
    1252           0 :     switch (state->type) {
    1253             :     case IPA_ACCOUNT_INFO_SUBDOMAIN:
    1254             :         /* Subdomain lookups are handled differently on server and client. */
    1255           0 :         subreq = ipa_subdomain_account_send(state, params->ev, id_ctx, data);
    1256           0 :         break;
    1257             :     case IPA_ACCOUNT_INFO_NETGROUP:
    1258           0 :         if (data->filter_type != BE_FILTER_NAME) {
    1259           0 :             ret = EINVAL;
    1260           0 :             goto immediately;
    1261             :         }
    1262             : 
    1263           0 :         subreq = ipa_id_get_netgroup_send(state, params->ev, id_ctx,
    1264             :                                           data->filter_value);
    1265           0 :         break;
    1266             :     case IPA_ACCOUNT_INFO_OTHER:
    1267           0 :         subreq = ipa_id_get_account_info_send(state, params->ev, id_ctx, data);
    1268           0 :         break;
    1269             :     }
    1270             : 
    1271           0 :     if (subreq == NULL) {
    1272           0 :         ret = ENOMEM;
    1273           0 :         goto immediately;
    1274             :     }
    1275             : 
    1276           0 :     tevent_req_set_callback(subreq, ipa_account_info_handler_done, req);
    1277             : 
    1278           0 :     return req;
    1279             : 
    1280             : immediately:
    1281           0 :     dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
    1282             : 
    1283             :     /* TODO For backward compatibility we always return EOK to DP now. */
    1284           0 :     tevent_req_done(req);
    1285           0 :     tevent_req_post(req, params->ev);
    1286             : 
    1287           0 :     return req;
    1288             : }
    1289             : 
    1290           0 : static void ipa_account_info_handler_done(struct tevent_req *subreq)
    1291             : {
    1292             :     struct ipa_account_info_handler_state *state;
    1293             :     struct tevent_req *req;
    1294             :     int dp_error;
    1295           0 :     errno_t ret = ERR_INTERNAL;
    1296             : 
    1297           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
    1298           0 :     state = tevent_req_data(req, struct ipa_account_info_handler_state);
    1299             : 
    1300           0 :     switch (state->type) {
    1301             :     case IPA_ACCOUNT_INFO_SUBDOMAIN:
    1302           0 :         ret = ipa_subdomain_account_recv(subreq, &dp_error);
    1303           0 :         break;
    1304             :     case IPA_ACCOUNT_INFO_NETGROUP:
    1305           0 :         ret = ipa_id_get_netgroup_recv(subreq, &dp_error);
    1306           0 :         break;
    1307             :     case IPA_ACCOUNT_INFO_OTHER:
    1308           0 :         ret = ipa_id_get_account_info_recv(subreq, &dp_error);
    1309           0 :         break;
    1310             :     }
    1311           0 :     talloc_zfree(subreq);
    1312             : 
    1313             :     /* TODO For backward compatibility we always return EOK to DP now. */
    1314           0 :     dp_reply_std_set(&state->reply, dp_error, ret, NULL);
    1315           0 :     tevent_req_done(req);
    1316           0 : }
    1317             : 
    1318           0 : errno_t ipa_account_info_handler_recv(TALLOC_CTX *mem_ctx,
    1319             :                                       struct tevent_req *req,
    1320             :                                       struct dp_reply_std *data)
    1321             : {
    1322           0 :     struct ipa_account_info_handler_state *state = NULL;
    1323             : 
    1324           0 :     state = tevent_req_data(req, struct ipa_account_info_handler_state);
    1325             : 
    1326           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
    1327             : 
    1328           0 :     *data = state->reply;
    1329             : 
    1330           0 :     return EOK;
    1331             : }

Generated by: LCOV version 1.10