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

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Stephen Gallagher <sgallagh@redhat.com>
       6             : 
       7             :     Copyright (C) 2012 Red Hat
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : 
      24             : #include <errno.h>
      25             : 
      26             : #include "util/util.h"
      27             : #include "util/strtonum.h"
      28             : #include "db/sysdb.h"
      29             : #include "db/sysdb_services.h"
      30             : #include "providers/ldap/ldap_common.h"
      31             : #include "providers/ldap/sdap_async.h"
      32             : 
      33             : struct sdap_services_get_state {
      34             :     struct tevent_context *ev;
      35             :     struct sdap_id_ctx *id_ctx;
      36             :     struct sdap_domain *sdom;
      37             :     struct sdap_id_op *op;
      38             :     struct sysdb_ctx *sysdb;
      39             :     struct sss_domain_info *domain;
      40             :     struct sdap_id_conn_ctx *conn;
      41             : 
      42             :     const char *name;
      43             :     const char *protocol;
      44             : 
      45             :     char *filter;
      46             :     const char **attrs;
      47             : 
      48             :     int filter_type;
      49             : 
      50             :     int dp_error;
      51             :     int sdap_ret;
      52             :     bool noexist_delete;
      53             : };
      54             : 
      55             : static errno_t
      56             : services_get_retry(struct tevent_req *req);
      57             : static void
      58             : services_get_connect_done(struct tevent_req *subreq);
      59             : static void
      60             : services_get_done(struct tevent_req *subreq);
      61             : 
      62             : struct tevent_req *
      63           0 : services_get_send(TALLOC_CTX *mem_ctx,
      64             :                   struct tevent_context *ev,
      65             :                   struct sdap_id_ctx *id_ctx,
      66             :                   struct sdap_domain *sdom,
      67             :                   struct sdap_id_conn_ctx *conn,
      68             :                   const char *name,
      69             :                   const char *protocol,
      70             :                   int filter_type,
      71             :                   bool noexist_delete)
      72             : {
      73             :     errno_t ret;
      74             :     struct tevent_req *req;
      75             :     struct sdap_services_get_state *state;
      76             :     const char *attr_name;
      77             :     char *clean_name;
      78           0 :     char *clean_protocol = NULL;
      79             : 
      80           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_services_get_state);
      81           0 :     if (!req) return NULL;
      82             : 
      83           0 :     state->ev = ev;
      84           0 :     state->id_ctx = id_ctx;
      85           0 :     state->sdom = sdom;
      86           0 :     state->conn = conn;
      87           0 :     state->dp_error = DP_ERR_FATAL;
      88           0 :     state->domain = sdom->dom;
      89           0 :     state->sysdb = sdom->dom->sysdb;
      90           0 :     state->name = name;
      91           0 :     state->protocol = protocol;
      92           0 :     state->filter_type = filter_type;
      93           0 :     state->noexist_delete = noexist_delete;
      94             : 
      95           0 :     state->op = sdap_id_op_create(state, state->conn->conn_cache);
      96           0 :     if (!state->op) {
      97           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "sdap_id_op_create failed\n");
      98           0 :         ret = ENOMEM;
      99           0 :         goto error;
     100             :     }
     101             : 
     102           0 :     switch(filter_type) {
     103             :     case BE_FILTER_NAME:
     104           0 :         attr_name = id_ctx->opts->service_map[SDAP_AT_SERVICE_NAME].name;
     105           0 :         break;
     106             :     case BE_FILTER_IDNUM:
     107           0 :         attr_name = id_ctx->opts->service_map[SDAP_AT_SERVICE_PORT].name;
     108           0 :         break;
     109             :     default:
     110           0 :         ret = EINVAL;
     111           0 :         goto error;
     112             :     }
     113             : 
     114           0 :     ret = sss_filter_sanitize(state, name, &clean_name);
     115           0 :     if (ret != EOK)  goto error;
     116             : 
     117           0 :     if (protocol) {
     118           0 :         ret = sss_filter_sanitize(state, protocol, &clean_protocol);
     119           0 :         if (ret != EOK)  goto error;
     120             :     }
     121             : 
     122           0 :     if (clean_protocol) {
     123           0 :         state->filter = talloc_asprintf(
     124             :                 state, "(&(%s=%s)(%s=%s)(objectclass=%s))",
     125             :                 attr_name, clean_name,
     126           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_PROTOCOL].name,
     127             :                 clean_protocol,
     128           0 :                 id_ctx->opts->service_map[SDAP_OC_SERVICE].name);
     129             :     } else {
     130           0 :         state->filter =
     131           0 :                 talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
     132             :                                 attr_name, clean_name,
     133           0 :                                 id_ctx->opts->service_map[SDAP_OC_SERVICE].name);
     134             :     }
     135           0 :     talloc_zfree(clean_name);
     136           0 :     talloc_zfree(clean_protocol);
     137           0 :     if (!state->filter) {
     138           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     139             :               "Failed to build the base filter\n");
     140           0 :         ret = ENOMEM;
     141           0 :         goto error;
     142             :     }
     143           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     144             :           "Preparing to search for services with filter [%s]\n",
     145             :            state->filter);
     146             : 
     147           0 :     ret = build_attrs_from_map(state, id_ctx->opts->service_map,
     148             :                                SDAP_OPTS_SERVICES, NULL,
     149           0 :                                &state->attrs, NULL);
     150           0 :     if (ret != EOK) goto error;
     151             : 
     152           0 :     ret = services_get_retry(req);
     153           0 :     if (ret != EOK) goto error;
     154             : 
     155           0 :     return req;
     156             : 
     157             : error:
     158           0 :     tevent_req_error(req, ret);
     159           0 :     tevent_req_post(req, ev);
     160           0 :     return req;
     161             : }
     162             : 
     163             : static errno_t
     164           0 : services_get_retry(struct tevent_req *req)
     165             : {
     166             :     errno_t ret;
     167           0 :     struct sdap_services_get_state *state =
     168           0 :             tevent_req_data(req, struct sdap_services_get_state);
     169             :     struct tevent_req *subreq;
     170             : 
     171           0 :     subreq = sdap_id_op_connect_send(state->op, state, &ret);
     172           0 :     if (!subreq) {
     173           0 :         return ret;
     174             :     }
     175             : 
     176           0 :     tevent_req_set_callback(subreq, services_get_connect_done, req);
     177           0 :     return EOK;
     178             : }
     179             : 
     180             : static void
     181           0 : services_get_connect_done(struct tevent_req *subreq)
     182             : {
     183             :     errno_t ret;
     184           0 :     struct tevent_req *req =
     185           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     186           0 :     struct sdap_services_get_state *state =
     187           0 :             tevent_req_data(req, struct sdap_services_get_state);
     188           0 :     int dp_error = DP_ERR_FATAL;
     189             : 
     190           0 :     ret = sdap_id_op_connect_recv(subreq, &dp_error);
     191           0 :     talloc_zfree(subreq);
     192             : 
     193           0 :     if (ret != EOK) {
     194           0 :         state->dp_error = dp_error;
     195           0 :         tevent_req_error(req, ret);
     196           0 :         return;
     197             :     }
     198             : 
     199           0 :     subreq = sdap_get_services_send(state, state->ev,
     200             :                                     state->domain, state->sysdb,
     201           0 :                                     state->id_ctx->opts,
     202           0 :                                     state->sdom->service_search_bases,
     203             :                                     sdap_id_op_handle(state->op),
     204           0 :                                     state->attrs, state->filter,
     205           0 :                                     dp_opt_get_int(state->id_ctx->opts->basic,
     206             :                                                    SDAP_SEARCH_TIMEOUT),
     207             :                                     false);
     208           0 :     if (!subreq) {
     209           0 :         tevent_req_error(req, ENOMEM);
     210           0 :         return;
     211             :     }
     212           0 :     tevent_req_set_callback(subreq, services_get_done, req);
     213             : }
     214             : 
     215             : static void
     216           0 : services_get_done(struct tevent_req *subreq)
     217             : {
     218             :     errno_t ret;
     219             :     uint16_t port;
     220           0 :     struct tevent_req *req =
     221           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     222           0 :     struct sdap_services_get_state *state =
     223           0 :             tevent_req_data(req, struct sdap_services_get_state);
     224           0 :     int dp_error = DP_ERR_FATAL;
     225             : 
     226           0 :     ret = sdap_get_services_recv(NULL, subreq, NULL);
     227           0 :     talloc_zfree(subreq);
     228             : 
     229             :     /* Check whether we need to try again with another
     230             :      * failover server.
     231             :      */
     232           0 :     ret = sdap_id_op_done(state->op, ret, &dp_error);
     233           0 :     if (dp_error == DP_ERR_OK && ret != EOK) {
     234             :         /* retry */
     235           0 :         ret = services_get_retry(req);
     236           0 :         if (ret != EOK) {
     237           0 :             tevent_req_error(req, ret);
     238           0 :             return;
     239             :         }
     240             : 
     241             :         /* Return to the mainloop to retry */
     242           0 :         return;
     243             :     }
     244           0 :     state->sdap_ret = ret;
     245             : 
     246             :     /* An error occurred. */
     247           0 :     if (ret && ret != ENOENT) {
     248           0 :         state->dp_error = dp_error;
     249           0 :         tevent_req_error(req, ret);
     250           0 :         return;
     251             :     }
     252             : 
     253           0 :     if (ret == ENOENT && state->noexist_delete == true) {
     254             :         /* Ensure that this entry is removed from the sysdb */
     255           0 :         switch(state->filter_type) {
     256             :         case BE_FILTER_NAME:
     257           0 :             ret = sysdb_svc_delete(state->domain, state->name,
     258             :                                    0, state->protocol);
     259           0 :             if (ret != EOK) {
     260           0 :                 tevent_req_error(req, ret);
     261           0 :                 return;
     262             :             }
     263           0 :             break;
     264             : 
     265             :         case BE_FILTER_IDNUM:
     266           0 :             port = strtouint16(state->name, NULL, 10);
     267           0 :             if (errno) {
     268           0 :                 tevent_req_error(req, errno);
     269           0 :                 return;
     270             :             }
     271             : 
     272           0 :             ret = sysdb_svc_delete(state->domain, NULL,  port,
     273             :                                    state->protocol);
     274           0 :             if (ret != EOK) {
     275           0 :                 tevent_req_error(req, ret);
     276           0 :                 return;
     277             :             }
     278           0 :             break;
     279             : 
     280             :         default:
     281           0 :             tevent_req_error(req, EINVAL);
     282           0 :             return;
     283             :         }
     284             :     }
     285             : 
     286           0 :     state->dp_error = DP_ERR_OK;
     287           0 :     tevent_req_done(req);
     288             : }
     289             : 
     290             : errno_t
     291           0 : services_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret)
     292             : {
     293           0 :     struct sdap_services_get_state *state =
     294           0 :             tevent_req_data(req, struct sdap_services_get_state);
     295             : 
     296           0 :     if (dp_error_out) {
     297           0 :         *dp_error_out = state->dp_error;
     298             :     }
     299             : 
     300           0 :     if (sdap_ret) {
     301           0 :         *sdap_ret = state->sdap_ret;
     302             :     }
     303             : 
     304           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     305             : 
     306           0 :     return EOK;
     307             : }

Generated by: LCOV version 1.10