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

Generated by: LCOV version 1.10