LCOV - code coverage report
Current view: top level - providers/ldap - sdap_sudo_shared.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 59 0.0 %
Date: 2016-06-29 Functions: 0 3 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 <time.h>
      23             : #include <talloc.h>
      24             : 
      25             : #include "util/util.h"
      26             : #include "providers/be_ptask.h"
      27             : #include "providers/ldap/sdap.h"
      28             : #include "providers/ldap/sdap_sudo_shared.h"
      29             : #include "db/sysdb_sudo.h"
      30             : 
      31             : errno_t
      32           0 : sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
      33             :                               struct dp_option *opts,
      34             :                               be_ptask_send_t full_send_fn,
      35             :                               be_ptask_recv_t full_recv_fn,
      36             :                               be_ptask_send_t smart_send_fn,
      37             :                               be_ptask_recv_t smart_recv_fn,
      38             :                               void *pvt)
      39             : {
      40             :     time_t smart;
      41             :     time_t full;
      42             :     time_t delay;
      43             :     time_t last_refresh;
      44             :     errno_t ret;
      45             : 
      46           0 :     smart = dp_opt_get_int(opts, SDAP_SUDO_SMART_REFRESH_INTERVAL);
      47           0 :     full = dp_opt_get_int(opts, SDAP_SUDO_FULL_REFRESH_INTERVAL);
      48             : 
      49           0 :     if (smart == 0 && full == 0) {
      50             :         /* We don't allow both types to be disabled. At least smart refresh
      51             :          * needs to be enabled. In this case smart refresh will catch up new
      52             :          * and modified rules and deleted rules are caught when expired. */
      53           0 :         smart = opts[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number;
      54             : 
      55           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "At least smart refresh needs to be "
      56             :               "enabled. Setting smart refresh interval to default value "
      57             :               "(%ld) seconds.\n", smart);
      58           0 :     } else if (full > 0 && full <= smart) {
      59             :         /* In this case it does not make any sense to run smart refresh. */
      60           0 :         smart = 0;
      61             : 
      62           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "Smart refresh interval has to be lower "
      63             :               "than full refresh interval. Periodical smart refresh will be "
      64             :               "disabled.\n");
      65             :     }
      66             : 
      67           0 :     ret = sysdb_sudo_get_last_full_refresh(be_ctx->domain, &last_refresh);
      68           0 :     if (ret != EOK) {
      69           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Unable to obtain time of last full "
      70             :               "refresh. Assuming none was performed so far.\n");
      71           0 :         last_refresh = 0;
      72             :     }
      73             : 
      74           0 :     if (last_refresh == 0) {
      75             :         /* If this is the first startup, we need to kick off an refresh
      76             :          * immediately, to close a window where clients requesting sudo
      77             :          * information won't get an immediate reply with no entries */
      78           0 :         delay = 0;
      79             :     } else {
      80             :         /* At least one update has previously run, so clients will get cached
      81             :          * data. We will delay the refresh so we don't slow down the startup
      82             :          * process if this is happening during system boot. */
      83           0 :         delay = 10;
      84             :     }
      85             : 
      86             :     /* Full refresh.
      87             :      *
      88             :      * Disable when offline and run immediately when SSSD goes back online.
      89             :      * Since we have periodical online check we don't have to run this task
      90             :      * when offline. */
      91           0 :     if (full > 0) {
      92           0 :         ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full,
      93             :                               BE_PTASK_OFFLINE_DISABLE, 0,
      94             :                               full_send_fn, full_recv_fn, pvt,
      95             :                               "SUDO Full Refresh", NULL);
      96           0 :         if (ret != EOK) {
      97           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask "
      98             :                   "[%d]: %s\n", ret, sss_strerror(ret));
      99           0 :             return ret;
     100             :         }
     101             :     }
     102             : 
     103             :     /* Smart refresh.
     104             :      *
     105             :      * Disable when offline and reschedule normally when SSSD goes back online.
     106             :      * Since we have periodical online check we don't have to run this task
     107             :      * when offline. */
     108           0 :     if (smart > 0) {
     109           0 :         ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0,
     110             :                               smart, BE_PTASK_OFFLINE_DISABLE, 0,
     111             :                               smart_send_fn, smart_recv_fn, pvt,
     112             :                               "SUDO Smart Refresh", NULL);
     113           0 :         if (ret != EOK) {
     114           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask "
     115             :                   "[%d]: %s\n", ret, sss_strerror(ret));
     116           0 :             return ret;
     117             :         }
     118             :     }
     119             : 
     120           0 :     return EOK;
     121             : }
     122             : 
     123             : static char *
     124           0 : sdap_sudo_new_usn(TALLOC_CTX *mem_ctx,
     125             :                   unsigned long usn,
     126             :                   const char *leftover)
     127             : {
     128           0 :     const char *str = leftover == NULL ? "" : leftover;
     129             :     char *newusn;
     130             : 
     131             :     /* We increment USN number so that we can later use simplify filter
     132             :      * (just usn >= last+1 instaed of usn >= last && usn != last).
     133             :      */
     134           0 :     usn++;
     135             : 
     136             :     /* Convert back to string appending non-converted values since it
     137             :      * is an indicator that modifyTimestamp is used instead of entryUSN.
     138             :      * modifyTimestamp contains also timezone specification, usually Z.
     139             :      * We can't really handle any errors here so we just use what we got. */
     140           0 :     newusn = talloc_asprintf(mem_ctx, "%lu%s", usn, str);
     141           0 :     if (newusn == NULL) {
     142           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change USN value (OOM)!\n");
     143           0 :         return NULL;
     144             :     }
     145             : 
     146           0 :     return newusn;
     147             : }
     148             : 
     149             : void
     150           0 : sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
     151             :                   const char *usn)
     152             : {
     153             :     unsigned long usn_number;
     154             :     char *newusn;
     155           0 :     char *endptr = NULL;
     156             :     errno_t ret;
     157             : 
     158           0 :     if (srv_opts == NULL) {
     159           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n");
     160           0 :         return;
     161             :     }
     162             : 
     163           0 :     if (usn == NULL) {
     164           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Bug: usn is NULL\n");
     165           0 :         return;
     166             :     }
     167             : 
     168           0 :     errno = 0;
     169           0 :     usn_number = strtoul(usn, &endptr, 10);
     170           0 :     if (errno != 0) {
     171           0 :         ret = errno;
     172           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert USN %s [%d]: %s\n",
     173             :               usn, ret, sss_strerror(ret));
     174           0 :         return;
     175             :     }
     176             : 
     177           0 :     newusn = sdap_sudo_new_usn(srv_opts, usn_number, endptr);
     178           0 :     if (newusn == NULL) {
     179           0 :         return;
     180             :     }
     181             : 
     182           0 :     if (sysdb_compare_usn(newusn, srv_opts->max_sudo_value) > 0) {
     183           0 :         talloc_zfree(srv_opts->max_sudo_value);
     184           0 :         srv_opts->max_sudo_value = newusn;
     185             :     } else {
     186           0 :         talloc_zfree(newusn);
     187             :     }
     188             : 
     189           0 :     if (usn_number > srv_opts->last_usn) {
     190           0 :         srv_opts->last_usn = usn_number;
     191             :     }
     192             : 
     193           0 :     DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n",
     194             :                              srv_opts->max_sudo_value);
     195             : }

Generated by: LCOV version 1.10