LCOV - code coverage report
Current view: top level - responder/ifp - ifp_domains.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 226 0.0 %
Date: 2015-10-19 Functions: 0 20 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Jakub Hrozek <jhrozek@redhat.com>
       4             :         Pavel Březina <pbrezina@redhat.com>
       5             : 
       6             :     Copyright (C) 2014 Red Hat
       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 <talloc.h>
      23             : #include <tevent.h>
      24             : #include <string.h>
      25             : 
      26             : #include "db/sysdb.h"
      27             : #include "util/util.h"
      28             : #include "confdb/confdb.h"
      29             : #include "responder/common/responder.h"
      30             : #include "responder/ifp/ifp_domains.h"
      31             : 
      32             : #define RETURN_DOM_PROP_AS_STRING(dbus_req, pvt_data, out, property) do { \
      33             :     struct sss_domain_info *__dom;                                        \
      34             :                                                                           \
      35             :     *(out) = NULL;                                                        \
      36             :                                                                           \
      37             :     __dom = get_domain_info_from_req((dbus_req), (pvt_data));             \
      38             :     if (__dom == NULL) {                                                  \
      39             :         return;                                                           \
      40             :     }                                                                     \
      41             :                                                                           \
      42             :     *(out) = __dom->property;                                             \
      43             : } while (0)
      44             : 
      45             : static void ifp_list_domains_process(struct tevent_req *req);
      46             : 
      47           0 : int ifp_list_domains(struct sbus_request *dbus_req,
      48             :                      void *data)
      49             : {
      50             :     struct ifp_ctx *ifp_ctx;
      51             :     struct ifp_req *ireq;
      52             :     struct tevent_req *req;
      53             :     DBusError *error;
      54             :     errno_t ret;
      55             : 
      56           0 :     ifp_ctx = talloc_get_type(data, struct ifp_ctx);
      57           0 :     if (ifp_ctx == NULL) {
      58           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
      59           0 :         error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
      60             :                                "Invalid ifp context!");
      61           0 :         return sbus_request_fail_and_finish(dbus_req, error);
      62             :     }
      63             : 
      64           0 :     ret = ifp_req_create(dbus_req, ifp_ctx, &ireq);
      65           0 :     if (ret != EOK) {
      66           0 :         error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
      67             :                                "%s", sss_strerror(ret));
      68           0 :         return sbus_request_fail_and_finish(dbus_req, error);
      69             :     }
      70             : 
      71           0 :     req = sss_dp_get_domains_send(ireq, ifp_ctx->rctx, false, NULL);
      72           0 :     if (req == NULL) {
      73           0 :         return sbus_request_finish(ireq->dbus_req, NULL);
      74             :     }
      75             : 
      76           0 :     tevent_req_set_callback(req, ifp_list_domains_process, ireq);
      77             : 
      78           0 :     return EOK;
      79             : }
      80             : 
      81           0 : static void ifp_list_domains_process(struct tevent_req *req)
      82             : {
      83             :     struct sss_domain_info *dom;
      84             :     struct ifp_req *ireq;
      85             :     const char **paths;
      86             :     char *p;
      87             :     DBusError *error;
      88             :     size_t num_domains;
      89             :     size_t pi;
      90             :     errno_t ret;
      91             : 
      92           0 :     ireq = tevent_req_callback_data(req, struct ifp_req);
      93             : 
      94           0 :     ret = sss_dp_get_domains_recv(req);
      95           0 :     talloc_free(req);
      96           0 :     if (ret != EOK) {
      97           0 :         error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED,
      98             :                                "Failed to refresh domain objects\n");
      99           0 :         sbus_request_fail_and_finish(ireq->dbus_req, error);
     100           0 :         return;
     101             :     }
     102             : 
     103           0 :     ret = sysdb_master_domain_update(ireq->ifp_ctx->rctx->domains);
     104           0 :     if (ret != EOK) {
     105           0 :         error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED,
     106             :                                "Failed to refresh subdomain list\n");
     107           0 :         sbus_request_fail_and_finish(ireq->dbus_req, error);
     108           0 :         return;
     109             :     }
     110             : 
     111           0 :     num_domains = 0;
     112           0 :     for (dom = ireq->ifp_ctx->rctx->domains;
     113             :             dom != NULL;
     114           0 :             dom = get_next_domain(dom, true)) {
     115           0 :         num_domains++;
     116             :     }
     117             : 
     118           0 :     paths = talloc_zero_array(ireq, const char *, num_domains);
     119           0 :     if (paths == NULL) {
     120           0 :         sbus_request_finish(ireq->dbus_req, NULL);
     121           0 :         return;
     122             :     }
     123             : 
     124           0 :     pi = 0;
     125           0 :     for (dom = ireq->ifp_ctx->rctx->domains;
     126             :             dom != NULL;
     127           0 :             dom = get_next_domain(dom, true)) {
     128           0 :         p = sbus_opath_compose(ireq, IFP_PATH_DOMAINS, dom->name);
     129           0 :         if (p == NULL) {
     130           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     131             :                   "Could not create path for dom %s, skipping\n", dom->name);
     132           0 :             continue;
     133             :         }
     134           0 :         paths[pi] = p;
     135           0 :         pi++;
     136             :     }
     137             : 
     138           0 :     ret = iface_ifp_ListDomains_finish(ireq->dbus_req, paths, num_domains);
     139           0 :     if (ret != EOK) {
     140           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not finish request!\n");
     141             :     }
     142             : }
     143             : 
     144             : struct ifp_get_domain_state {
     145             :     const char *name;
     146             :     struct ifp_req *ireq;
     147             : };
     148             : 
     149             : static void ifp_find_domain_by_name_process(struct tevent_req *req);
     150             : 
     151           0 : int ifp_find_domain_by_name(struct sbus_request *dbus_req,
     152             :                             void *data,
     153             :                             const char *arg_name)
     154             : {
     155             :     struct ifp_ctx *ifp_ctx;
     156             :     struct ifp_req *ireq;
     157             :     struct tevent_req *req;
     158             :     struct ifp_get_domain_state *state;
     159             :     DBusError *error;
     160             :     errno_t ret;
     161             : 
     162           0 :     ifp_ctx = talloc_get_type(data, struct ifp_ctx);
     163           0 :     if (ifp_ctx == NULL) {
     164           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     165           0 :         error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
     166             :                                "Invalid ifp context!");
     167           0 :         return sbus_request_fail_and_finish(dbus_req, error);
     168             :     }
     169             : 
     170           0 :     ret = ifp_req_create(dbus_req, ifp_ctx, &ireq);
     171           0 :     if (ret != EOK) {
     172           0 :         error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
     173             :                                "%s", sss_strerror(ret));
     174           0 :         return sbus_request_fail_and_finish(dbus_req, error);
     175             :     }
     176             : 
     177           0 :     state = talloc_zero(ireq, struct ifp_get_domain_state);
     178           0 :     if (state == NULL) {
     179           0 :         return sbus_request_finish(dbus_req, NULL);
     180             :     }
     181           0 :     state->name = arg_name;
     182           0 :     state->ireq = ireq;
     183             : 
     184           0 :     req = sss_dp_get_domains_send(ireq, ifp_ctx->rctx, false, NULL);
     185           0 :     if (req == NULL) {
     186           0 :         return sbus_request_finish(dbus_req, NULL);
     187             :     }
     188           0 :     tevent_req_set_callback(req, ifp_find_domain_by_name_process, state);
     189           0 :     return EOK;
     190             : }
     191             : 
     192           0 : static void ifp_find_domain_by_name_process(struct tevent_req *req)
     193             : {
     194             :     errno_t ret;
     195             :     struct ifp_req *ireq;
     196             :     struct ifp_get_domain_state *state;
     197             :     struct sss_domain_info *iter;
     198             :     const char *path;
     199             :     DBusError *error;
     200             : 
     201           0 :     state = tevent_req_callback_data(req, struct ifp_get_domain_state);
     202           0 :     ireq = state->ireq;
     203             : 
     204           0 :     ret = sss_dp_get_domains_recv(req);
     205           0 :     talloc_free(req);
     206           0 :     if (ret != EOK) {
     207           0 :         error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED,
     208             :                                "Failed to refresh domain objects\n");
     209           0 :         sbus_request_fail_and_finish(ireq->dbus_req, error);
     210           0 :         return;
     211             :     }
     212             : 
     213           0 :     ret = sysdb_master_domain_update(ireq->ifp_ctx->rctx->domains);
     214           0 :     if (ret != EOK) {
     215           0 :         error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED,
     216             :                                "Failed to refresh subdomain list\n");
     217           0 :         sbus_request_fail_and_finish(ireq->dbus_req, error);
     218           0 :         return;
     219             :     }
     220             : 
     221             :     /* Reply with the domain that was asked for */
     222           0 :     for (iter = ireq->ifp_ctx->rctx->domains;
     223             :             iter != NULL;
     224           0 :             iter = get_next_domain(iter, true)) {
     225           0 :         if (strcasecmp(iter->name, state->name) == 0) {
     226           0 :             break;
     227             :         }
     228             :     }
     229             : 
     230           0 :     if (iter == NULL) {
     231           0 :         error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED,
     232             :                                "No such domain\n");
     233           0 :         sbus_request_fail_and_finish(ireq->dbus_req, error);
     234           0 :         return;
     235             :     }
     236             : 
     237           0 :     path = sbus_opath_compose(ireq, IFP_PATH_DOMAINS, iter->name);
     238           0 :     if (path == NULL) {
     239           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     240             :                 "Could not create path for domain %s, skipping\n", iter->name);
     241           0 :         sbus_request_finish(ireq->dbus_req, NULL);
     242           0 :         return;
     243             :     }
     244             : 
     245           0 :     ret = iface_ifp_FindDomainByName_finish(ireq->dbus_req, path);
     246           0 :     if (ret != EOK) {
     247           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not finish request!\n");
     248             :     }
     249             : }
     250             : 
     251             : static struct sss_domain_info *
     252           0 : get_domain_info_from_req(struct sbus_request *dbus_req, void *data)
     253             : {
     254           0 :     struct ifp_ctx *ctx = NULL;
     255           0 :     struct sss_domain_info *domains = NULL;
     256           0 :     struct sss_domain_info *iter = NULL;
     257           0 :     char *name = NULL;
     258             : 
     259           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     260           0 :     if (ctx == NULL) {
     261           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     262           0 :         return NULL;
     263             :     }
     264             : 
     265           0 :     name = sbus_opath_get_object_name(dbus_req, dbus_req->path,
     266             :                                       IFP_PATH_DOMAINS);
     267           0 :     if (name == NULL) {
     268           0 :         return NULL;
     269             :     }
     270             : 
     271           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "Looking for domain %s\n", name);
     272             : 
     273           0 :     domains = ctx->rctx->domains;
     274           0 :     for (iter = domains; iter != NULL; iter = get_next_domain(iter, true)) {
     275           0 :         if (strcasecmp(iter->name, name) == 0) {
     276           0 :             break;
     277             :         }
     278             :     }
     279             : 
     280           0 :     talloc_free(name);
     281           0 :     return iter;
     282             : }
     283             : 
     284           0 : static void get_server_list(struct sbus_request *dbus_req,
     285             :                             void *data,
     286             :                             const char ***_out,
     287             :                             int *_out_len,
     288             :                             bool backup)
     289             : {
     290             :     static const char *srv[] = {"_srv_"};
     291           0 :     struct sss_domain_info *dom = NULL;
     292           0 :     struct ifp_ctx *ctx = NULL;
     293           0 :     const char *conf_path = NULL;
     294           0 :     const char *option = NULL;
     295           0 :     const char **out = NULL;
     296           0 :     char **servers = NULL;
     297             :     int num_servers;
     298             :     errno_t ret;
     299             :     int i;
     300             : 
     301           0 :     *_out = NULL;
     302           0 :     *_out_len = 0;
     303             : 
     304           0 :     dom = get_domain_info_from_req(dbus_req, data);
     305           0 :     if (dom == NULL) {
     306           0 :         return;
     307             :     }
     308             : 
     309           0 :     if (dom->parent != NULL) {
     310             :         /* subdomains are not present in configuration */
     311           0 :         ret = ENOENT;
     312           0 :         goto done;
     313             :     }
     314             : 
     315           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     316           0 :     if (ctx == NULL) {
     317           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
     318           0 :         ret = ENOMEM;
     319           0 :         goto done;
     320             :     }
     321             : 
     322           0 :     conf_path = talloc_asprintf(dbus_req, CONFDB_DOMAIN_PATH_TMPL, dom->name);
     323           0 :     if (conf_path == NULL) {
     324           0 :         ret = ENOMEM;
     325           0 :         goto done;
     326             :     }
     327             : 
     328             :     /* TODO: replace hardcoded values with option names from the provider */
     329           0 :     if (strcasecmp(dom->provider, "ldap") == 0) {
     330           0 :         option = backup == false ? "ldap_uri" : "ldap_backup_uri";
     331           0 :     } else if (strcasecmp(dom->provider, "ipa") == 0) {
     332           0 :         option = backup == false ? "ipa_server" : "ipa_backup_server";
     333           0 :     } else if (strcasecmp(dom->provider, "ad") == 0) {
     334           0 :         option = backup == false ? "ad_server" : "ad_backup_server";
     335             :     } else {
     336           0 :         ret = EINVAL;
     337           0 :         goto done;
     338             :     }
     339             : 
     340           0 :     ret = confdb_get_string_as_list(ctx->rctx->cdb, dbus_req, conf_path,
     341             :                                     option, &servers);
     342           0 :     if (ret != EOK) {
     343           0 :         goto done;
     344             :     }
     345             : 
     346           0 :     for (num_servers = 0; servers[num_servers] != NULL; num_servers++);
     347             : 
     348           0 :     if (num_servers == 0) {
     349           0 :         ret = ENOENT;
     350           0 :         goto done;
     351             :     }
     352             : 
     353           0 :     out = talloc_zero_array(dbus_req, const char*, num_servers);
     354           0 :     if (out == NULL) {
     355           0 :         ret = ENOMEM;
     356           0 :         goto done;
     357             :     }
     358             : 
     359           0 :     for (i = 0; i < num_servers; i++) {
     360           0 :         out[i] = talloc_steal(out, servers[i]);
     361             :     }
     362             : 
     363           0 :     *_out = out;
     364           0 :     *_out_len = num_servers;
     365             : 
     366           0 :     ret = EOK;
     367             : 
     368             : done:
     369           0 :     if (ret == ENOENT) {
     370           0 :         *_out = srv;
     371           0 :         *_out_len = 1;
     372             :     }
     373             : 
     374           0 :     return;
     375             : }
     376             : 
     377           0 : void ifp_dom_get_name(struct sbus_request *dbus_req,
     378             :                       void *data,
     379             :                       const char **_out)
     380             : {
     381           0 :     RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, name);
     382             : }
     383             : 
     384           0 : void ifp_dom_get_provider(struct sbus_request *dbus_req,
     385             :                           void *data,
     386             :                           const char **_out)
     387             : {
     388           0 :     RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, provider);
     389             : }
     390             : 
     391           0 : void ifp_dom_get_primary_servers(struct sbus_request *dbus_req,
     392             :                                  void *data,
     393             :                                  const char ***_out,
     394             :                                  int *_out_len)
     395             : {
     396           0 :     get_server_list(dbus_req, data, _out, _out_len, false);
     397           0 : }
     398             : 
     399           0 : void ifp_dom_get_backup_servers(struct sbus_request *dbus_req,
     400             :                                 void *data,
     401             :                                 const char ***_out,
     402             :                                 int *_out_len)
     403             : {
     404           0 :     get_server_list(dbus_req, data, _out, _out_len, true);
     405           0 : }
     406             : 
     407           0 : void ifp_dom_get_min_id(struct sbus_request *dbus_req,
     408             :                         void *data,
     409             :                         uint32_t *_out)
     410             : {
     411             :     struct sss_domain_info *dom;
     412             : 
     413           0 :     *_out = 1;
     414             : 
     415           0 :     dom = get_domain_info_from_req(dbus_req, data);
     416           0 :     if (dom == NULL) {
     417           0 :         return;
     418             :     }
     419             : 
     420           0 :     *_out = dom->id_min;
     421             : }
     422             : 
     423           0 : void ifp_dom_get_max_id(struct sbus_request *dbus_req,
     424             :                         void *data,
     425             :                         uint32_t *_out)
     426             : {
     427             :     struct sss_domain_info *dom;
     428             : 
     429           0 :     *_out = 0;
     430             : 
     431           0 :     dom = get_domain_info_from_req(dbus_req, data);
     432           0 :     if (dom == NULL) {
     433           0 :         return;
     434             :     }
     435             : 
     436           0 :     *_out = dom->id_max;
     437             : }
     438             : 
     439           0 : void ifp_dom_get_realm(struct sbus_request *dbus_req,
     440             :                        void *data,
     441             :                        const char **_out)
     442             : {
     443           0 :     RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, realm);
     444             : }
     445             : 
     446           0 : void ifp_dom_get_forest(struct sbus_request *dbus_req,
     447             :                         void *data,
     448             :                         const char **_out)
     449             : {
     450           0 :     RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, forest);
     451             : }
     452             : 
     453           0 : void ifp_dom_get_login_format(struct sbus_request *dbus_req,
     454             :                               void *data,
     455             :                               const char **_out)
     456             : {
     457           0 :     RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, names->re_pattern);
     458             : }
     459             : 
     460           0 : void ifp_dom_get_fqdn_format(struct sbus_request *dbus_req,
     461             :                              void *data,
     462             :                              const char **_out)
     463             : {
     464           0 :     RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, names->fq_fmt);
     465             : }
     466             : 
     467           0 : void ifp_dom_get_enumerable(struct sbus_request *dbus_req,
     468             :                             void *data,
     469             :                             bool *_out)
     470             : {
     471             :     struct sss_domain_info *dom;
     472             : 
     473           0 :     *_out = false;
     474             : 
     475           0 :     dom = get_domain_info_from_req(dbus_req, data);
     476           0 :     if (dom == NULL) {
     477           0 :         return;
     478             :     }
     479             : 
     480           0 :     *_out = dom->enumerate;
     481             : }
     482             : 
     483           0 : void ifp_dom_get_use_fqdn(struct sbus_request *dbus_req,
     484             :                           void *data,
     485             :                           bool *_out)
     486             : {
     487             :     struct sss_domain_info *dom;
     488             : 
     489           0 :     *_out = false;
     490             : 
     491           0 :     dom = get_domain_info_from_req(dbus_req, data);
     492           0 :     if (dom == NULL) {
     493           0 :         return;
     494             :     }
     495             : 
     496           0 :     *_out = dom->fqnames;
     497             : }
     498             : 
     499           0 : void ifp_dom_get_subdomain(struct sbus_request *dbus_req,
     500             :                            void *data,
     501             :                            bool *_out)
     502             : {
     503             :     struct sss_domain_info *dom;
     504             : 
     505           0 :     *_out = false;
     506             : 
     507           0 :     dom = get_domain_info_from_req(dbus_req, data);
     508           0 :     if (dom == NULL) {
     509           0 :         return;
     510             :     }
     511             : 
     512           0 :     *_out = dom->parent ? true : false;
     513             : }
     514             : 
     515           0 : void ifp_dom_get_parent_domain(struct sbus_request *dbus_req,
     516             :                               void *data,
     517             :                               const char **_out)
     518             : {
     519             :     struct sss_domain_info *dom;
     520             : 
     521           0 :     *_out = NULL;
     522             : 
     523           0 :     dom = get_domain_info_from_req(dbus_req, data);
     524           0 :     if (dom == NULL) {
     525           0 :         return;
     526             :     }
     527             : 
     528           0 :     if (dom->parent == NULL) {
     529           0 :         *_out = "/";
     530           0 :         return;
     531             :     }
     532             : 
     533           0 :     *_out = sbus_opath_compose(dbus_req, IFP_PATH_DOMAINS,
     534             :                                dom->parent->name);
     535             : }

Generated by: LCOV version 1.10