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

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     proxy_init.c
       5             : 
       6             :     Authors:
       7             :         Stephen Gallagher <sgallagh@redhat.com>
       8             : 
       9             :     Copyright (C) 2010 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "config.h"
      26             : 
      27             : #include "util/sss_format.h"
      28             : #include "providers/proxy/proxy.h"
      29             : 
      30             : #define NSS_FN_NAME "_nss_%s_%s"
      31             : 
      32             : #define ERROR_INITGR "The '%s' library does not provides the " \
      33             :                          "_nss_XXX_initgroups_dyn function!\n" \
      34             :                          "initgroups will be slow as it will require " \
      35             :                          "full groups enumeration!\n"
      36             : #define ERROR_NETGR "The '%s' library does not support netgroups.\n"
      37             : #define ERROR_SERV "The '%s' library does not support services.\n"
      38             : 
      39           0 : static void *proxy_dlsym(void *handle,
      40             :                          const char *name,
      41             :                          const char *libname)
      42             : {
      43             :     char *funcname;
      44             :     void *funcptr;
      45             : 
      46           0 :     funcname = talloc_asprintf(NULL, NSS_FN_NAME, libname, name);
      47           0 :     if (funcname == NULL) {
      48           0 :         return NULL;
      49             :     }
      50             : 
      51           0 :     funcptr = dlsym(handle, funcname);
      52           0 :     talloc_free(funcname);
      53             : 
      54           0 :     return funcptr;
      55             : }
      56             : 
      57           0 : static errno_t proxy_id_conf(TALLOC_CTX *mem_ctx,
      58             :                              struct be_ctx *be_ctx,
      59             :                              char **_libname,
      60             :                              char **_libpath,
      61             :                              bool *_fast_alias)
      62             : {
      63             :     TALLOC_CTX *tmp_ctx;
      64             :     char *libname;
      65             :     char *libpath;
      66             :     bool fast_alias;
      67             :     errno_t ret;
      68             : 
      69           0 :     tmp_ctx = talloc_new(NULL);
      70           0 :     if (tmp_ctx == NULL) {
      71           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
      72           0 :         return ENOMEM;
      73             :     }
      74             : 
      75           0 :     ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path,
      76             :                             CONFDB_PROXY_LIBNAME, NULL, &libname);
      77           0 :     if (ret != EOK) {
      78           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n",
      79             :               ret, sss_strerror(ret));
      80           0 :         goto done;
      81           0 :     } else if (libname == NULL) {
      82           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No library name given\n");
      83           0 :         ret = ENOENT;
      84           0 :         goto done;
      85             :     }
      86             : 
      87           0 :     ret = confdb_get_bool(be_ctx->cdb, be_ctx->conf_path,
      88             :                           CONFDB_PROXY_FAST_ALIAS, false, &fast_alias);
      89           0 :     if (ret != EOK) {
      90           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n",
      91             :               ret, sss_strerror(ret));
      92           0 :         goto done;
      93             :     }
      94             : 
      95           0 :     libpath = talloc_asprintf(tmp_ctx, "libnss_%s.so.2", libname);
      96           0 :     if (libpath == NULL) {
      97           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
      98           0 :         ret = ENOMEM;
      99           0 :         goto done;
     100             :     }
     101             : 
     102           0 :     *_libname = talloc_steal(mem_ctx, libname);
     103           0 :     *_libpath = talloc_steal(mem_ctx, libpath);
     104           0 :     *_fast_alias = fast_alias;
     105             : 
     106           0 :     ret = EOK;
     107             : 
     108             : done:
     109           0 :     talloc_free(tmp_ctx);
     110             : 
     111           0 :     return ret;
     112             : }
     113             : 
     114           0 : static errno_t proxy_id_load_symbols(struct proxy_nss_ops *ops,
     115             :                                      const char *libname,
     116             :                                      void *handle)
     117             : {
     118             :     int i;
     119             :     struct {void **dest;
     120             :             const char *name;
     121             :             const char *custom_error;
     122             :             bool is_fatal;
     123           0 :     } symbols[] = {
     124           0 :         {(void**)&ops->getpwnam_r, "getpwnam_r", NULL, true},
     125           0 :         {(void**)&ops->getpwuid_r, "getpwuid_r", NULL, true},
     126           0 :         {(void**)&ops->setpwent, "setpwent", NULL, true},
     127           0 :         {(void**)&ops->getpwent_r, "getpwent_r", NULL, true},
     128           0 :         {(void**)&ops->endpwent, "endpwent", NULL, true},
     129           0 :         {(void**)&ops->getgrnam_r, "getgrnam_r", NULL, true},
     130           0 :         {(void**)&ops->getgrgid_r, "getgrgid_r", NULL, true},
     131           0 :         {(void**)&ops->setgrent, "setgrent", NULL, true},
     132           0 :         {(void**)&ops->getgrent_r, "getgrent_r", NULL, true},
     133           0 :         {(void**)&ops->endgrent, "endgrent", NULL, true},
     134           0 :         {(void**)&ops->initgroups_dyn, "initgroups_dyn", ERROR_INITGR, false},
     135           0 :         {(void**)&ops->setnetgrent, "setnetgrent", ERROR_NETGR, false},
     136           0 :         {(void**)&ops->getnetgrent_r, "getnetgrent_r", ERROR_NETGR, false},
     137           0 :         {(void**)&ops->endnetgrent, "endnetgrent", ERROR_NETGR, false},
     138           0 :         {(void**)&ops->getservbyname_r, "getservbyname_r", ERROR_SERV, false},
     139           0 :         {(void**)&ops->getservbyport_r, "getservbyport_r", ERROR_SERV, false},
     140           0 :         {(void**)&ops->setservent, "setservent", ERROR_SERV, false},
     141           0 :         {(void**)&ops->getservent_r, "getservent_r", ERROR_SERV, false},
     142           0 :         {(void**)&ops->endservent, "endservent", ERROR_SERV, false},
     143             :         {NULL, NULL, NULL, false}
     144             :     };
     145             : 
     146           0 :     for (i = 0; symbols[i].dest != NULL; i++) {
     147           0 :         *symbols[i].dest = proxy_dlsym(handle, symbols[i].name, libname);
     148           0 :         if (*symbols[i].dest == NULL) {
     149           0 :             DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load _nss_%s_%s, "
     150             :                   "error: %s.\n", libname, symbols[i].name, dlerror());
     151             : 
     152           0 :             if (symbols[i].custom_error != NULL) {
     153           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, symbols[i].custom_error, libname);
     154             :             }
     155             : 
     156           0 :             if (symbols[i].is_fatal) {
     157           0 :                 return ELIBBAD;
     158             :             }
     159             :         }
     160             :     }
     161             : 
     162           0 :     return EOK;
     163             : }
     164             : 
     165           0 : static errno_t proxy_setup_sbus(TALLOC_CTX *mem_ctx,
     166             :                                 struct proxy_auth_ctx *ctx,
     167             :                                 struct be_ctx *be_ctx)
     168             : {
     169             :     char *sbus_address;
     170             :     errno_t ret;
     171             : 
     172           0 :     sbus_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s_%s", PIPE_PATH,
     173           0 :                                    PROXY_CHILD_PIPE, be_ctx->domain->name);
     174           0 :     if (sbus_address == NULL) {
     175           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed.\n");
     176           0 :         return ENOMEM;
     177             :     }
     178             : 
     179           0 :     ret = sbus_new_server(mem_ctx, be_ctx->ev, sbus_address, 0, be_ctx->gid,
     180             :                           false, &ctx->sbus_srv, proxy_client_init, ctx);
     181           0 :     talloc_free(sbus_address);
     182           0 :     if (ret != EOK) {
     183           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n");
     184           0 :         return ret;
     185             :     }
     186             : 
     187           0 :     return EOK;
     188             : }
     189             : 
     190           0 : static errno_t proxy_auth_conf(TALLOC_CTX *mem_ctx,
     191             :                                struct be_ctx *be_ctx,
     192             :                                char **_pam_target)
     193             : {
     194             :     char *pam_target;
     195             :     errno_t ret;
     196             : 
     197           0 :     ret = confdb_get_string(be_ctx->cdb, mem_ctx, be_ctx->conf_path,
     198             :                             CONFDB_PROXY_PAM_TARGET, NULL, &pam_target);
     199           0 :     if (ret != EOK) {
     200           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n",
     201             :               ret, sss_strerror(ret));
     202           0 :         return ret;
     203             :     }
     204             : 
     205           0 :     if (pam_target == NULL) {
     206           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Missing option %s.\n",
     207             :               CONFDB_PROXY_PAM_TARGET);
     208           0 :         return EINVAL;
     209             :     }
     210             : 
     211           0 :     *_pam_target = pam_target;
     212             : 
     213           0 :     return EOK;
     214             : }
     215             : 
     216           0 : static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx,
     217             :                                    struct be_ctx *be_ctx,
     218             :                                    struct proxy_auth_ctx **_auth_ctx)
     219             : {
     220             :     struct proxy_auth_ctx *auth_ctx;
     221             :     errno_t ret;
     222             :     int hret;
     223             : 
     224           0 :     auth_ctx = talloc_zero(mem_ctx, struct proxy_auth_ctx);
     225           0 :     if (auth_ctx == NULL) {
     226           0 :         return ENOMEM;
     227             :     }
     228             : 
     229           0 :     auth_ctx->be = be_ctx;
     230           0 :     auth_ctx->timeout_ms = SSS_CLI_SOCKET_TIMEOUT / 4;
     231           0 :     auth_ctx->next_id = 1;
     232             : 
     233           0 :     ret = proxy_auth_conf(auth_ctx, be_ctx, &auth_ctx->pam_target);
     234           0 :     if (ret != EOK) {
     235           0 :         goto done;
     236             :     }
     237             : 
     238           0 :     ret = proxy_setup_sbus(auth_ctx, auth_ctx, be_ctx);
     239           0 :     if (ret != EOK) {
     240           0 :         goto done;
     241             :     }
     242             : 
     243             :     /* Set up request hash table */
     244             :     /* FIXME: get max_children from configuration file */
     245           0 :     auth_ctx->max_children = 10;
     246             : 
     247           0 :     hret = hash_create(auth_ctx->max_children * 2, &auth_ctx->request_table,
     248             :                        NULL, NULL);
     249           0 :     if (hret != HASH_SUCCESS) {
     250           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize request table\n");
     251           0 :         ret = EIO;
     252           0 :         goto done;
     253             :     }
     254             : 
     255           0 :     *_auth_ctx = auth_ctx;
     256             : 
     257           0 :     ret = EOK;
     258             : 
     259             : done:
     260           0 :     if (ret != EOK) {
     261           0 :         talloc_free(auth_ctx);
     262             :     }
     263             : 
     264           0 :     return ret;
     265             : }
     266             : 
     267           0 : errno_t sssm_proxy_init(TALLOC_CTX *mem_ctx,
     268             :                        struct be_ctx *be_ctx,
     269             :                        struct data_provider *provider,
     270             :                        const char *module_name,
     271             :                        void **_module_data)
     272             : {
     273             :     struct proxy_auth_ctx *auth_ctx;
     274             :     errno_t ret;
     275             : 
     276           0 :     if (!dp_target_enabled(provider, module_name,
     277             :                            DPT_ACCESS, DPT_AUTH, DPT_CHPASS)) {
     278           0 :         return EOK;
     279             :     }
     280             : 
     281             :     /* Initialize auth_ctx since one of the access, auth or chpass is set. */
     282             : 
     283           0 :     ret = proxy_init_auth_ctx(mem_ctx, be_ctx, &auth_ctx);
     284           0 :     if (ret != EOK) {
     285           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create auth context [%d]: %s\n",
     286             :               ret, sss_strerror(ret));
     287           0 :         return ret;
     288             :     }
     289             : 
     290           0 :     *_module_data = auth_ctx;
     291             : 
     292           0 :     return EOK;
     293             : }
     294             : 
     295           0 : errno_t sssm_proxy_id_init(TALLOC_CTX *mem_ctx,
     296             :                            struct be_ctx *be_ctx,
     297             :                            void *module_data,
     298             :                            struct dp_method *dp_methods)
     299             : {
     300             :     struct proxy_id_ctx *ctx;
     301             :     char *libname;
     302             :     char *libpath;
     303             :     errno_t ret;
     304             : 
     305           0 :     ctx = talloc_zero(mem_ctx, struct proxy_id_ctx);
     306           0 :     if (ctx == NULL) {
     307           0 :         return ENOMEM;
     308             :     }
     309             : 
     310           0 :     ctx->be = be_ctx;
     311             : 
     312           0 :     ret = proxy_id_conf(ctx, be_ctx, &libname, &libpath, &ctx->fast_alias);
     313           0 :     if (ret != EOK) {
     314           0 :         goto done;
     315             :     }
     316             : 
     317           0 :     ctx->handle = dlopen(libpath, RTLD_NOW);
     318           0 :     if (ctx->handle == NULL) {
     319           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load %s module, "
     320             :               "error: %s\n", libpath, dlerror());
     321           0 :         ret = ELIBACC;
     322           0 :         goto done;
     323             :     }
     324             : 
     325           0 :     ret = proxy_id_load_symbols(&ctx->ops, libname, ctx->handle);
     326           0 :     if (ret != EOK) {
     327           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load NSS symbols [%d]: %s\n",
     328             :               ret, sss_strerror(ret));
     329           0 :         goto done;
     330             :     }
     331             : 
     332           0 :     dp_set_method(dp_methods, DPM_ACCOUNT_HANDLER,
     333             :                   proxy_account_info_handler_send, proxy_account_info_handler_recv, ctx,
     334             :                   struct proxy_id_ctx, struct be_acct_req, struct dp_reply_std);
     335             : 
     336           0 :     ret = EOK;
     337             : 
     338             : done:
     339           0 :     if (ret != EOK) {
     340           0 :         talloc_free(ctx);
     341             :     }
     342             : 
     343           0 :     return ret;
     344             : }
     345             : 
     346           0 : errno_t sssm_proxy_auth_init(TALLOC_CTX *mem_ctx,
     347             :                              struct be_ctx *be_ctx,
     348             :                              void *module_data,
     349             :                              struct dp_method *dp_methods)
     350             : {
     351             :     struct proxy_auth_ctx *auth_ctx;
     352             : 
     353           0 :     auth_ctx = talloc_get_type(module_data, struct proxy_auth_ctx);
     354             : 
     355           0 :     dp_set_method(dp_methods, DPM_AUTH_HANDLER,
     356             :                   proxy_pam_handler_send, proxy_pam_handler_recv, auth_ctx,
     357             :                   struct proxy_auth_ctx, struct pam_data, struct pam_data *);
     358             : 
     359           0 :     return EOK;
     360             : }
     361             : 
     362           0 : errno_t sssm_proxy_chpass_init(TALLOC_CTX *mem_ctx,
     363             :                                struct be_ctx *be_ctx,
     364             :                                void *module_data,
     365             :                                struct dp_method *dp_methods)
     366             : {
     367           0 :     return sssm_proxy_auth_init(mem_ctx, be_ctx, module_data, dp_methods);
     368             : }
     369             : 
     370           0 : errno_t sssm_proxy_access_init(TALLOC_CTX *mem_ctx,
     371             :                                struct be_ctx *be_ctx,
     372             :                                void *module_data,
     373             :                                struct dp_method *dp_methods)
     374             : {
     375             :     struct proxy_auth_ctx *auth_ctx;
     376             : 
     377           0 :     auth_ctx = talloc_get_type(module_data, struct proxy_auth_ctx);
     378             : 
     379           0 :     dp_set_method(dp_methods, DPM_ACCESS_HANDLER,
     380             :                   proxy_pam_handler_send, proxy_pam_handler_recv, auth_ctx,
     381             :                   struct proxy_auth_ctx, struct pam_data, struct pam_data *);
     382             : 
     383           0 :     return EOK;
     384             : }

Generated by: LCOV version 1.10