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

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     LDAP handler for autofs
       5             : 
       6             :     Authors:
       7             :         Jakub Hrozek <jhrozek@redhat.com>
       8             : 
       9             :     Copyright (C) 2012 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 <errno.h>
      26             : #include <tevent.h>
      27             : 
      28             : #include "providers/ldap/ldap_common.h"
      29             : #include "providers/ldap/sdap_autofs.h"
      30             : #include "providers/ldap/sdap.h"
      31             : #include "providers/ldap/sdap_async.h"
      32             : #include "providers/backend.h"
      33             : #include "providers/data_provider.h"
      34             : #include "db/sysdb_autofs.h"
      35             : #include "util/util.h"
      36             : 
      37             : struct autofs_get_map_state {
      38             :     struct tevent_context *ev;
      39             :     struct sdap_id_ctx *ctx;
      40             :     struct sdap_id_op *op;
      41             :     const char *map_name;
      42             : 
      43             :     int dp_error;
      44             : };
      45             : 
      46             : static errno_t
      47             : sdap_autofs_get_map_retry(struct tevent_req *req);
      48             : static void
      49             : sdap_autofs_get_map_connect_done(struct tevent_req *subreq);
      50             : static void
      51             : sdap_autofs_get_map_done(struct tevent_req *req);
      52             : 
      53             : static struct tevent_req *
      54           0 : sdap_autofs_get_map_send(TALLOC_CTX *mem_ctx,
      55             :                          struct tevent_context *ev,
      56             :                          struct sdap_id_ctx *ctx,
      57             :                          const char *map_name)
      58             : {
      59             :     struct tevent_req *req;
      60             :     struct autofs_get_map_state *state;
      61             :     int ret;
      62             : 
      63           0 :     req = tevent_req_create(mem_ctx, &state, struct autofs_get_map_state);
      64           0 :     if (!req) return NULL;
      65             : 
      66           0 :     state->ev = ev;
      67           0 :     state->ctx = ctx;
      68           0 :     state->dp_error = DP_ERR_FATAL;
      69           0 :     state->map_name = map_name;
      70             : 
      71           0 :     state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache);
      72           0 :     if (!state->op) {
      73           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
      74           0 :         ret = ENOMEM;
      75           0 :         goto fail;
      76             :     }
      77             : 
      78           0 :     ret = sdap_autofs_get_map_retry(req);
      79           0 :     if (ret != EOK) {
      80           0 :         goto fail;
      81             :     }
      82             : 
      83           0 :     return req;
      84             : 
      85             : fail:
      86           0 :     tevent_req_error(req, ret);
      87           0 :     tevent_req_post(req, ev);
      88           0 :     return req;
      89             : }
      90             : 
      91             : static errno_t
      92           0 : sdap_autofs_get_map_retry(struct tevent_req *req)
      93             : {
      94           0 :     struct autofs_get_map_state *state =
      95           0 :                 tevent_req_data(req, struct autofs_get_map_state);
      96             :     struct tevent_req *subreq;
      97           0 :     int ret = EOK;
      98             : 
      99           0 :     subreq = sdap_id_op_connect_send(state->op, state, &ret);
     100           0 :     if (!subreq) {
     101           0 :         return ret;
     102             :     }
     103             : 
     104           0 :     tevent_req_set_callback(subreq, sdap_autofs_get_map_connect_done, req);
     105           0 :     return EOK;
     106             : }
     107             : 
     108             : static void
     109           0 : sdap_autofs_get_map_connect_done(struct tevent_req *subreq)
     110             : {
     111           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     112             :                                                       struct tevent_req);
     113           0 :     struct autofs_get_map_state *state =
     114           0 :                 tevent_req_data(req, struct autofs_get_map_state);
     115           0 :     int dp_error = DP_ERR_FATAL;
     116             :     int ret;
     117             : 
     118           0 :     ret = sdap_id_op_connect_recv(subreq, &dp_error);
     119           0 :     talloc_zfree(subreq);
     120             : 
     121           0 :     if (ret != EOK) {
     122           0 :         state->dp_error = dp_error;
     123           0 :         tevent_req_error(req, ret);
     124           0 :         return;
     125             :     }
     126             : 
     127           0 :     subreq = sdap_autofs_setautomntent_send(state, state->ev,
     128           0 :                                             state->ctx->be->domain,
     129           0 :                                             state->ctx->be->domain->sysdb,
     130             :                                             sdap_id_op_handle(state->op),
     131             :                                             state->op,
     132           0 :                                             state->ctx->opts,
     133             :                                             state->map_name);
     134           0 :     if (!subreq) {
     135           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     136             :               "sdap_autofs_setautomntent_send failed\n");
     137           0 :         tevent_req_error(req, ENOMEM);
     138           0 :         return;
     139             :     }
     140           0 :     tevent_req_set_callback(subreq, sdap_autofs_get_map_done, req);
     141             : 
     142             : }
     143             : 
     144             : static void
     145           0 : sdap_autofs_get_map_done(struct tevent_req *subreq)
     146             : {
     147           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     148             :                                                       struct tevent_req);
     149           0 :     struct autofs_get_map_state *state =
     150           0 :         tevent_req_data(req, struct autofs_get_map_state);
     151           0 :     int dp_error = DP_ERR_FATAL;
     152             :     int ret;
     153             : 
     154           0 :     ret = sdap_autofs_setautomntent_recv(subreq);
     155           0 :     talloc_zfree(subreq);
     156             : 
     157           0 :     ret = sdap_id_op_done(state->op, ret, &dp_error);
     158           0 :     if (dp_error == DP_ERR_OK && ret != EOK) {
     159             :         /* retry */
     160           0 :         ret = sdap_autofs_get_map_retry(req);
     161           0 :         if (ret != EOK) {
     162           0 :             tevent_req_error(req, ret);
     163           0 :             return;
     164             :         }
     165           0 :         return;
     166             :     }
     167             : 
     168           0 :     if (ret && ret != ENOENT) {
     169           0 :         state->dp_error = dp_error;
     170           0 :         tevent_req_error(req, ret);
     171           0 :         return;
     172             :     }
     173             : 
     174           0 :     if (ret == ENOENT) {
     175           0 :         ret = sysdb_delete_autofsmap(state->ctx->be->domain, state->map_name);
     176           0 :         if (ret != EOK && ret != ENOENT) {
     177           0 :             DEBUG(SSSDBG_OP_FAILURE,
     178             :                 "Cannot delete autofs map %s [%d]: %s\n",
     179             :                  state->map_name, ret, strerror(ret));
     180           0 :             tevent_req_error(req, ret);
     181           0 :             return;
     182             :         }
     183             :     }
     184             : 
     185           0 :     state->dp_error = DP_ERR_OK;
     186           0 :     tevent_req_done(req);
     187             : }
     188             : 
     189             : static errno_t
     190           0 : sdap_autofs_get_map_recv(struct tevent_req *req, int *dp_error_out)
     191             : {
     192           0 :     struct autofs_get_map_state *state =
     193           0 :         tevent_req_data(req, struct autofs_get_map_state);
     194             : 
     195           0 :     if (dp_error_out) {
     196           0 :         *dp_error_out = state->dp_error;
     197             :     }
     198             : 
     199           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     200             : 
     201           0 :     return EOK;
     202             : }
     203             : 
     204             : struct sdap_autofs_handler_state {
     205             :     struct dp_reply_std reply;
     206             : };
     207             : 
     208             : static void sdap_autofs_handler_done(struct tevent_req *subreq);
     209             : 
     210             : struct tevent_req *
     211           0 : sdap_autofs_handler_send(TALLOC_CTX *mem_ctx,
     212             :                          struct sdap_id_ctx *id_ctx,
     213             :                          struct dp_autofs_data *data,
     214             :                          struct dp_req_params *params)
     215             : {
     216             :     struct sdap_autofs_handler_state *state;
     217             :     struct tevent_req *subreq;
     218             :     struct tevent_req *req;
     219             :     const char *master_map;
     220             : 
     221             :     errno_t ret;
     222             : 
     223           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_autofs_handler_state);
     224           0 :     if (req == NULL) {
     225           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
     226           0 :         return NULL;
     227             :     }
     228             : 
     229           0 :     DEBUG(SSSDBG_FUNC_DATA, "Requested refresh for: %s\n", data->mapname);
     230             : 
     231           0 :     master_map = dp_opt_get_string(id_ctx->opts->basic,
     232             :                                    SDAP_AUTOFS_MAP_MASTER_NAME);
     233           0 :     if (strcmp(master_map, data->mapname) == 0) {
     234           0 :         DEBUG(SSSDBG_FUNC_DATA, "Refresh of automount master map triggered: "
     235             :               "%s\n", data->mapname);
     236             : 
     237           0 :         ret = sysdb_invalidate_autofs_maps(id_ctx->be->domain);
     238           0 :         if (ret != EOK) {
     239           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Could not invalidate autofs maps, "
     240             :                   "backend might return stale entries\n");
     241             :         }
     242             :     }
     243             : 
     244           0 :     subreq = sdap_autofs_get_map_send(mem_ctx, params->ev,
     245             :                                       id_ctx, data->mapname);
     246           0 :     if (subreq == NULL) {
     247           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request for %s.\n",
     248             :               data->mapname);
     249           0 :         ret = ENOMEM;
     250           0 :         goto immediately;
     251             :     }
     252             : 
     253           0 :     tevent_req_set_callback(subreq, sdap_autofs_handler_done, req);
     254             : 
     255           0 :     return req;
     256             : 
     257             : immediately:
     258           0 :     dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
     259             : 
     260             :     /* TODO For backward compatibility we always return EOK to DP now. */
     261           0 :     tevent_req_done(req);
     262           0 :     tevent_req_post(req, params->ev);
     263             : 
     264           0 :     return req;
     265             : }
     266             : 
     267           0 : static void sdap_autofs_handler_done(struct tevent_req *subreq)
     268             : {
     269             :     struct sdap_autofs_handler_state *state;
     270             :     struct tevent_req *req;
     271             :     int dp_error;
     272             :     errno_t ret;
     273             : 
     274           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     275           0 :     state = tevent_req_data(req, struct sdap_autofs_handler_state);
     276             : 
     277           0 :     ret = sdap_autofs_get_map_recv(subreq, &dp_error);
     278           0 :     talloc_zfree(subreq);
     279             : 
     280             :     /* TODO For backward compatibility we always return EOK to DP now. */
     281           0 :     dp_reply_std_set(&state->reply, dp_error, ret, NULL);
     282           0 :     tevent_req_done(req);
     283           0 : }
     284             : 
     285             : errno_t
     286           0 : sdap_autofs_handler_recv(TALLOC_CTX *mem_ctx,
     287             :                          struct tevent_req *req,
     288             :                          struct dp_reply_std *data)
     289             : {
     290           0 :     struct sdap_autofs_handler_state *state = NULL;
     291             : 
     292           0 :     state = tevent_req_data(req, struct sdap_autofs_handler_state);
     293             : 
     294           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     295             : 
     296           0 :     *data = state->reply;
     297             : 
     298           0 :     return EOK;
     299             : }
     300             : 
     301           0 : errno_t sdap_autofs_init(TALLOC_CTX *mem_ctx,
     302             :                          struct be_ctx *be_ctx,
     303             :                          struct sdap_id_ctx *id_ctx,
     304             :                          struct dp_method *dp_methods)
     305             : {
     306             :     errno_t ret;
     307             : 
     308           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing autofs LDAP back end\n");
     309             : 
     310           0 :     ret = ldap_get_autofs_options(id_ctx, be_ctx->cdb, be_ctx->conf_path,
     311             :                                   id_ctx->opts);
     312           0 :     if (ret != EOK) {
     313           0 :         return ret;
     314             :     }
     315             : 
     316           0 :     dp_set_method(dp_methods, DPM_AUTOFS_HANDLER,
     317             :                   sdap_autofs_handler_send, sdap_autofs_handler_recv, id_ctx,
     318             :                   struct sdap_id_ctx, struct dp_autofs_data, struct dp_reply_std);
     319             : 
     320           0 :     return EOK;
     321             : }

Generated by: LCOV version 1.10