LCOV - code coverage report
Current view: top level - providers/ldap - sdap_sudo_refresh.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 203 0.0 %
Date: 2016-06-29 Functions: 0 14 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 <errno.h>
      22             : #include <talloc.h>
      23             : #include <tevent.h>
      24             : 
      25             : #include "util/util.h"
      26             : #include "providers/be_ptask.h"
      27             : #include "providers/ldap/sdap_sudo.h"
      28             : #include "providers/ldap/sdap_sudo_shared.h"
      29             : #include "db/sysdb_sudo.h"
      30             : 
      31             : struct sdap_sudo_full_refresh_state {
      32             :     struct sdap_sudo_ctx *sudo_ctx;
      33             :     struct sdap_id_ctx *id_ctx;
      34             :     struct sysdb_ctx *sysdb;
      35             :     struct sss_domain_info *domain;
      36             :     int dp_error;
      37             : };
      38             : 
      39             : static void sdap_sudo_full_refresh_done(struct tevent_req *subreq);
      40             : 
      41           0 : struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
      42             :                                                struct sdap_sudo_ctx *sudo_ctx)
      43             : {
      44           0 :     struct tevent_req *req = NULL;
      45           0 :     struct tevent_req *subreq = NULL;
      46           0 :     struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
      47           0 :     struct sdap_sudo_full_refresh_state *state = NULL;
      48           0 :     char *search_filter = NULL;
      49           0 :     char *delete_filter = NULL;
      50             :     int ret;
      51             : 
      52           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_full_refresh_state);
      53           0 :     if (req == NULL) {
      54           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
      55           0 :         return NULL;
      56             :     }
      57             : 
      58           0 :     state->sudo_ctx = sudo_ctx;
      59           0 :     state->id_ctx = id_ctx;
      60           0 :     state->sysdb = id_ctx->be->domain->sysdb;
      61           0 :     state->domain = id_ctx->be->domain;
      62             : 
      63             :     /* Download all rules from LDAP */
      64           0 :     search_filter = talloc_asprintf(state, SDAP_SUDO_FILTER_CLASS,
      65           0 :                             id_ctx->opts->sudorule_map[SDAP_OC_SUDORULE].name);
      66           0 :     if (search_filter == NULL) {
      67           0 :         ret = ENOMEM;
      68           0 :         goto immediately;
      69             :     }
      70             : 
      71             :     /* Remove all rules from cache */
      72           0 :     delete_filter = talloc_asprintf(state, "(%s=%s)",
      73             :                                     SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC);
      74           0 :     if (delete_filter == NULL) {
      75           0 :         ret = ENOMEM;
      76           0 :         goto immediately;
      77             :     }
      78             : 
      79           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n");
      80             : 
      81           0 :     subreq = sdap_sudo_refresh_send(state, sudo_ctx, search_filter,
      82             :                                     delete_filter);
      83           0 :     if (subreq == NULL) {
      84           0 :         ret = ENOMEM;
      85           0 :         goto immediately;
      86             :     }
      87             : 
      88           0 :     tevent_req_set_callback(subreq, sdap_sudo_full_refresh_done, req);
      89             : 
      90           0 :     return req;
      91             : 
      92             : immediately:
      93           0 :     if (ret == EOK) {
      94           0 :         tevent_req_done(req);
      95             :     } else {
      96           0 :         tevent_req_error(req, ret);
      97             :     }
      98           0 :     tevent_req_post(req, id_ctx->be->ev);
      99             : 
     100           0 :     return req;
     101             : }
     102             : 
     103           0 : static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
     104             : {
     105           0 :     struct tevent_req *req = NULL;
     106           0 :     struct sdap_sudo_full_refresh_state *state = NULL;
     107             :     int ret;
     108             : 
     109           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     110           0 :     state = tevent_req_data(req, struct sdap_sudo_full_refresh_state);
     111             : 
     112           0 :     ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, NULL);
     113           0 :     talloc_zfree(subreq);
     114           0 :     if (ret != EOK || state->dp_error != DP_ERR_OK) {
     115             :         goto done;
     116             :     }
     117             : 
     118             :     /* save the time in the sysdb */
     119           0 :     ret = sysdb_sudo_set_last_full_refresh(state->domain, time(NULL));
     120           0 :     if (ret != EOK) {
     121           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Unable to save time of "
     122             :                                     "a successful full refresh\n");
     123             :         /* this is only a minor error that does not affect the functionality,
     124             :          * therefore there is no need to report it with tevent_req_error()
     125             :          * which would cause problems in the consumers */
     126             :     }
     127             : 
     128           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Successful full refresh of sudo rules\n");
     129             : 
     130             : done:
     131           0 :     if (ret != EOK) {
     132           0 :         tevent_req_error(req, ret);
     133           0 :         return;
     134             :     }
     135             : 
     136           0 :     tevent_req_done(req);
     137             : }
     138             : 
     139           0 : int sdap_sudo_full_refresh_recv(struct tevent_req *req,
     140             :                                 int *dp_error)
     141             : {
     142           0 :     struct sdap_sudo_full_refresh_state *state = NULL;
     143           0 :     state = tevent_req_data(req, struct sdap_sudo_full_refresh_state);
     144             : 
     145           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     146             : 
     147           0 :     *dp_error = state->dp_error;
     148             : 
     149           0 :     return EOK;
     150             : }
     151             : 
     152             : struct sdap_sudo_smart_refresh_state {
     153             :     struct sdap_id_ctx *id_ctx;
     154             :     struct sysdb_ctx *sysdb;
     155             :     int dp_error;
     156             : };
     157             : 
     158             : static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq);
     159             : 
     160           0 : struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
     161             :                                                 struct sdap_sudo_ctx *sudo_ctx)
     162             : {
     163           0 :     struct tevent_req *req = NULL;
     164           0 :     struct tevent_req *subreq = NULL;
     165           0 :     struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
     166           0 :     struct sdap_attr_map *map = id_ctx->opts->sudorule_map;
     167           0 :     struct sdap_server_opts *srv_opts = id_ctx->srv_opts;
     168           0 :     struct sdap_sudo_smart_refresh_state *state = NULL;
     169           0 :     char *search_filter = NULL;
     170             :     const char *usn;
     171             :     int ret;
     172             : 
     173           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_smart_refresh_state);
     174           0 :     if (req == NULL) {
     175           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
     176           0 :         return NULL;
     177             :     }
     178             : 
     179           0 :     state->id_ctx = id_ctx;
     180           0 :     state->sysdb = id_ctx->be->domain->sysdb;
     181             : 
     182             :     /* Download all rules from LDAP that are newer than usn */
     183           0 :     if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
     184           0 :         DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
     185           0 :         usn = "0";
     186           0 :         search_filter = talloc_asprintf(state, "(objectclass=%s)",
     187             :                                         map[SDAP_OC_SUDORULE].name);
     188             :     } else {
     189           0 :         usn = srv_opts->max_sudo_value;
     190           0 :         search_filter = talloc_asprintf(state, "(&(objectclass=%s)(%s>=%s))",
     191             :                                         map[SDAP_OC_SUDORULE].name,
     192           0 :                                         map[SDAP_AT_SUDO_USN].name, usn);
     193             :     }
     194           0 :     if (search_filter == NULL) {
     195           0 :         ret = ENOMEM;
     196           0 :         goto immediately;
     197             :     }
     198             : 
     199             :     /* Do not remove any rules that are already in the sysdb
     200             :      * sysdb_filter = NULL; */
     201             : 
     202           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules "
     203             :                              "(USN >= %s)\n", usn);
     204             : 
     205           0 :     subreq = sdap_sudo_refresh_send(state, sudo_ctx, search_filter, NULL);
     206           0 :     if (subreq == NULL) {
     207           0 :         ret = ENOMEM;
     208           0 :         goto immediately;
     209             :     }
     210             : 
     211           0 :     tevent_req_set_callback(subreq, sdap_sudo_smart_refresh_done, req);
     212             : 
     213           0 :     return req;
     214             : 
     215             : immediately:
     216           0 :     if (ret == EOK) {
     217           0 :         tevent_req_done(req);
     218             :     } else {
     219           0 :         tevent_req_error(req, ret);
     220             :     }
     221           0 :     tevent_req_post(req, id_ctx->be->ev);
     222             : 
     223           0 :     return req;
     224             : }
     225             : 
     226           0 : static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq)
     227             : {
     228           0 :     struct tevent_req *req = NULL;
     229           0 :     struct sdap_sudo_smart_refresh_state *state = NULL;
     230             :     int ret;
     231             : 
     232           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     233           0 :     state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state);
     234             : 
     235           0 :     ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, NULL);
     236           0 :     talloc_zfree(subreq);
     237           0 :     if (ret != EOK || state->dp_error != DP_ERR_OK) {
     238             :         goto done;
     239             :     }
     240             : 
     241           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Successful smart refresh of sudo rules\n");
     242             : 
     243             : done:
     244           0 :     if (ret != EOK) {
     245           0 :         tevent_req_error(req, ret);
     246           0 :         return;
     247             :     }
     248             : 
     249           0 :     tevent_req_done(req);
     250             : }
     251             : 
     252           0 : int sdap_sudo_smart_refresh_recv(struct tevent_req *req,
     253             :                                  int *dp_error)
     254             : {
     255           0 :     struct sdap_sudo_smart_refresh_state *state = NULL;
     256           0 :     state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state);
     257             : 
     258           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     259             : 
     260           0 :     *dp_error = state->dp_error;
     261             : 
     262           0 :     return EOK;
     263             : }
     264             : 
     265             : struct sdap_sudo_rules_refresh_state {
     266             :     struct sdap_id_ctx *id_ctx;
     267             :     size_t num_rules;
     268             :     int dp_error;
     269             :     bool deleted;
     270             : };
     271             : 
     272             : static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq);
     273             : 
     274           0 : struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
     275             :                                                 struct sdap_sudo_ctx *sudo_ctx,
     276             :                                                 char **rules)
     277             : {
     278           0 :     struct tevent_req *req = NULL;
     279           0 :     struct tevent_req *subreq = NULL;
     280           0 :     struct sdap_sudo_rules_refresh_state *state = NULL;
     281           0 :     struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
     282           0 :     struct sdap_options *opts = id_ctx->opts;
     283           0 :     TALLOC_CTX *tmp_ctx = NULL;
     284           0 :     char *search_filter = NULL;
     285           0 :     char *delete_filter = NULL;
     286           0 :     char *safe_rule = NULL;
     287             :     int ret;
     288             :     int i;
     289             : 
     290           0 :     if (rules == NULL) {
     291           0 :         return NULL;
     292             :     }
     293             : 
     294           0 :     tmp_ctx = talloc_new(NULL);
     295           0 :     if (tmp_ctx == NULL) {
     296           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
     297           0 :         return NULL;
     298             :     }
     299             : 
     300           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_rules_refresh_state);
     301           0 :     if (req == NULL) {
     302           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
     303           0 :         return NULL;
     304             :     }
     305             : 
     306           0 :     search_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
     307           0 :     delete_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
     308             : 
     309             :     /* Download only selected rules from LDAP */
     310             :     /* Remove all selected rules from cache */
     311           0 :     for (i = 0; rules[i] != NULL; i++) {
     312           0 :         ret = sss_filter_sanitize(tmp_ctx, rules[i], &safe_rule);
     313           0 :         if (ret != EOK) {
     314           0 :             ret = ENOMEM;
     315           0 :             goto immediately;
     316             :         }
     317             : 
     318           0 :         search_filter = talloc_asprintf_append_buffer(search_filter, "(%s=%s)",
     319           0 :                                      opts->sudorule_map[SDAP_AT_SUDO_NAME].name,
     320             :                                      safe_rule);
     321           0 :         if (search_filter == NULL) {
     322           0 :             ret = ENOMEM;
     323           0 :             goto immediately;
     324             :         }
     325             : 
     326           0 :         delete_filter = talloc_asprintf_append_buffer(delete_filter, "(%s=%s)",
     327             :                                                       SYSDB_SUDO_CACHE_AT_CN,
     328             :                                                       safe_rule);
     329           0 :         if (delete_filter == NULL) {
     330           0 :             ret = ENOMEM;
     331           0 :             goto immediately;
     332             :         }
     333             :     }
     334             : 
     335           0 :     state->id_ctx = sudo_ctx->id_ctx;
     336           0 :     state->num_rules = i;
     337             : 
     338           0 :     search_filter = talloc_asprintf(tmp_ctx, "(&"SDAP_SUDO_FILTER_CLASS"(|%s))",
     339           0 :                                     opts->sudorule_map[SDAP_OC_SUDORULE].name,
     340             :                                     search_filter);
     341           0 :     if (search_filter == NULL) {
     342           0 :         ret = ENOMEM;
     343           0 :         goto immediately;
     344             :     }
     345             : 
     346           0 :     delete_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|%s))",
     347             :                                     SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC,
     348             :                                     delete_filter);
     349           0 :     if (delete_filter == NULL) {
     350           0 :         ret = ENOMEM;
     351           0 :         goto immediately;
     352             :     }
     353             : 
     354           0 :     subreq = sdap_sudo_refresh_send(req, sudo_ctx, search_filter,
     355             :                                     delete_filter);
     356           0 :     if (subreq == NULL) {
     357           0 :         ret = ENOMEM;
     358           0 :         goto immediately;
     359             :     }
     360             : 
     361           0 :     tevent_req_set_callback(subreq, sdap_sudo_rules_refresh_done, req);
     362             : 
     363           0 :     ret = EOK;
     364             : immediately:
     365           0 :     talloc_free(tmp_ctx);
     366             : 
     367           0 :     if (ret != EOK) {
     368           0 :         tevent_req_error(req, ret);
     369           0 :         tevent_req_post(req, id_ctx->be->ev);
     370             :     }
     371             : 
     372           0 :     return req;
     373             : }
     374             : 
     375           0 : static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq)
     376             : {
     377           0 :     struct tevent_req *req = NULL;
     378           0 :     struct sdap_sudo_rules_refresh_state *state = NULL;
     379             :     size_t downloaded_rules_num;
     380             :     int ret;
     381             : 
     382           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     383           0 :     state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state);
     384             : 
     385           0 :     ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error,
     386             :                                  &downloaded_rules_num);
     387           0 :     talloc_zfree(subreq);
     388           0 :     if (ret != EOK || state->dp_error != DP_ERR_OK) {
     389             :         goto done;
     390             :     }
     391             : 
     392           0 :     state->deleted = downloaded_rules_num != state->num_rules ? true : false;
     393             : 
     394             : done:
     395           0 :     if (ret != EOK) {
     396           0 :         tevent_req_error(req, ret);
     397           0 :         return;
     398             :     }
     399             : 
     400           0 :     tevent_req_done(req);
     401             : }
     402             : 
     403           0 : int sdap_sudo_rules_refresh_recv(struct tevent_req *req,
     404             :                                  int *dp_error,
     405             :                                  bool *deleted)
     406             : {
     407           0 :     struct sdap_sudo_rules_refresh_state *state = NULL;
     408           0 :     state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state);
     409             : 
     410           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     411             : 
     412           0 :     *dp_error = state->dp_error;
     413           0 :     *deleted = state->deleted;
     414             : 
     415           0 :     return EOK;
     416             : }
     417             : 
     418             : static struct tevent_req *
     419           0 : sdap_sudo_ptask_full_refresh_send(TALLOC_CTX *mem_ctx,
     420             :                                   struct tevent_context *ev,
     421             :                                   struct be_ctx *be_ctx,
     422             :                                   struct be_ptask *be_ptask,
     423             :                                   void *pvt)
     424             : {
     425             :     struct sdap_sudo_ctx *sudo_ctx;
     426           0 :     sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx);
     427             : 
     428           0 :     return sdap_sudo_full_refresh_send(mem_ctx, sudo_ctx);
     429             : }
     430             : 
     431             : static errno_t
     432           0 : sdap_sudo_ptask_full_refresh_recv(struct tevent_req *req)
     433             : {
     434             :     int dp_error;
     435             : 
     436           0 :     return sdap_sudo_full_refresh_recv(req, &dp_error);
     437             : }
     438             : 
     439             : static struct tevent_req *
     440           0 : sdap_sudo_ptask_smart_refresh_send(TALLOC_CTX *mem_ctx,
     441             :                                    struct tevent_context *ev,
     442             :                                    struct be_ctx *be_ctx,
     443             :                                    struct be_ptask *be_ptask,
     444             :                                    void *pvt)
     445             : {
     446             :     struct sdap_sudo_ctx *sudo_ctx;
     447           0 :     sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx);
     448             : 
     449           0 :     return sdap_sudo_smart_refresh_send(mem_ctx, sudo_ctx);
     450             : }
     451             : 
     452             : static errno_t
     453           0 : sdap_sudo_ptask_smart_refresh_recv(struct tevent_req *req)
     454             : {
     455             :     int dp_error;
     456             : 
     457           0 :     return sdap_sudo_smart_refresh_recv(req, &dp_error);
     458             : }
     459             : 
     460             : errno_t
     461           0 : sdap_sudo_ptask_setup(struct be_ctx *be_ctx, struct sdap_sudo_ctx *sudo_ctx)
     462             : {
     463           0 :     return sdap_sudo_ptask_setup_generic(be_ctx, sudo_ctx->id_ctx->opts->basic,
     464             :                                          sdap_sudo_ptask_full_refresh_send,
     465             :                                          sdap_sudo_ptask_full_refresh_recv,
     466             :                                          sdap_sudo_ptask_smart_refresh_send,
     467             :                                          sdap_sudo_ptask_smart_refresh_recv,
     468             :                                          sudo_ctx);
     469             : }

Generated by: LCOV version 1.10