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

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2015 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "providers/ipa/ipa_opts.h"
      22             : #include "providers/ipa/ipa_common.h"
      23             : #include "providers/ldap/sdap_sudo.h"
      24             : #include "providers/ipa/ipa_sudo.h"
      25             : #include "db/sysdb_sudo.h"
      26             : 
      27             : struct ipa_sudo_handler_state {
      28             :     uint32_t type;
      29             :     struct dp_reply_std reply;
      30             : };
      31             : 
      32             : static void ipa_sudo_handler_done(struct tevent_req *subreq);
      33             : 
      34             : static struct tevent_req *
      35           0 : ipa_sudo_handler_send(TALLOC_CTX *mem_ctx,
      36             :                       struct ipa_sudo_ctx *sudo_ctx,
      37             :                       struct dp_sudo_data *data,
      38             :                       struct dp_req_params *params)
      39             : {
      40             :     struct ipa_sudo_handler_state *state;
      41             :     struct tevent_req *subreq;
      42             :     struct tevent_req *req;
      43             :     errno_t ret;
      44             : 
      45           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_handler_state);
      46           0 :     if (req == NULL) {
      47           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
      48           0 :         return NULL;
      49             :     }
      50             : 
      51           0 :     state->type = data->type;
      52             : 
      53           0 :     switch (data->type) {
      54             :     case BE_REQ_SUDO_FULL:
      55           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n");
      56           0 :         subreq = ipa_sudo_full_refresh_send(state, params->ev, sudo_ctx);
      57           0 :         break;
      58             :     case BE_REQ_SUDO_RULES:
      59           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Issuing a refresh of specific sudo rules\n");
      60           0 :         subreq = ipa_sudo_rules_refresh_send(state, params->ev, sudo_ctx,
      61             :                                              data->rules);
      62           0 :         break;
      63             :     default:
      64           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", data->type);
      65           0 :         ret = EINVAL;
      66           0 :         goto immediately;
      67             :     }
      68             : 
      69           0 :     if (subreq == NULL) {
      70           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request: %d\n", data->type);
      71           0 :         ret = ENOMEM;
      72           0 :         goto immediately;
      73             :     }
      74             : 
      75           0 :     tevent_req_set_callback(subreq, ipa_sudo_handler_done, req);
      76             : 
      77           0 :     return req;
      78             : 
      79             : immediately:
      80           0 :     dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
      81             : 
      82             :     /* TODO For backward compatibility we always return EOK to DP now. */
      83           0 :     tevent_req_done(req);
      84           0 :     tevent_req_post(req, params->ev);
      85             : 
      86           0 :     return req;
      87             : }
      88             : 
      89           0 : static void ipa_sudo_handler_done(struct tevent_req *subreq)
      90             : {
      91             :     struct ipa_sudo_handler_state *state;
      92             :     struct tevent_req *req;
      93             :     int dp_error;
      94             :     bool deleted;
      95             :     errno_t ret;
      96             : 
      97           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
      98           0 :     state = tevent_req_data(req, struct ipa_sudo_handler_state);
      99             : 
     100           0 :     switch (state->type) {
     101             :     case BE_REQ_SUDO_FULL:
     102           0 :         ret = ipa_sudo_full_refresh_recv(subreq, &dp_error);
     103           0 :         talloc_zfree(subreq);
     104           0 :         break;
     105             :     case BE_REQ_SUDO_RULES:
     106           0 :         ret = ipa_sudo_rules_refresh_recv(subreq, &dp_error, &deleted);
     107           0 :         talloc_zfree(subreq);
     108           0 :         if (ret == EOK && deleted == true) {
     109           0 :             ret = ENOENT;
     110             :         }
     111           0 :         break;
     112             :     default:
     113           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", state->type);
     114           0 :         dp_error = DP_ERR_FATAL;
     115           0 :         ret = ERR_INTERNAL;
     116           0 :         break;
     117             :     }
     118             : 
     119             :     /* TODO For backward compatibility we always return EOK to DP now. */
     120           0 :     dp_reply_std_set(&state->reply, dp_error, ret, NULL);
     121           0 :     tevent_req_done(req);
     122           0 : }
     123             : 
     124             : static errno_t
     125           0 : ipa_sudo_handler_recv(TALLOC_CTX *mem_ctx,
     126             :                       struct tevent_req *req,
     127             :                       struct dp_reply_std *data)
     128             : {
     129           0 :     struct ipa_sudo_handler_state *state = NULL;
     130             : 
     131           0 :     state = tevent_req_data(req, struct ipa_sudo_handler_state);
     132             : 
     133           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     134             : 
     135           0 :     *data = state->reply;
     136             : 
     137           0 :     return EOK;
     138             : }
     139             : 
     140             : enum sudo_schema {
     141             :     SUDO_SCHEMA_IPA,
     142             :     SUDO_SCHEMA_LDAP
     143             : };
     144             : 
     145             : static errno_t
     146           0 : ipa_sudo_choose_schema(struct dp_option *ipa_opts,
     147             :                        struct dp_option *sdap_opts,
     148             :                        enum sudo_schema *_schema)
     149             : {
     150             :     TALLOC_CTX *tmp_ctx;
     151             :     char *ipa_search_base;
     152             :     char *search_base;
     153             :     char *basedn;
     154             :     errno_t ret;
     155             : 
     156           0 :     tmp_ctx = talloc_new(NULL);
     157           0 :     if (tmp_ctx == NULL) {
     158           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
     159           0 :         return ENOMEM;
     160             :     }
     161             : 
     162           0 :     ret = domain_to_basedn(tmp_ctx, dp_opt_get_string(ipa_opts,
     163             :                            IPA_KRB5_REALM), &basedn);
     164           0 :     if (ret != EOK) {
     165           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain basedn\n");
     166           0 :         goto done;
     167             :     }
     168             : 
     169           0 :     ipa_search_base = talloc_asprintf(tmp_ctx, "cn=sudo,%s", basedn);
     170           0 :     if (ipa_search_base == NULL) {
     171           0 :         ret = ENOMEM;
     172           0 :         goto done;
     173             :     }
     174             : 
     175           0 :     search_base = dp_opt_get_string(sdap_opts, SDAP_SUDO_SEARCH_BASE);
     176           0 :     if (search_base == NULL) {
     177           0 :         ret = dp_opt_set_string(sdap_opts, SDAP_SUDO_SEARCH_BASE,
     178             :                                 ipa_search_base);
     179           0 :         if (ret != EOK) {
     180           0 :             goto done;
     181             :         }
     182             : 
     183           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n",
     184             :               sdap_opts[SDAP_SUDO_SEARCH_BASE].opt_name, ipa_search_base);
     185             : 
     186           0 :         search_base = ipa_search_base;
     187             :     }
     188             : 
     189             :     /* Use IPA schema only if search base is cn=sudo,$dc. */
     190           0 :     if (strcmp(ipa_search_base, search_base) == 0) {
     191           0 :         *_schema = SUDO_SCHEMA_IPA;
     192             :     } else {
     193           0 :         *_schema = SUDO_SCHEMA_LDAP;
     194             :     }
     195             : 
     196           0 :     ret = EOK;
     197             : 
     198             : done:
     199           0 :     talloc_free(tmp_ctx);
     200           0 :     return ret;
     201             : }
     202             : 
     203             : static int
     204           0 : ipa_sudo_init_ipa_schema(TALLOC_CTX *mem_ctx,
     205             :                          struct be_ctx *be_ctx,
     206             :                          struct ipa_id_ctx *id_ctx,
     207             :                          struct dp_method *dp_methods)
     208             : {
     209             :     struct ipa_sudo_ctx *sudo_ctx;
     210             :     errno_t ret;
     211             : 
     212           0 :     sudo_ctx = talloc_zero(be_ctx, struct ipa_sudo_ctx);
     213           0 :     if (sudo_ctx == NULL) {
     214           0 :         return ENOMEM;
     215             :     }
     216             : 
     217           0 :     sudo_ctx->id_ctx = id_ctx->sdap_id_ctx;
     218           0 :     sudo_ctx->ipa_opts = id_ctx->ipa_options;
     219           0 :     sudo_ctx->sdap_opts = id_ctx->sdap_id_ctx->opts;
     220             : 
     221           0 :     ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path,
     222             :                        ipa_sudorule_map, IPA_OPTS_SUDORULE,
     223             :                        &sudo_ctx->sudorule_map);
     224           0 :     if (ret != EOK) {
     225           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map "
     226             :               "[%d]: %s\n", ret, sss_strerror(ret));
     227           0 :         goto done;
     228             :     }
     229             : 
     230           0 :     ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path,
     231             :                        ipa_sudocmdgroup_map, IPA_OPTS_SUDOCMDGROUP,
     232             :                        &sudo_ctx->sudocmdgroup_map);
     233           0 :     if (ret != EOK) {
     234           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map "
     235             :               "[%d]: %s\n", ret, sss_strerror(ret));
     236           0 :         goto done;
     237             :     }
     238             : 
     239           0 :     ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path,
     240             :                        ipa_sudocmd_map, IPA_OPTS_SUDOCMD,
     241             :                        &sudo_ctx->sudocmd_map);
     242           0 :     if (ret != EOK) {
     243           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map "
     244             :               "[%d]: %s\n", ret, sss_strerror(ret));
     245           0 :         goto done;
     246             :     }
     247             : 
     248           0 :     ret = sdap_parse_search_base(sudo_ctx, sudo_ctx->sdap_opts->basic,
     249             :                                  SDAP_SUDO_SEARCH_BASE,
     250             :                                  &sudo_ctx->sudo_sb);
     251           0 :     if (ret != EOK) {
     252           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not parse sudo search base\n");
     253           0 :         return ret;
     254             :     }
     255             : 
     256           0 :     ret = ipa_sudo_ptask_setup(be_ctx, sudo_ctx);
     257           0 :     if (ret != EOK) {
     258           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup periodic tasks "
     259             :               "[%d]: %s\n", ret, sss_strerror(ret));
     260           0 :         goto done;
     261             :     }
     262             : 
     263           0 :     dp_set_method(dp_methods, DPM_SUDO_HANDLER,
     264             :                   ipa_sudo_handler_send, ipa_sudo_handler_recv, sudo_ctx,
     265             :                   struct ipa_sudo_ctx, struct dp_sudo_data, struct dp_reply_std);
     266             : 
     267           0 :     ret = EOK;
     268             : 
     269             : done:
     270           0 :     if (ret != EOK) {
     271           0 :         talloc_free(sudo_ctx);
     272             :     }
     273             : 
     274           0 :     return ret;
     275             : }
     276             : 
     277           0 : int ipa_sudo_init(TALLOC_CTX *mem_ctx,
     278             :                   struct be_ctx *be_ctx,
     279             :                   struct ipa_id_ctx *id_ctx,
     280             :                   struct dp_method *dp_methods)
     281             : {
     282             :     enum sudo_schema schema;
     283             :     errno_t ret;
     284             : 
     285           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA sudo back end\n");
     286             : 
     287           0 :     ret = ipa_sudo_choose_schema(id_ctx->ipa_options->basic,
     288           0 :                                  id_ctx->ipa_options->id->basic,
     289             :                                  &schema);
     290           0 :     if (ret != EOK) {
     291           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to choose sudo schema [%d]: %s\n",
     292             :                                    ret, sss_strerror(ret));
     293           0 :         return ret;
     294             :     }
     295             : 
     296           0 :     switch (schema) {
     297             :     case SUDO_SCHEMA_IPA:
     298           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Using IPA schema for sudo\n");
     299           0 :         ret = ipa_sudo_init_ipa_schema(mem_ctx, be_ctx, id_ctx, dp_methods);
     300           0 :         break;
     301             :     case SUDO_SCHEMA_LDAP:
     302           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Using LDAP schema for sudo\n");
     303           0 :         ret = sdap_sudo_init(mem_ctx, be_ctx, id_ctx->sdap_id_ctx, dp_methods);
     304           0 :         break;
     305             :     }
     306             : 
     307           0 :     if (ret != EOK) {
     308           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize sudo provider"
     309             :               "[%d]: %s\n", ret, sss_strerror(ret));
     310           0 :         return ret;
     311             :     }
     312             : 
     313           0 :     return EOK;
     314             : }

Generated by: LCOV version 1.10