LCOV - code coverage report
Current view: top level - providers/ipa - ipa_views.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 207 0.0 %
Date: 2015-10-19 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     IPA Identity Backend Module for views and overrides
       5             : 
       6             :     Authors:
       7             :         Sumit Bose <sbose@redhat.com>
       8             : 
       9             :     Copyright (C) 2014 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 "util/util.h"
      26             : #include "util/strtonum.h"
      27             : #include "providers/ldap/sdap_async.h"
      28             : #include "providers/ipa/ipa_id.h"
      29             : 
      30           0 : static errno_t be_acct_req_to_override_filter(TALLOC_CTX *mem_ctx,
      31             :                                               struct ipa_options *ipa_opts,
      32             :                                               struct be_acct_req *ar,
      33             :                                               char **override_filter)
      34             : {
      35             :     char *filter;
      36             :     uint32_t id;
      37             :     char *endptr;
      38             : 
      39           0 :     switch (ar->filter_type) {
      40             :     case BE_FILTER_NAME:
      41           0 :         switch ((ar->entry_type & BE_REQ_TYPE_MASK)) {
      42             :         case BE_REQ_USER:
      43             :         case BE_REQ_INITGROUPS:
      44           0 :             filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
      45           0 :                          ipa_opts->override_map[IPA_OC_OVERRIDE_USER].name,
      46           0 :                          ipa_opts->override_map[IPA_AT_OVERRIDE_USER_NAME].name,
      47             :                          ar->filter_value);
      48           0 :             break;
      49             : 
      50             :          case BE_REQ_GROUP:
      51           0 :             filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
      52           0 :                         ipa_opts->override_map[IPA_OC_OVERRIDE_GROUP].name,
      53           0 :                         ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_NAME].name,
      54             :                         ar->filter_value);
      55           0 :             break;
      56             : 
      57             :          case BE_REQ_USER_AND_GROUP:
      58           0 :             filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
      59           0 :                         ipa_opts->override_map[IPA_OC_OVERRIDE].name,
      60           0 :                         ipa_opts->override_map[IPA_AT_OVERRIDE_USER_NAME].name,
      61             :                         ar->filter_value,
      62           0 :                         ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_NAME].name,
      63             :                         ar->filter_value);
      64           0 :             break;
      65             :         default:
      66           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d] for name filter.\n",
      67             :                                        ar->entry_type);
      68           0 :             return EINVAL;
      69             :         }
      70           0 :         break;
      71             : 
      72             :     case BE_FILTER_IDNUM:
      73           0 :         errno = 0;
      74           0 :         id = strtouint32(ar->filter_value, &endptr, 10);
      75           0 :         if (errno != 0|| *endptr != '\0' || (ar->filter_value == endptr)) {
      76           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Invalid id value [%s].\n",
      77             :                                        ar->filter_value);
      78           0 :             return EINVAL;
      79             :         }
      80           0 :         switch ((ar->entry_type & BE_REQ_TYPE_MASK)) {
      81             :         case BE_REQ_USER:
      82             :         case BE_REQ_INITGROUPS:
      83           0 :             filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%"PRIu32"))",
      84           0 :                         ipa_opts->override_map[IPA_OC_OVERRIDE_USER].name,
      85           0 :                         ipa_opts->override_map[IPA_AT_OVERRIDE_UID_NUMBER].name,
      86             :                         id);
      87           0 :             break;
      88             : 
      89             :          case BE_REQ_GROUP:
      90           0 :             filter = talloc_asprintf(mem_ctx,
      91             :                   "(&(objectClass=%s)(%s=%"PRIu32"))",
      92           0 :                   ipa_opts->override_map[IPA_OC_OVERRIDE_GROUP].name,
      93           0 :                   ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_GID_NUMBER].name,
      94             :                   id);
      95           0 :             break;
      96             : 
      97             :          case BE_REQ_USER_AND_GROUP:
      98           0 :             filter = talloc_asprintf(mem_ctx,
      99             :                   "(&(objectClass=%s)(|(%s=%"PRIu32")(%s=%"PRIu32")))",
     100           0 :                   ipa_opts->override_map[IPA_OC_OVERRIDE].name,
     101           0 :                   ipa_opts->override_map[IPA_AT_OVERRIDE_UID_NUMBER].name,
     102             :                   id,
     103           0 :                   ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_GID_NUMBER].name,
     104             :                   id);
     105           0 :             break;
     106             :         default:
     107           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     108             :                   "Unexpected entry type [%d] for id filter.\n",
     109             :                   ar->entry_type);
     110           0 :             return EINVAL;
     111             :         }
     112           0 :         break;
     113             : 
     114             :     case BE_FILTER_SECID:
     115           0 :         if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_SECID) {
     116           0 :             filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=:SID:%s))",
     117           0 :                        ipa_opts->override_map[IPA_OC_OVERRIDE].name,
     118           0 :                        ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name,
     119             :                        ar->filter_value);
     120             :         } else {
     121           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     122             :                   "Unexpected entry type [%d] for SID filter.\n",
     123             :                   ar->entry_type);
     124           0 :             return EINVAL;
     125             :         }
     126           0 :         break;
     127             : 
     128             :     case BE_FILTER_UUID:
     129           0 :         if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_UUID) {
     130           0 :             filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=:IPA:%s:%s))",
     131           0 :                        ipa_opts->override_map[IPA_OC_OVERRIDE].name,
     132           0 :                        ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name,
     133             :                        dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN),
     134             :                        ar->filter_value);
     135             :         } else {
     136           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     137             :                   "Unexpected entry type [%d] for UUID filter.\n",
     138             :                   ar->entry_type);
     139           0 :             return EINVAL;
     140             :         }
     141           0 :         break;
     142             : 
     143             :     default:
     144           0 :         DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain filter type.\n");
     145           0 :         return EINVAL;
     146             :     }
     147             : 
     148           0 :     if (filter == NULL) {
     149           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
     150           0 :         return ENOMEM;
     151             :     }
     152             : 
     153           0 :     *override_filter = filter;
     154             : 
     155           0 :     return EOK;
     156             : }
     157             : 
     158           0 : static errno_t get_be_acct_req_for_xyz(TALLOC_CTX *mem_ctx, const char *val,
     159             :                                        const char *domain_name,
     160             :                                        int type,
     161             :                                        struct be_acct_req **_ar)
     162             : {
     163             :     struct be_acct_req *ar;
     164             : 
     165           0 :     ar = talloc_zero(mem_ctx, struct be_acct_req);
     166           0 :     if (ar == NULL) {
     167           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
     168           0 :         return ENOMEM;
     169             :     }
     170             : 
     171           0 :     switch (type) {
     172             :     case BE_REQ_BY_SECID:
     173           0 :         ar->entry_type = BE_REQ_BY_SECID;
     174           0 :         ar->filter_type = BE_FILTER_SECID;
     175           0 :         break;
     176             :     case BE_REQ_BY_UUID:
     177           0 :         ar->entry_type = BE_REQ_BY_UUID;
     178           0 :         ar->filter_type = BE_FILTER_UUID;
     179           0 :         break;
     180             :     case BE_REQ_USER:
     181           0 :         ar->entry_type = BE_REQ_USER;
     182           0 :         ar->filter_type = BE_FILTER_NAME;
     183           0 :         break;
     184             :     default:
     185           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported request type [%d].\n", type);
     186           0 :         talloc_free(ar);
     187           0 :         return EINVAL;
     188             :     }
     189             : 
     190           0 :     ar->filter_value = talloc_strdup(ar, val);
     191           0 :     ar->domain = talloc_strdup(ar, domain_name);
     192           0 :     if (ar->filter_value == NULL || ar->domain == NULL) {
     193           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
     194           0 :         talloc_free(ar);
     195           0 :         return ENOMEM;
     196             :     }
     197             : 
     198             : 
     199           0 :     *_ar = ar;
     200             : 
     201           0 :     return EOK;
     202             : }
     203             : 
     204           0 : errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid,
     205             :                                 const char *domain_name,
     206             :                                 struct be_acct_req **_ar)
     207             : {
     208           0 :     return get_be_acct_req_for_xyz(mem_ctx, sid, domain_name, BE_REQ_BY_SECID,
     209             :                                    _ar);
     210             : }
     211             : 
     212           0 : errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, const char *uuid,
     213             :                                  const char *domain_name,
     214             :                                  struct be_acct_req **_ar)
     215             : {
     216           0 :     return get_be_acct_req_for_xyz(mem_ctx, uuid, domain_name, BE_REQ_BY_UUID,
     217             :                                    _ar);
     218             : }
     219             : 
     220           0 : errno_t get_be_acct_req_for_user_name(TALLOC_CTX *mem_ctx,
     221             :                                       const char *user_name,
     222             :                                       const char *domain_name,
     223             :                                       struct be_acct_req **_ar)
     224             : {
     225           0 :     return get_be_acct_req_for_xyz(mem_ctx, user_name, domain_name, BE_REQ_USER,
     226             :                                    _ar);
     227             : }
     228             : 
     229             : struct ipa_get_ad_override_state {
     230             :     struct tevent_context *ev;
     231             :     struct sdap_id_ctx *sdap_id_ctx;
     232             :     struct ipa_options *ipa_options;
     233             :     const char *ipa_realm;
     234             :     const char *ipa_view_name;
     235             :     struct be_acct_req *ar;
     236             : 
     237             :     struct sdap_id_op *sdap_op;
     238             :     int dp_error;
     239             :     struct sysdb_attrs *override_attrs;
     240             :     char *filter;
     241             : };
     242             : 
     243             : static void ipa_get_ad_override_connect_done(struct tevent_req *subreq);
     244             : static void ipa_get_ad_override_done(struct tevent_req *subreq);
     245             : 
     246           0 : struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx,
     247             :                                             struct tevent_context *ev,
     248             :                                             struct sdap_id_ctx *sdap_id_ctx,
     249             :                                             struct ipa_options *ipa_options,
     250             :                                             const char *ipa_realm,
     251             :                                             const char *view_name,
     252             :                                             struct be_acct_req *ar)
     253             : {
     254             :     int ret;
     255             :     struct tevent_req *req;
     256             :     struct tevent_req *subreq;
     257             :     struct ipa_get_ad_override_state *state;
     258             : 
     259           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_override_state);
     260           0 :     if (req == NULL) {
     261           0 :         DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
     262           0 :         return NULL;
     263             :     }
     264             : 
     265           0 :     state->ev = ev;
     266           0 :     state->sdap_id_ctx = sdap_id_ctx;
     267           0 :     state->ipa_options = ipa_options;
     268           0 :     state->ipa_realm = ipa_realm;
     269           0 :     state->ar = ar;
     270           0 :     state->dp_error = -1;
     271           0 :     state->override_attrs = NULL;
     272           0 :     state->filter = NULL;
     273             : 
     274           0 :     if (view_name == NULL) {
     275           0 :         DEBUG(SSSDBG_TRACE_ALL, "View not defined, nothing to do.\n");
     276           0 :         ret = EOK;
     277           0 :         goto done;
     278             :     }
     279             : 
     280           0 :     if (is_default_view(view_name)) {
     281           0 :         state->ipa_view_name = IPA_DEFAULT_VIEW_NAME;
     282             :     } else {
     283           0 :         state->ipa_view_name = view_name;
     284             :     }
     285             : 
     286           0 :     state->sdap_op = sdap_id_op_create(state,
     287           0 :                                        state->sdap_id_ctx->conn->conn_cache);
     288           0 :     if (state->sdap_op == NULL) {
     289           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
     290           0 :         ret = ENOMEM;
     291           0 :         goto done;
     292             :     }
     293             : 
     294           0 :     subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
     295           0 :     if (subreq == NULL) {
     296           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n",
     297             :                                   ret, strerror(ret));
     298           0 :         goto done;
     299             :     }
     300             : 
     301           0 :     tevent_req_set_callback(subreq, ipa_get_ad_override_connect_done, req);
     302             : 
     303           0 :     return req;
     304             : 
     305             : done:
     306           0 :     if (ret != EOK) {
     307           0 :         state->dp_error = DP_ERR_FATAL;
     308           0 :         tevent_req_error(req, ret);
     309             :     } else {
     310           0 :         state->dp_error = DP_ERR_OK;
     311           0 :         tevent_req_done(req);
     312             :     }
     313           0 :     tevent_req_post(req, state->ev);
     314             : 
     315           0 :     return req;
     316             : }
     317             : 
     318           0 : static void ipa_get_ad_override_connect_done(struct tevent_req *subreq)
     319             : {
     320           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     321             :                                                       struct tevent_req);
     322           0 :     struct ipa_get_ad_override_state *state = tevent_req_data(req,
     323             :                                               struct ipa_get_ad_override_state);
     324             :     int ret;
     325             :     char *basedn;
     326             :     char *search_base;
     327           0 :     struct ipa_options *ipa_opts = state->ipa_options;
     328             : 
     329           0 :     ret = sdap_id_op_connect_recv(subreq, &state->dp_error);
     330           0 :     talloc_zfree(subreq);
     331           0 :     if (ret != EOK) {
     332           0 :         if (state->dp_error == DP_ERR_OFFLINE) {
     333           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     334             :                   "No IPA server is available, going offline\n");
     335             :         } else {
     336           0 :             DEBUG(SSSDBG_OP_FAILURE,
     337             :                   "Failed to connect to IPA server: [%d](%s)\n",
     338             :                    ret, strerror(ret));
     339             :         }
     340             : 
     341           0 :         goto fail;
     342             :     }
     343             : 
     344           0 :     ret = domain_to_basedn(state, state->ipa_realm, &basedn);
     345           0 :     if (ret != EOK) {
     346           0 :         DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
     347           0 :         goto fail;
     348             :     }
     349             : 
     350           0 :     search_base = talloc_asprintf(state, "cn=%s,%s", state->ipa_view_name,
     351           0 :                                        ipa_opts->views_search_bases[0]->basedn);
     352           0 :     if (search_base == NULL) {
     353           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
     354           0 :         ret = ENOMEM;
     355           0 :         goto fail;
     356             :     }
     357             : 
     358           0 :     ret = be_acct_req_to_override_filter(state, state->ipa_options, state->ar,
     359             :                                          &state->filter);
     360           0 :     if (ret != EOK) {
     361           0 :         DEBUG(SSSDBG_OP_FAILURE, "be_acct_req_to_override_filter failed.\n");
     362           0 :         goto fail;
     363             :     }
     364             : 
     365           0 :     DEBUG(SSSDBG_TRACE_ALL,
     366             :           "Searching for overrides in view [%s] with filter [%s].\n",
     367             :           state->ipa_view_name, state->filter);
     368             : 
     369           0 :     subreq = sdap_get_generic_send(state, state->ev, state->sdap_id_ctx->opts,
     370             :                                  sdap_id_op_handle(state->sdap_op), search_base,
     371             :                                  LDAP_SCOPE_SUBTREE,
     372           0 :                                  state->filter, NULL,
     373           0 :                                  state->ipa_options->override_map,
     374             :                                  IPA_OPTS_OVERRIDE,
     375           0 :                                  dp_opt_get_int(state->sdap_id_ctx->opts->basic,
     376             :                                                 SDAP_ENUM_SEARCH_TIMEOUT),
     377             :                                  false);
     378           0 :     if (subreq == NULL) {
     379           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
     380           0 :         ret = ENOMEM;
     381           0 :         goto fail;
     382             :     }
     383             : 
     384           0 :     tevent_req_set_callback(subreq, ipa_get_ad_override_done, req);
     385           0 :     return;
     386             : 
     387             : fail:
     388           0 :     state->dp_error = DP_ERR_FATAL;
     389           0 :     tevent_req_error(req, ret);
     390           0 :     return;
     391             : }
     392             : 
     393           0 : static void ipa_get_ad_override_done(struct tevent_req *subreq)
     394             : {
     395           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     396             :                                                       struct tevent_req);
     397           0 :     struct ipa_get_ad_override_state *state = tevent_req_data(req,
     398             :                                               struct ipa_get_ad_override_state);
     399             :     int ret;
     400           0 :     size_t reply_count = 0;
     401           0 :     struct sysdb_attrs **reply = NULL;
     402             : 
     403           0 :     ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
     404           0 :     talloc_zfree(subreq);
     405           0 :     if (ret != EOK) {
     406           0 :         DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override request failed.\n");
     407           0 :         goto fail;
     408             :     }
     409             : 
     410           0 :     if (reply_count == 0) {
     411           0 :         DEBUG(SSSDBG_TRACE_ALL, "No override found with filter [%s].\n",
     412             :                                 state->filter);
     413           0 :         state->dp_error = DP_ERR_OK;
     414           0 :         tevent_req_done(req);
     415           0 :         return;
     416           0 :     } else if (reply_count > 1) {
     417           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     418             :               "Found [%zu] overrides with filter [%s], expected only 1.\n",
     419             :               reply_count, state->filter);
     420           0 :         ret = EINVAL;
     421           0 :         goto fail;
     422             :     }
     423             : 
     424           0 :     DEBUG(SSSDBG_TRACE_ALL, "Found override for object with filter [%s].\n",
     425             :                             state->filter);
     426             : 
     427           0 :     state->override_attrs = reply[0];
     428           0 :     state->dp_error = DP_ERR_OK;
     429           0 :     tevent_req_done(req);
     430           0 :     return;
     431             : 
     432             : fail:
     433           0 :     state->dp_error = DP_ERR_FATAL;
     434           0 :     tevent_req_error(req, ret);
     435           0 :     return;
     436             : }
     437             : 
     438           0 : errno_t ipa_get_ad_override_recv(struct tevent_req *req, int *dp_error_out,
     439             :                                  TALLOC_CTX *mem_ctx,
     440             :                                  struct sysdb_attrs **override_attrs)
     441             : {
     442           0 :     struct ipa_get_ad_override_state *state = tevent_req_data(req,
     443             :                                               struct ipa_get_ad_override_state);
     444             : 
     445           0 :     if (dp_error_out != NULL) {
     446           0 :         *dp_error_out = state->dp_error;
     447             :     }
     448             : 
     449           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     450             : 
     451           0 :     if (override_attrs != NULL) {
     452           0 :         *override_attrs = talloc_steal(mem_ctx, state->override_attrs);
     453             :     }
     454             : 
     455           0 :     return EOK;
     456             : }

Generated by: LCOV version 1.10