LCOV - code coverage report
Current view: top level - util - sss_config.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 159 209 76.1 %
Date: 2016-06-29 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2014 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 <augeas.h>
      22             : #include <talloc.h>
      23             : #include <string.h>
      24             : #include "util/sss_config.h"
      25             : 
      26             : #define PATH_SECTION "/files/%s/target[. = \"%s\"]"
      27             : #define PATH_OPTION PATH_SECTION "/%s"
      28             : 
      29             : #define build_section_path(mem_ctx, config_ctx, section) \
      30             :     talloc_asprintf(mem_ctx, PATH_SECTION, config_ctx->file, section)
      31             : 
      32             : #define build_option_path(mem_ctx, config_ctx, section, option) \
      33             :     talloc_asprintf(mem_ctx, PATH_OPTION, config_ctx->file, section, option)
      34             : 
      35             : struct sss_config_ctx
      36             : {
      37             :     augeas *auges_ctx;
      38             :     const char *file;
      39             : };
      40             : 
      41             : static errno_t
      42          10 : sss_config_set_option(struct sss_config_ctx *ctx,
      43             :                       const char *section,
      44             :                       const char *option,
      45             :                       const char *value)
      46             : {
      47          10 :     TALLOC_CTX *tmp_ctx = NULL;
      48          10 :     char *target_path = NULL;
      49          10 :     char *option_path = NULL;
      50             :     errno_t ret;
      51             :     int aug_ret;
      52             : 
      53          10 :     tmp_ctx = talloc_new(NULL);
      54          10 :     if (tmp_ctx == NULL) {
      55           0 :         return ENOMEM;
      56             :     }
      57             : 
      58          10 :     target_path = build_section_path(tmp_ctx, ctx, section);
      59          10 :     if (target_path == NULL) {
      60           0 :         ret = ENOMEM;
      61           0 :         goto done;
      62             :     }
      63             : 
      64          10 :     option_path = build_option_path(tmp_ctx, ctx, section, option);
      65          10 :     if (option_path == NULL) {
      66           0 :         ret = ENOMEM;
      67           0 :         goto done;
      68             :     }
      69             : 
      70             :     /* Set configuration option:
      71             :      *
      72             :      * # make sure the section exists
      73             :      * set /files/$file/target[. = "$section"] $section
      74             :      *
      75             :      * # set value
      76             :      * set /files/$file/target[. = "$section"]/$option $value
      77             :      */
      78             : 
      79          10 :     aug_ret = aug_set(ctx->auges_ctx, target_path, section);
      80          10 :     if (aug_ret != 0) {
      81           0 :         ret = EIO;
      82           0 :         goto done;
      83             :     }
      84             : 
      85          10 :     aug_ret = aug_set(ctx->auges_ctx, option_path, value);
      86          10 :     if (aug_ret != 0) {
      87           0 :         ret = EIO;
      88           0 :         goto done;
      89             :     }
      90             : 
      91          10 :     ret = EOK;
      92             : 
      93             : done:
      94          10 :     talloc_free(tmp_ctx);
      95          10 :     return ret;
      96             : }
      97             : 
      98             : static errno_t
      99           2 : sss_config_rm_option(struct sss_config_ctx *ctx,
     100             :                       const char *section,
     101             :                       const char *option)
     102             : {
     103           2 :     TALLOC_CTX *tmp_ctx = NULL;
     104           2 :     char *option_path = NULL;
     105             :     errno_t ret;
     106             :     int aug_ret;
     107             : 
     108           2 :     tmp_ctx = talloc_new(NULL);
     109           2 :     if (tmp_ctx == NULL) {
     110           0 :         return ENOMEM;
     111             :     }
     112             : 
     113           2 :     option_path = build_option_path(tmp_ctx, ctx, section, option);
     114           2 :     if (option_path == NULL) {
     115           0 :         ret = ENOMEM;
     116           0 :         goto done;
     117             :     }
     118             : 
     119             :     /* Remove configuration option:
     120             :      *
     121             :      * rm /files/$file/target[. = "$section"]/$option
     122             :      */
     123             : 
     124           2 :     aug_ret = aug_rm(ctx->auges_ctx, option_path);
     125           2 :     if (aug_ret != 1) {
     126           0 :         ret = EIO;
     127           0 :         goto done;
     128             :     }
     129             : 
     130           2 :     ret = EOK;
     131             : 
     132             : done:
     133           2 :     talloc_free(tmp_ctx);
     134           2 :     return ret;
     135             : }
     136             : 
     137             : static errno_t
     138          10 : sss_config_set_list(struct sss_config_ctx *ctx,
     139             :                     const char *section,
     140             :                     const char *option,
     141             :                     char **list)
     142             : {
     143          10 :     TALLOC_CTX *tmp_ctx = NULL;
     144          10 :     char *value = NULL;
     145             :     errno_t ret;
     146             :     int i;
     147             : 
     148          10 :     if (list == NULL) {
     149           0 :         return EINVAL;
     150             :     }
     151             : 
     152          10 :     tmp_ctx = talloc_new(NULL);
     153          10 :     if (tmp_ctx == NULL) {
     154           0 :         return ENOMEM;
     155             :     }
     156             : 
     157          10 :     if (list[0] == NULL) {
     158           2 :         ret = sss_config_rm_option(ctx, section, option);
     159           2 :         goto done;
     160             :     }
     161             : 
     162           8 :     value = talloc_strdup(tmp_ctx, list[0]);
     163           8 :     if (value == NULL) {
     164           0 :         ret = ENOMEM;
     165           0 :         goto done;
     166             :     }
     167             : 
     168          11 :     for (i = 1; list[i] != NULL; i++) {
     169           3 :         value = talloc_asprintf_append(value, ", %s", list[i]);
     170           3 :         if (value == NULL) {
     171           0 :             ret = ENOMEM;
     172           0 :             goto done;
     173             :         }
     174             :     }
     175             : 
     176           8 :     ret = sss_config_set_option(ctx, section, option, value);
     177             : 
     178             : done:
     179          10 :     talloc_free(tmp_ctx);
     180          10 :     return ret;
     181             : }
     182             : 
     183             : static errno_t
     184          22 : sss_config_get_list(TALLOC_CTX *mem_ctx,
     185             :                     struct sss_config_ctx *ctx,
     186             :                     const char *section,
     187             :                     const char *option,
     188             :                     char ***_list)
     189             : {
     190          22 :     TALLOC_CTX *tmp_ctx = NULL;
     191          22 :     char *option_path = NULL;
     192          22 :     const char *value = NULL;
     193          22 :     char **list = NULL;
     194             :     errno_t ret;
     195             :     int aug_ret;
     196             : 
     197          22 :     tmp_ctx = talloc_new(NULL);
     198          22 :     if (tmp_ctx == NULL) {
     199           0 :         return ENOMEM;
     200             :     }
     201             : 
     202          22 :     option_path = build_option_path(tmp_ctx, ctx, section, option);
     203          22 :     if (option_path == NULL) {
     204           0 :         ret = ENOMEM;
     205           0 :         goto done;
     206             :     }
     207             : 
     208          22 :     aug_ret = aug_get(ctx->auges_ctx, option_path, &value);
     209          22 :     if (aug_ret == 0 || (aug_ret == 1 && (value == NULL || *value == '\0'))) {
     210             :         /* option is not present, return empty list */
     211          12 :         list = talloc_zero_array(tmp_ctx, char*, 1);
     212          12 :         if (list == NULL) {
     213           0 :             ret = ENOMEM;
     214           0 :             goto done;
     215             :         }
     216             : 
     217          12 :         ret = EOK;
     218          12 :         goto done;
     219          10 :     } else if (aug_ret != 1) {
     220             :         /* error: more than one value found */
     221           0 :         ret = EINVAL;
     222           0 :         goto done;
     223             :     }
     224             : 
     225          10 :     ret = split_on_separator(tmp_ctx, value, ',', true, true, &list, NULL);
     226          10 :     if (ret != EOK) {
     227           0 :         goto done;
     228             :     }
     229             : 
     230          10 :     *_list = talloc_steal(mem_ctx, list);
     231          10 :     ret = EOK;
     232             : 
     233             : done:
     234          22 :     talloc_free(tmp_ctx);
     235          22 :     return ret;
     236             : }
     237             : 
     238             : static errno_t
     239           8 : sss_config_is_in_list(struct sss_config_ctx *ctx,
     240             :                       const char *section,
     241             :                       const char *option,
     242             :                       const char *value,
     243             :                       bool *_result)
     244             : {
     245           8 :     char **list = NULL;
     246             :     errno_t ret;
     247             : 
     248           8 :     ret = sss_config_get_list(ctx, ctx, section, option, &list);
     249           8 :     if (ret != EOK) {
     250           0 :         goto done;
     251             :     }
     252             : 
     253           8 :     *_result = string_in_list(value, list, true);
     254             : 
     255             : done:
     256           8 :     talloc_free(list);
     257           8 :     return ret;
     258             : }
     259             : 
     260             : static errno_t
     261           6 : sss_config_add_to_list(struct sss_config_ctx *ctx,
     262             :                        const char *section,
     263             :                        const char *option,
     264             :                        const char *value)
     265             : {
     266           6 :     TALLOC_CTX *tmp_ctx = NULL;
     267           6 :     char **list = NULL;
     268             :     errno_t ret;
     269           6 :     bool result = false;
     270             : 
     271           6 :     tmp_ctx = talloc_new(NULL);
     272           6 :     if (tmp_ctx == NULL) {
     273           0 :         return ENOMEM;
     274             :     }
     275             : 
     276           6 :     ret = sss_config_get_list(tmp_ctx, ctx, section, option, &list);
     277           6 :     if (ret != EOK) {
     278           0 :         goto done;
     279             :     }
     280             : 
     281           6 :     result = string_in_list(value, list, true);
     282           6 :     if (result == true) {
     283           0 :         ret = EOK;
     284           0 :         goto done;
     285             :     }
     286             : 
     287           6 :     ret = add_string_to_list(tmp_ctx, value, &list);
     288           6 :     if (ret != EOK) {
     289           0 :         goto done;
     290             :     }
     291             : 
     292           6 :     ret = sss_config_set_list(ctx, section, option, list);
     293             : 
     294             : done:
     295           6 :     talloc_free(tmp_ctx);
     296           6 :     return ret;
     297             : }
     298             : 
     299             : static errno_t
     300           8 : sss_config_del_from_list(struct sss_config_ctx *ctx,
     301             :                          const char *section,
     302             :                          const char *option,
     303             :                          const char *value)
     304             : {
     305           8 :     TALLOC_CTX *tmp_ctx = NULL;
     306           8 :     char **list = NULL;
     307             :     errno_t ret;
     308             :     bool found;
     309             :     int i;
     310             : 
     311           8 :     tmp_ctx = talloc_new(NULL);
     312           8 :     if (tmp_ctx == NULL) {
     313           0 :         return ENOMEM;
     314             :     }
     315             : 
     316           8 :     ret = sss_config_get_list(tmp_ctx, ctx, section, option, &list);
     317           8 :     if (ret != EOK) {
     318           0 :         goto done;
     319             :     }
     320             : 
     321           8 :     if (list == NULL) {
     322           4 :         goto done;
     323             :     }
     324             : 
     325           4 :     found = false;
     326          10 :     for (i = 0; list[i] != NULL; i++) {
     327           6 :         if (strcmp(list[i], value) == 0) {
     328           4 :             found = true;
     329             :         }
     330             : 
     331           6 :         if (found) {
     332           6 :             list[i] = list[i + 1];
     333             :         }
     334             :     }
     335             : 
     336           4 :     ret = sss_config_set_list(ctx, section, option, list);
     337             : 
     338             : done:
     339           8 :     talloc_free(tmp_ctx);
     340           8 :     return ret;
     341             : }
     342             : 
     343          24 : static int sss_config_ctx_destructor(struct sss_config_ctx *ctx)
     344             : {
     345          24 :     if (ctx->auges_ctx != NULL) {
     346          24 :         aug_close(ctx->auges_ctx);
     347          24 :         ctx->auges_ctx = NULL;
     348             :     }
     349             : 
     350          24 :     return 0;
     351             : }
     352             : 
     353             : struct sss_config_ctx *
     354          24 : sss_config_open(TALLOC_CTX *mem_ctx,
     355             :                 const char *root,
     356             :                 const char *file)
     357             : {
     358          24 :     struct sss_config_ctx *ctx = NULL;
     359             :     errno_t ret;
     360             :     int aug_ret;
     361             : 
     362          24 :     ctx = talloc_zero(mem_ctx, struct sss_config_ctx);
     363          24 :     if (ctx == NULL) {
     364           0 :         return NULL;
     365             :     }
     366             : 
     367          24 :     talloc_set_destructor(ctx, sss_config_ctx_destructor);
     368             : 
     369          24 :     ctx->auges_ctx = aug_init(root, NULL, AUG_NO_LOAD | AUG_NO_MODL_AUTOLOAD
     370             :                               | AUG_SAVE_BACKUP);
     371          24 :     if (ctx->auges_ctx == NULL) {
     372           0 :         ret = ENOMEM;
     373           0 :         goto done;
     374             :     }
     375             : 
     376          24 :     ctx->file = talloc_strdup(ctx, file);
     377          24 :     if (ctx->file == NULL) {
     378           0 :         ret = ENOMEM;
     379           0 :         goto done;
     380             :     }
     381             : 
     382             :     /* Load configuration file
     383             :      *
     384             :      * set /augeas/load/sssd/lens sssd.lns
     385             :      * set /augeas/load/sssd/incl $file
     386             :      * load
     387             :      */
     388             : 
     389          24 :     aug_ret = aug_set(ctx->auges_ctx, "/augeas/load/sssd/lens", "sssd.lns");
     390          24 :     if (aug_ret != 0) {
     391           0 :         ret = EIO;
     392           0 :         goto done;
     393             :     }
     394             : 
     395          24 :     aug_ret = aug_set(ctx->auges_ctx, "/augeas/load/sssd/incl", ctx->file);
     396          24 :     if (aug_ret != 0) {
     397           0 :         ret = EIO;
     398           0 :         goto done;
     399             :     }
     400             : 
     401          24 :     aug_ret = aug_load(ctx->auges_ctx);
     402          24 :     if (aug_ret != 0) {
     403           0 :         ret = EIO;
     404           0 :         goto done;
     405             :     }
     406             : 
     407          24 :     ret = EOK;
     408             : 
     409             : done:
     410          24 :     if (ret != EOK) {
     411           0 :         talloc_free(ctx);
     412             :     }
     413             : 
     414          24 :     return ctx;
     415             : }
     416             : 
     417             : errno_t
     418          16 : sss_config_save(struct sss_config_ctx *ctx)
     419             : {
     420             :     int aug_ret;
     421             : 
     422          16 :     aug_ret = aug_save(ctx->auges_ctx);
     423          16 :     if (aug_ret != 0) {
     424           0 :         return EIO;
     425             :     }
     426             : 
     427          16 :     return EOK;
     428             : }
     429             : 
     430             : void
     431          24 : sss_config_close(struct sss_config_ctx **_ctx)
     432             : {
     433          24 :     if (_ctx == NULL || *_ctx == NULL) {
     434          24 :         return;
     435             :     }
     436             : 
     437          24 :     talloc_free(*_ctx);
     438          24 :     *_ctx = NULL;
     439             : }
     440             : 
     441             : errno_t
     442           2 : sss_config_set_debug_level(struct sss_config_ctx *ctx,
     443             :                            const char *section,
     444             :                            uint32_t level)
     445             : {
     446           2 :     char *level_str = NULL;
     447             :     errno_t ret;
     448             : 
     449           2 :     level_str = talloc_asprintf(ctx, "%#.4x", level);
     450           2 :     if (level_str == NULL) {
     451           0 :         return ENOMEM;
     452             :     }
     453             : 
     454           2 :     ret = sss_config_set_option(ctx, section, CONFDB_SERVICE_DEBUG_LEVEL,
     455             :                                 level_str);
     456             : 
     457           2 :     talloc_free(level_str);
     458           2 :     return ret;
     459             : }
     460             : 
     461             : errno_t
     462           4 : sss_config_service_is_enabled(struct sss_config_ctx *ctx,
     463             :                               const char *service,
     464             :                               bool *_result)
     465             : {
     466           4 :     return sss_config_is_in_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES,
     467             :                                  service, _result);
     468             : }
     469             : 
     470             : errno_t
     471           3 : sss_config_service_enable(struct sss_config_ctx *ctx,
     472             :                           const char *service)
     473             : {
     474           3 :     return sss_config_add_to_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES,
     475             :                                   service);
     476             : }
     477             : 
     478             : errno_t
     479           4 : sss_config_service_disable(struct sss_config_ctx *ctx,
     480             :                            const char *service)
     481             : {
     482           4 :     return sss_config_del_from_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES,
     483             :                                     service);
     484             : }
     485             : 
     486             : errno_t
     487           4 : sss_config_domain_is_enabled(struct sss_config_ctx *ctx,
     488             :                              const char *domain,
     489             :                              bool *_result)
     490             : {
     491           4 :     return sss_config_is_in_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS,
     492             :                                  domain, _result);
     493             : }
     494             : 
     495             : errno_t
     496           3 : sss_config_domain_enable(struct sss_config_ctx *ctx,
     497             :                          const char *domain)
     498             : {
     499           3 :     return sss_config_add_to_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS,
     500             :                                   domain);
     501             : }
     502             : 
     503             : errno_t
     504           4 : sss_config_domain_disable(struct sss_config_ctx *ctx,
     505             :                           const char *domain)
     506             : {
     507           4 :     return sss_config_del_from_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS,
     508             :                                     domain);
     509             : }

Generated by: LCOV version 1.10