LCOV - code coverage report
Current view: top level - providers - data_provider_opts.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 144 196 73.5 %
Date: 2016-06-29 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Data Provider Helpers
       5             : 
       6             :     Copyright (C) Simo Sorce <ssorce@redhat.com> 2009
       7             : 
       8             :     This program is free software; you can redistribute it and/or modify
       9             :     it under the terms of the GNU General Public License as published by
      10             :     the Free Software Foundation; either version 3 of the License, or
      11             :     (at your option) any later version.
      12             : 
      13             :     This program is distributed in the hope that it will be useful,
      14             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :     GNU General Public License for more details.
      17             : 
      18             :     You should have received a copy of the GNU General Public License
      19             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "data_provider.h"
      23             : 
      24             : /* =Copy-Option-From-Subdomain-If-Allowed================================= */
      25          17 : void dp_option_inherit(char **inherit_opt_list,
      26             :                        int option,
      27             :                        struct dp_option *parent_opts,
      28             :                        struct dp_option *subdom_opts)
      29             : {
      30             :     errno_t ret;
      31             :     bool inherit_option;
      32             : 
      33          17 :     inherit_option = string_in_list(parent_opts[option].opt_name,
      34             :                                     inherit_opt_list, false);
      35          17 :     if (inherit_option == false) {
      36          11 :         DEBUG(SSSDBG_CONF_SETTINGS,
      37             :               "Option %s is not set up to be inherited\n",
      38             :               parent_opts[option].opt_name);
      39          28 :         return;
      40             :     }
      41             : 
      42           6 :     DEBUG(SSSDBG_CONF_SETTINGS,
      43             :           "Will inherit option %s\n", parent_opts[option].opt_name);
      44           6 :     switch (parent_opts[option].type) {
      45             :     case DP_OPT_NUMBER:
      46           2 :         ret = dp_opt_set_int(subdom_opts,
      47             :                              option,
      48             :                              dp_opt_get_int(parent_opts,
      49             :                                             option));
      50           2 :         break;
      51             :     case DP_OPT_STRING:
      52           1 :         ret = dp_opt_set_string(subdom_opts,
      53             :                                 option,
      54             :                                 dp_opt_get_string(parent_opts,
      55             :                                                   option));
      56           1 :         break;
      57             :     case DP_OPT_BLOB:
      58           1 :         ret = dp_opt_set_blob(subdom_opts,
      59             :                               option,
      60             :                               dp_opt_get_blob(parent_opts,
      61             :                                               option));
      62           1 :         break;
      63             :     case DP_OPT_BOOL:
      64           2 :         ret = dp_opt_set_bool(subdom_opts,
      65             :                               option,
      66             :                               dp_opt_get_bool(parent_opts,
      67             :                                               option));
      68           2 :         break;
      69             :     default:
      70           0 :         ret = EINVAL;
      71           0 :         break;
      72             :     }
      73             : 
      74           6 :     if (ret != EOK) {
      75           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
      76             :               "Failed to inherit option %s\n", parent_opts[option].opt_name);
      77             :         /* Not fatal */
      78             :     }
      79             : }
      80             : 
      81             : /* =Retrieve-Options====================================================== */
      82             : 
      83          32 : int dp_get_options(TALLOC_CTX *memctx,
      84             :                    struct confdb_ctx *cdb,
      85             :                    const char *conf_path,
      86             :                    struct dp_option *def_opts,
      87             :                    int num_opts,
      88             :                    struct dp_option **_opts)
      89             : {
      90             :     struct dp_option *opts;
      91             :     int i, ret;
      92             : 
      93          32 :     opts = talloc_zero_array(memctx, struct dp_option, num_opts);
      94          32 :     if (!opts) return ENOMEM;
      95             : 
      96        3266 :     for (i = 0; i < num_opts; i++) {
      97             :         char *tmp;
      98             : 
      99        1601 :         opts[i].opt_name = def_opts[i].opt_name;
     100        1601 :         opts[i].type = def_opts[i].type;
     101        1601 :         opts[i].def_val = def_opts[i].def_val;
     102             : 
     103        1601 :         switch (def_opts[i].type) {
     104             :         case DP_OPT_STRING:
     105        2511 :             ret = confdb_get_string(cdb, opts, conf_path,
     106         837 :                                     opts[i].opt_name,
     107         837 :                                     opts[i].def_val.cstring,
     108         837 :                                     &opts[i].val.string);
     109        1674 :             if (ret != EOK ||
     110        1011 :                 ((opts[i].def_val.string != NULL) &&
     111         174 :                  (opts[i].val.string == NULL))) {
     112           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     113             :                       "Failed to retrieve value for option (%s)\n",
     114             :                        opts[i].opt_name);
     115           0 :                 if (ret == EOK) ret = EINVAL;
     116           0 :                 goto done;
     117             :             }
     118         837 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s has%s value %s\n",
     119             :                   opts[i].opt_name,
     120             :                   opts[i].val.cstring ? "" : " no",
     121             :                   opts[i].val.cstring ? opts[i].val.cstring : "");
     122         837 :             break;
     123             : 
     124             :         case DP_OPT_BLOB:
     125          18 :             ret = confdb_get_string(cdb, opts, conf_path,
     126          18 :                                     opts[i].opt_name,
     127             :                                     NULL, &tmp);
     128          18 :             if (ret != EOK) {
     129           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     130             :                       "Failed to retrieve value for option (%s)\n",
     131             :                       opts[i].opt_name);
     132           0 :                 goto done;
     133             :             }
     134             : 
     135          18 :             if (tmp) {
     136           1 :                 opts[i].val.blob.data = (uint8_t *)tmp;
     137           1 :                 opts[i].val.blob.length = strlen(tmp);
     138          17 :             } else if (opts[i].def_val.blob.data != NULL) {
     139           1 :                 opts[i].val.blob.data = opts[i].def_val.blob.data;
     140           1 :                 opts[i].val.blob.length = opts[i].def_val.blob.length;
     141             :             } else {
     142          16 :                 opts[i].val.blob.data = NULL;
     143          16 :                 opts[i].val.blob.length = 0;
     144             :             }
     145             : 
     146          18 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s has %s binary value.\n",
     147             :                   opts[i].opt_name, opts[i].val.blob.length?"a":"no");
     148          18 :             break;
     149             : 
     150             :         case DP_OPT_NUMBER:
     151        1200 :             ret = confdb_get_int(cdb, conf_path,
     152         400 :                                  opts[i].opt_name,
     153         400 :                                  opts[i].def_val.number,
     154         400 :                                  &opts[i].val.number);
     155         400 :             if (ret != EOK) {
     156           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     157             :                       "Failed to retrieve value for option (%s)\n",
     158             :                       opts[i].opt_name);
     159           0 :                 goto done;
     160             :             }
     161         400 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s has value %d\n",
     162             :                   opts[i].opt_name, opts[i].val.number);
     163         400 :             break;
     164             : 
     165             :         case DP_OPT_BOOL:
     166        1038 :             ret = confdb_get_bool(cdb, conf_path,
     167         346 :                                   opts[i].opt_name,
     168         346 :                                   opts[i].def_val.boolean,
     169         346 :                                   &opts[i].val.boolean);
     170         346 :             if (ret != EOK) {
     171           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     172             :                       "Failed to retrieve value for option (%s)\n",
     173             :                       opts[i].opt_name);
     174           0 :                 goto done;
     175             :             }
     176         346 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s is %s\n",
     177             :                   opts[i].opt_name, opts[i].val.boolean?"TRUE":"FALSE");
     178         346 :             break;
     179             :         }
     180             :     }
     181             : 
     182          32 :     ret = EOK;
     183          32 :     *_opts = opts;
     184             : 
     185             : done:
     186          32 :     if (ret != EOK) talloc_zfree(opts);
     187          32 :     return ret;
     188             : }
     189             : 
     190             : /* =Basic-Option-Helpers================================================== */
     191          21 : static int dp_copy_options_ex(TALLOC_CTX *memctx,
     192             :                               bool copy_values,
     193             :                               struct dp_option *src_opts,
     194             :                               int num_opts,
     195             :                               struct dp_option **_opts)
     196             : {
     197             :     struct dp_option *opts;
     198          21 :     int i, ret = EOK;
     199             : 
     200          21 :     opts = talloc_zero_array(memctx, struct dp_option, num_opts);
     201          21 :     if (!opts) return ENOMEM;
     202             : 
     203        1095 :     for (i = 0; i < num_opts; i++) {
     204        1074 :         opts[i].opt_name = src_opts[i].opt_name;
     205        1074 :         opts[i].type = src_opts[i].type;
     206        1074 :         opts[i].def_val = src_opts[i].def_val;
     207        1074 :         ret = EOK;
     208             : 
     209        1074 :         switch (src_opts[i].type) {
     210             :         case DP_OPT_STRING:
     211         532 :             if (copy_values) {
     212           2 :                 ret = dp_opt_set_string(opts, i, src_opts[i].val.string);
     213             :             } else {
     214         530 :                 ret = dp_opt_set_string(opts, i, src_opts[i].def_val.string);
     215             :             }
     216         532 :             if (ret != EOK) {
     217           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     218             :                       "Failed to copy value for option (%s)\n",
     219             :                        opts[i].opt_name);
     220           0 :                 goto done;
     221             :             }
     222         532 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s has%s value %s\n",
     223             :                   opts[i].opt_name,
     224             :                   opts[i].val.cstring ? "" : " no",
     225             :                   opts[i].val.cstring ? opts[i].val.cstring : "");
     226         532 :             break;
     227             : 
     228             :         case DP_OPT_BLOB:
     229          29 :             if (copy_values) {
     230           2 :                 ret = dp_opt_set_blob(opts, i, src_opts[i].val.blob);
     231             :             } else {
     232          27 :                 ret = dp_opt_set_blob(opts, i, src_opts[i].def_val.blob);
     233             :             }
     234          29 :             if (ret != EOK) {
     235           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     236             :                       "Failed to retrieve value for option (%s)\n",
     237             :                        opts[i].opt_name);
     238           0 :                 goto done;
     239             :             }
     240          29 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s has %s binary value.\n",
     241             :                   opts[i].opt_name, opts[i].val.blob.length?"a":"no");
     242          29 :             break;
     243             : 
     244             :         case DP_OPT_NUMBER:
     245         273 :             if (copy_values) {
     246           2 :                 ret = dp_opt_set_int(opts, i, src_opts[i].val.number);
     247             :             } else {
     248         271 :                 ret = dp_opt_set_int(opts, i, src_opts[i].def_val.number);
     249             :             }
     250         273 :             if (ret != EOK) {
     251           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     252             :                       "Failed to retrieve value for option (%s)\n",
     253             :                       opts[i].opt_name);
     254           0 :                 goto done;
     255             :             }
     256         273 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s has value %d\n",
     257             :                   opts[i].opt_name, opts[i].val.number);
     258         273 :             break;
     259             : 
     260             :         case DP_OPT_BOOL:
     261         240 :             if (copy_values) {
     262           2 :                 ret = dp_opt_set_bool(opts, i, src_opts[i].val.boolean);
     263             :             } else {
     264         238 :                 ret = dp_opt_set_bool(opts, i, src_opts[i].def_val.boolean);
     265             :             }
     266         240 :             if (ret != EOK) {
     267           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     268             :                       "Failed to retrieve value for option (%s)\n",
     269             :                        opts[i].opt_name);
     270           0 :                 goto done;
     271             :             }
     272         240 :             DEBUG(SSSDBG_TRACE_FUNC, "Option %s is %s\n",
     273             :                   opts[i].opt_name, opts[i].val.boolean?"TRUE":"FALSE");
     274         240 :             break;
     275             :         }
     276             :     }
     277             : 
     278          21 :     *_opts = opts;
     279             : 
     280             : done:
     281          21 :     if (ret != EOK) talloc_zfree(opts);
     282          21 :     return ret;
     283             : }
     284             : 
     285           1 : int dp_copy_options(TALLOC_CTX *memctx,
     286             :                     struct dp_option *src_opts,
     287             :                     int num_opts,
     288             :                     struct dp_option **_opts)
     289             : {
     290           1 :     return dp_copy_options_ex(memctx, true, src_opts, num_opts, _opts);
     291             : }
     292             : 
     293          20 : int dp_copy_defaults(TALLOC_CTX *memctx,
     294             :                      struct dp_option *src_opts,
     295             :                      int num_opts,
     296             :                      struct dp_option **_opts)
     297             : {
     298          20 :     return dp_copy_options_ex(memctx, false, src_opts, num_opts, _opts);
     299             : }
     300             : 
     301           0 : static const char *dp_opt_type_to_string(enum dp_opt_type type)
     302             : {
     303           0 :     switch (type) {
     304             :     case DP_OPT_STRING:
     305           0 :         return "String";
     306             :     case DP_OPT_BLOB:
     307           0 :         return "Blob";
     308             :     case DP_OPT_NUMBER:
     309           0 :         return "Number";
     310             :     case DP_OPT_BOOL:
     311           0 :         return "Boolean";
     312             :     }
     313           0 :     return NULL;
     314             : }
     315             : 
     316             : /* Getters */
     317           0 : const char *_dp_opt_get_cstring(struct dp_option *opts,
     318             :                                 int id, const char *location)
     319             : {
     320           0 :     if (opts[id].type != DP_OPT_STRING) {
     321           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     322             :               "[%s] Requested type 'String' for option '%s'"
     323             :                   " but value is of type '%s'!\n",
     324             :                   location, opts[id].opt_name,
     325             :                   dp_opt_type_to_string(opts[id].type));
     326           0 :         return NULL;
     327             :     }
     328           0 :     return opts[id].val.cstring;
     329             : }
     330             : 
     331         264 : char *_dp_opt_get_string(struct dp_option *opts,
     332             :                          int id, const char *location)
     333             : {
     334         264 :     if (opts[id].type != DP_OPT_STRING) {
     335           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     336             :               "[%s] Requested type 'String' for option '%s'"
     337             :                   " but value is of type '%s'!\n",
     338             :                   location, opts[id].opt_name,
     339             :                   dp_opt_type_to_string(opts[id].type));
     340           0 :         return NULL;
     341             :     }
     342         264 :     return opts[id].val.string;
     343             : }
     344             : 
     345          26 : struct dp_opt_blob _dp_opt_get_blob(struct dp_option *opts,
     346             :                                   int id, const char *location)
     347             : {
     348          26 :     struct dp_opt_blob null_blob = { NULL, 0 };
     349          26 :     if (opts[id].type != DP_OPT_BLOB) {
     350           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Blob' for option '%s'"
     351             :                   " but value is of type '%s'!\n",
     352             :                   location, opts[id].opt_name,
     353             :                   dp_opt_type_to_string(opts[id].type));
     354           0 :         return null_blob;
     355             :     }
     356          26 :     return opts[id].val.blob;
     357             : }
     358             : 
     359         171 : int _dp_opt_get_int(struct dp_option *opts,
     360             :                     int id, const char *location)
     361             : {
     362         171 :     if (opts[id].type != DP_OPT_NUMBER) {
     363           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     364             :               "[%s] Requested type 'Number' for option '%s'"
     365             :                   " but value is of type '%s'!\n",
     366             :                   location, opts[id].opt_name,
     367             :                   dp_opt_type_to_string(opts[id].type));
     368           0 :         return 0;
     369             :     }
     370         171 :     return opts[id].val.number;
     371             : }
     372             : 
     373          91 : bool _dp_opt_get_bool(struct dp_option *opts,
     374             :                       int id, const char *location)
     375             : {
     376          91 :     if (opts[id].type != DP_OPT_BOOL) {
     377           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     378             :               "[%s] Requested type 'Boolean' for option '%s'"
     379             :                   " but value is of type '%s'!\n",
     380             :                   location, opts[id].opt_name,
     381             :                   dp_opt_type_to_string(opts[id].type));
     382           0 :         return false;
     383             :     }
     384          91 :     return opts[id].val.boolean;
     385             : }
     386             : 
     387             : /* Setters */
     388         627 : int _dp_opt_set_string(struct dp_option *opts, int id,
     389             :                        const char *s, const char *location)
     390             : {
     391         627 :     if (opts[id].type != DP_OPT_STRING) {
     392           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     393             :               "[%s] Requested type 'String' for option '%s'"
     394             :                   " but type is '%s'!\n",
     395             :                   location, opts[id].opt_name,
     396             :                   dp_opt_type_to_string(opts[id].type));
     397           0 :         return EINVAL;
     398             :     }
     399             : 
     400         627 :     if (opts[id].val.string) {
     401          21 :         talloc_zfree(opts[id].val.string);
     402             :     }
     403         627 :     if (s) {
     404         209 :         opts[id].val.string = talloc_strdup(opts, s);
     405         209 :         if (!opts[id].val.string) {
     406           0 :             DEBUG(SSSDBG_FATAL_FAILURE, "talloc_strdup() failed!\n");
     407           0 :             return ENOMEM;
     408             :         }
     409             :     }
     410             : 
     411         627 :     return EOK;
     412             : }
     413             : 
     414          35 : int _dp_opt_set_blob(struct dp_option *opts, int id,
     415             :                      struct dp_opt_blob b, const char *location)
     416             : {
     417          35 :     if (opts[id].type != DP_OPT_BLOB) {
     418           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Blob' for option '%s'"
     419             :                   " but type is '%s'!\n",
     420             :                   location, opts[id].opt_name,
     421             :                   dp_opt_type_to_string(opts[id].type));
     422           0 :         return EINVAL;
     423             :     }
     424             : 
     425          35 :     if (opts[id].val.blob.data) {
     426           1 :         talloc_zfree(opts[id].val.blob.data);
     427           1 :         opts[id].val.blob.length = 0;
     428             :     }
     429          35 :     if (b.data) {
     430          14 :         opts[id].val.blob.data = talloc_memdup(opts, b.data, b.length);
     431          14 :         if (!opts[id].val.blob.data) {
     432           0 :             DEBUG(SSSDBG_FATAL_FAILURE, "talloc_memdup() failed!\n");
     433           0 :             return ENOMEM;
     434             :         }
     435             :     }
     436          35 :     opts[id].val.blob.length = b.length;
     437             : 
     438          35 :     return EOK;
     439             : }
     440             : 
     441         285 : int _dp_opt_set_int(struct dp_option *opts, int id,
     442             :                     int i, const char *location)
     443             : {
     444         285 :     if (opts[id].type != DP_OPT_NUMBER) {
     445           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     446             :               "[%s] Requested type 'Number' for option '%s'"
     447             :                   " but type is '%s'!\n",
     448             :                   location, opts[id].opt_name,
     449             :                   dp_opt_type_to_string(opts[id].type));
     450           0 :         return EINVAL;
     451             :     }
     452             : 
     453         285 :     opts[id].val.number = i;
     454             : 
     455         285 :     return EOK;
     456             : }
     457             : 
     458         254 : int _dp_opt_set_bool(struct dp_option *opts, int id,
     459             :                      bool b, const char *location)
     460             : {
     461         254 :     if (opts[id].type != DP_OPT_BOOL) {
     462           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     463             :               "[%s] Requested type 'Boolean' for option '%s'"
     464             :                   " but type is '%s'!\n",
     465             :                   location, opts[id].opt_name,
     466             :                   dp_opt_type_to_string(opts[id].type));
     467           0 :         return EINVAL;
     468             :     }
     469             : 
     470         254 :     opts[id].val.boolean = b;
     471             : 
     472         254 :     return EOK;
     473             : }
     474             : 

Generated by: LCOV version 1.10