LCOV - code coverage report
Current view: top level - util - sss_ldap.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 37 244 15.2 %
Date: 2015-10-19 Functions: 3 14 21.4 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Sumit Bose <sbose@redhat.com>
       4             : 
       5             :     Copyright (C) 2009 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : #include <stdlib.h>
      21             : #include <unistd.h>
      22             : #include <fcntl.h>
      23             : #include <sys/socket.h>
      24             : #include <netinet/in.h>
      25             : #include <netinet/tcp.h>
      26             : 
      27             : #include "config.h"
      28             : 
      29             : #include "providers/ldap/sdap.h"
      30             : #include "util/sss_ldap.h"
      31             : #include "util/util.h"
      32             : 
      33           1 : const char* sss_ldap_err2string(int err)
      34             : {
      35           1 :     if (IS_SSSD_ERROR(err)) {
      36           0 :         return sss_strerror(err);
      37             :     } else {
      38           1 :         return ldap_err2string(err);
      39             :     }
      40             : }
      41             : 
      42           0 : int sss_ldap_get_diagnostic_msg(TALLOC_CTX *mem_ctx, LDAP *ld, char **_errmsg)
      43             : {
      44           0 :     char *errmsg = NULL;
      45             :     int optret;
      46             : 
      47           0 :     optret = ldap_get_option(ld, SDAP_DIAGNOSTIC_MESSAGE, (void*)&errmsg);
      48           0 :     if (optret != LDAP_SUCCESS) {
      49           0 :         return EINVAL;
      50             :     }
      51             : 
      52           0 :     *_errmsg = talloc_strdup(mem_ctx, errmsg ? errmsg : "unknown error");
      53           0 :     ldap_memfree(errmsg);
      54           0 :     if (*_errmsg == NULL) {
      55           0 :         return ENOMEM;
      56             :     }
      57           0 :     return EOK;
      58             : }
      59             : 
      60           0 : int sss_ldap_control_create(const char *oid, int iscritical,
      61             :                             struct berval *value, int dupval,
      62             :                             LDAPControl **ctrlp)
      63             : {
      64             : #ifdef HAVE_LDAP_CONTROL_CREATE
      65           0 :     return ldap_control_create(oid, iscritical, value, dupval, ctrlp);
      66             : #else
      67             :     LDAPControl *lc = NULL;
      68             : 
      69             :     if (oid == NULL || ctrlp == NULL) {
      70             :         return LDAP_PARAM_ERROR;
      71             :     }
      72             : 
      73             :     lc = calloc(sizeof(LDAPControl), 1);
      74             :     if (lc == NULL) {
      75             :         return LDAP_NO_MEMORY;
      76             :     }
      77             : 
      78             :     lc->ldctl_oid = strdup(oid);
      79             :     if (lc->ldctl_oid == NULL) {
      80             :         free(lc);
      81             :         return LDAP_NO_MEMORY;
      82             :     }
      83             : 
      84             :     if (value != NULL && value->bv_val != NULL) {
      85             :         if (dupval == 0) {
      86             :             lc->ldctl_value = *value;
      87             :         } else {
      88             :             ber_dupbv(&lc->ldctl_value, value);
      89             :             if (lc->ldctl_value.bv_val == NULL) {
      90             :                 free(lc->ldctl_oid);
      91             :                 free(lc);
      92             :                 return LDAP_NO_MEMORY;
      93             :             }
      94             :         }
      95             :     }
      96             : 
      97             :     lc->ldctl_iscritical = iscritical;
      98             : 
      99             :     *ctrlp = lc;
     100             : 
     101             :     return LDAP_SUCCESS;
     102             : #endif
     103             : }
     104             : 
     105             : #ifdef HAVE_LDAP_INIT_FD
     106             : struct sdap_async_sys_connect_state {
     107             :     long old_flags;
     108             :     struct tevent_fd *fde;
     109             :     int fd;
     110             :     socklen_t addr_len;
     111             :     struct sockaddr_storage addr;
     112             : };
     113             : 
     114             : static void sdap_async_sys_connect_done(struct tevent_context *ev,
     115             :                                         struct tevent_fd *fde, uint16_t flags,
     116             :                                         void *priv);
     117             : 
     118           0 : static struct tevent_req *sdap_async_sys_connect_send(TALLOC_CTX *mem_ctx,
     119             :                                                     struct tevent_context *ev,
     120             :                                                     int fd,
     121             :                                                     const struct sockaddr *addr,
     122             :                                                     socklen_t addr_len)
     123             : {
     124             :     struct tevent_req *req;
     125             :     struct sdap_async_sys_connect_state *state;
     126             :     long flags;
     127             :     int ret;
     128             :     int fret;
     129             : 
     130           0 :     flags = fcntl(fd, F_GETFL, 0);
     131           0 :     if (flags == -1) {
     132           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_GETFL failed.\n");
     133           0 :         return NULL;
     134             :     }
     135             : 
     136           0 :     req = tevent_req_create(mem_ctx, &state,
     137             :                             struct sdap_async_sys_connect_state);
     138           0 :     if (req == NULL) {
     139           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n");
     140           0 :         return NULL;
     141             :     }
     142             : 
     143           0 :     state->old_flags = flags;
     144           0 :     state->fd = fd;
     145           0 :     state->addr_len = addr_len;
     146           0 :     memcpy(&state->addr, addr, addr_len);
     147             : 
     148           0 :     ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
     149           0 :     if (ret != EOK) {
     150           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFL failed.\n");
     151           0 :         goto done;
     152             :     }
     153             : 
     154           0 :     ret = connect(fd, addr, addr_len);
     155           0 :     if (ret == EOK) {
     156           0 :         goto done;
     157             :     }
     158             : 
     159           0 :     ret = errno;
     160           0 :     switch(ret) {
     161             :         case EINPROGRESS:
     162             :         case EINTR:
     163           0 :             state->fde = tevent_add_fd(ev, state, fd,
     164             :                                        TEVENT_FD_READ | TEVENT_FD_WRITE,
     165             :                                        sdap_async_sys_connect_done, req);
     166           0 :             if (state->fde == NULL) {
     167           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd failed.\n");
     168           0 :                 ret = ENOMEM;
     169           0 :                 goto done;
     170             :             }
     171             : 
     172           0 :             return req;
     173             : 
     174             :             break;
     175             :         default:
     176           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     177             :                   "connect failed [%d][%s].\n", ret, strerror(ret));
     178             :     }
     179             : 
     180             : done:
     181           0 :     fret = fcntl(fd, F_SETFL, flags);
     182           0 :     if (fret != EOK) {
     183           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFL failed.\n");
     184             :     }
     185             : 
     186           0 :     if (ret == EOK) {
     187           0 :         tevent_req_done(req);
     188             :     } else {
     189           0 :         tevent_req_error(req, ret);
     190             :     }
     191             : 
     192           0 :     tevent_req_post(req, ev);
     193           0 :     return req;
     194             : }
     195             : 
     196           0 : static void sdap_async_sys_connect_done(struct tevent_context *ev,
     197             :                                         struct tevent_fd *fde, uint16_t flags,
     198             :                                         void *priv)
     199             : {
     200           0 :     struct tevent_req *req = talloc_get_type(priv, struct tevent_req);
     201           0 :     struct sdap_async_sys_connect_state *state = tevent_req_data(req,
     202             :                                           struct sdap_async_sys_connect_state);
     203             :     int ret;
     204             :     int fret;
     205             : 
     206           0 :     errno = 0;
     207           0 :     ret = connect(state->fd, (struct sockaddr *) &state->addr,
     208             :                   state->addr_len);
     209           0 :     if (ret != EOK) {
     210           0 :         ret = errno;
     211           0 :         if (ret == EINPROGRESS || ret == EINTR) {
     212           0 :             return; /* Try again later */
     213             :         }
     214           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     215             :               "connect failed [%d][%s].\n", ret, strerror(ret));
     216             :     }
     217             : 
     218           0 :     talloc_zfree(fde);
     219             : 
     220           0 :     fret = fcntl(state->fd, F_SETFL, state->old_flags);
     221           0 :     if (fret != EOK) {
     222           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFL failed.\n");
     223             :     }
     224             : 
     225           0 :     if (ret == EOK) {
     226           0 :         tevent_req_done(req);
     227             :     } else {
     228           0 :         tevent_req_error(req, ret);
     229             :     }
     230             : 
     231           0 :     return;
     232             : }
     233             : 
     234           0 : static int sdap_async_sys_connect_recv(struct tevent_req *req)
     235             : {
     236           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     237             : 
     238           0 :     return EOK;
     239             : }
     240             : 
     241           0 : static errno_t set_fd_flags_and_opts(int fd)
     242             : {
     243             :     int ret;
     244             :     long flags;
     245           0 :     int dummy = 1;
     246             : 
     247           0 :     flags = fcntl(fd, F_GETFD, 0);
     248           0 :     if (flags == -1) {
     249           0 :         ret = errno;
     250           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     251             :               "fcntl F_GETFD failed [%d][%s].\n", ret, strerror(ret));
     252           0 :         return ret;
     253             :     }
     254             : 
     255           0 :     flags = fcntl(fd, F_SETFD, flags| FD_CLOEXEC);
     256           0 :     if (flags == -1) {
     257           0 :         ret = errno;
     258           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     259             :               "fcntl F_SETFD failed [%d][%s].\n", ret, strerror(ret));
     260           0 :         return ret;
     261             :     }
     262             : 
     263             :     /* SO_KEEPALIVE and TCP_NODELAY are set by OpenLDAP client libraries but
     264             :      * failures are ignored.*/
     265           0 :     ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &dummy, sizeof(dummy));
     266           0 :     if (ret != 0) {
     267           0 :         ret = errno;
     268           0 :         DEBUG(SSSDBG_FUNC_DATA,
     269             :               "setsockopt SO_KEEPALIVE failed.[%d][%s].\n", ret,
     270             :                   strerror(ret));
     271             :     }
     272             : 
     273           0 :     ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &dummy, sizeof(dummy));
     274           0 :     if (ret != 0) {
     275           0 :         ret = errno;
     276           0 :         DEBUG(SSSDBG_FUNC_DATA,
     277             :               "setsockopt TCP_NODELAY failed.[%d][%s].\n", ret,
     278             :                   strerror(ret));
     279             :     }
     280             : 
     281           0 :     return EOK;
     282             : }
     283             : 
     284             : #define LDAP_PROTO_TCP 1 /* ldap://  */
     285             : #define LDAP_PROTO_UDP 2 /* reserved */
     286             : #define LDAP_PROTO_IPC 3 /* ldapi:// */
     287             : #define LDAP_PROTO_EXT 4 /* user-defined socket/sockbuf */
     288             : 
     289             : extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, LDAP **ld);
     290             : 
     291             : static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq);
     292             : static void sdap_async_sys_connect_timeout(struct tevent_context *ev,
     293             :                                            struct tevent_timer *te,
     294             :                                            struct timeval tv, void *pvt);
     295             : #endif
     296             : 
     297             : struct sss_ldap_init_state {
     298             :     LDAP *ldap;
     299             :     int sd;
     300             :     const char *uri;
     301             : 
     302             : #ifdef HAVE_LDAP_INIT_FD
     303             :     struct tevent_timer *connect_timeout;
     304             : #endif
     305             : };
     306             : 
     307             : 
     308           0 : struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx,
     309             :                                       struct tevent_context *ev,
     310             :                                       const char *uri,
     311             :                                       struct sockaddr_storage *addr,
     312             :                                       int addr_len, int timeout)
     313             : {
     314           0 :     int ret = EOK;
     315             :     struct tevent_req *req;
     316             :     struct sss_ldap_init_state *state;
     317             : 
     318           0 :     req = tevent_req_create(mem_ctx, &state, struct sss_ldap_init_state);
     319           0 :     if (req == NULL) {
     320           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n");
     321           0 :         return NULL;
     322             :     }
     323             : 
     324           0 :     state->ldap = NULL;
     325           0 :     state->uri = uri;
     326             : 
     327             : #ifdef HAVE_LDAP_INIT_FD
     328             :     struct tevent_req *subreq;
     329             :     struct timeval tv;
     330             : 
     331           0 :     state->sd = socket(addr->ss_family, SOCK_STREAM, 0);
     332           0 :     if (state->sd == -1) {
     333           0 :         ret = errno;
     334           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     335             :               "socket failed [%d][%s].\n", ret, strerror(ret));
     336           0 :         goto fail;
     337             :     }
     338             : 
     339           0 :     ret = set_fd_flags_and_opts(state->sd);
     340           0 :     if (ret != EOK) {
     341           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "set_fd_flags_and_opts failed.\n");
     342           0 :         goto fail;
     343             :     }
     344             : 
     345           0 :     DEBUG(SSSDBG_TRACE_ALL,
     346             :           "Using file descriptor [%d] for LDAP connection.\n", state->sd);
     347             : 
     348           0 :     subreq = sdap_async_sys_connect_send(state, ev, state->sd,
     349             :                                          (struct sockaddr *) addr, addr_len);
     350           0 :     if (subreq == NULL) {
     351           0 :         ret = ENOMEM;
     352           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sdap_async_sys_connect_send failed.\n");
     353           0 :         goto fail;
     354             :     }
     355             : 
     356           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     357             :           "Setting %d seconds timeout for connecting\n", timeout);
     358           0 :     tv = tevent_timeval_current_ofs(timeout, 0);
     359             : 
     360           0 :     state->connect_timeout = tevent_add_timer(ev, subreq, tv,
     361             :                                               sdap_async_sys_connect_timeout,
     362             :                                               subreq);
     363           0 :     if (state->connect_timeout == NULL) {
     364           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n");
     365           0 :         ret = ENOMEM;
     366           0 :         goto fail;
     367             :     }
     368             : 
     369           0 :     tevent_req_set_callback(subreq, sss_ldap_init_sys_connect_done, req);
     370           0 :     return req;
     371             : 
     372             : fail:
     373           0 :     if(state->sd >= 0) {
     374           0 :         close(state->sd);
     375             :     }
     376           0 :     tevent_req_error(req, ret);
     377             : #else
     378             :     DEBUG(SSSDBG_MINOR_FAILURE, "ldap_init_fd not available, "
     379             :               "will use ldap_initialize with uri [%s].\n", uri);
     380             :     state->sd = -1;
     381             :     ret = ldap_initialize(&state->ldap, uri);
     382             :     if (ret == LDAP_SUCCESS) {
     383             :         tevent_req_done(req);
     384             :     } else {
     385             :         DEBUG(SSSDBG_CRIT_FAILURE,
     386             :               "ldap_initialize failed [%s].\n", sss_ldap_err2string(ret));
     387             :         if (ret == LDAP_SERVER_DOWN) {
     388             :             tevent_req_error(req, ETIMEDOUT);
     389             :         } else {
     390             :             tevent_req_error(req, EIO);
     391             :         }
     392             :     }
     393             : #endif
     394             : 
     395           0 :     tevent_req_post(req, ev);
     396           0 :     return req;
     397             : }
     398             : 
     399             : #ifdef HAVE_LDAP_INIT_FD
     400           0 : static void sdap_async_sys_connect_timeout(struct tevent_context *ev,
     401             :                                            struct tevent_timer *te,
     402             :                                            struct timeval tv, void *pvt)
     403             : {
     404             :     struct tevent_req *connection_request;
     405             : 
     406           0 :     DEBUG(SSSDBG_CONF_SETTINGS, "The LDAP connection timed out\n");
     407             : 
     408           0 :     connection_request = talloc_get_type(pvt, struct tevent_req);
     409           0 :     tevent_req_error(connection_request, ETIMEDOUT);
     410           0 : }
     411             : 
     412           0 : static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
     413             : {
     414           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     415             :                                                       struct tevent_req);
     416           0 :     struct sss_ldap_init_state *state = tevent_req_data(req,
     417             :                                                     struct sss_ldap_init_state);
     418             :     int ret;
     419             :     int lret;
     420             : 
     421           0 :     talloc_zfree(state->connect_timeout);
     422             : 
     423           0 :     ret = sdap_async_sys_connect_recv(subreq);
     424           0 :     talloc_zfree(subreq);
     425           0 :     if (ret != EOK) {
     426           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     427             :               "sdap_async_sys_connect request failed: [%d]: %s.\n",
     428             :               ret, sss_strerror(ret));
     429           0 :         goto fail;
     430             :     }
     431             :     /* Initialize LDAP handler */
     432             : 
     433           0 :     lret = ldap_init_fd(state->sd, LDAP_PROTO_TCP, state->uri, &state->ldap);
     434           0 :     if (lret != LDAP_SUCCESS) {
     435           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     436             :               "ldap_init_fd failed: %s. [%d][%s]\n",
     437             :                sss_ldap_err2string(lret), state->sd, state->uri);
     438           0 :         ret = lret == LDAP_SERVER_DOWN ? ETIMEDOUT : EIO;
     439           0 :         goto fail;
     440             :     }
     441             : 
     442           0 :     if (ldap_is_ldaps_url(state->uri)) {
     443           0 :         lret = ldap_install_tls(state->ldap);
     444           0 :         if (lret != LDAP_SUCCESS) {
     445           0 :             if (lret == LDAP_LOCAL_ERROR) {
     446           0 :                 DEBUG(SSSDBG_FUNC_DATA, "TLS/SSL already in place.\n");
     447             :             } else {
     448           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "ldap_install_tls failed: %s\n",
     449             :                           sss_ldap_err2string(lret));
     450           0 :                 ret = EIO;
     451           0 :                 goto fail;
     452             :             }
     453             :         }
     454             :     }
     455             : 
     456           0 :     tevent_req_done(req);
     457           0 :     return;
     458             : 
     459             : fail:
     460           0 :     if (state->ldap) {
     461           0 :         ldap_unbind_ext(state->ldap, NULL, NULL);
     462             :     } else {
     463           0 :         close(state->sd);
     464             :     }
     465           0 :     tevent_req_error(req, ret);
     466             : }
     467             : #endif
     468             : 
     469           0 : int sss_ldap_init_recv(struct tevent_req *req, LDAP **ldap, int *sd)
     470             : {
     471           0 :     struct sss_ldap_init_state *state = tevent_req_data(req,
     472             :                                                     struct sss_ldap_init_state);
     473           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     474             : 
     475           0 :     *ldap = state->ldap;
     476           0 :     *sd = state->sd;
     477             : 
     478           0 :     return EOK;
     479             : }
     480             : 
     481             : /*
     482             :  * _filter will contain combined filters from all possible search bases
     483             :  * or NULL if it should be empty
     484             :  */
     485             : 
     486             : 
     487          94 : bool sss_ldap_dn_in_search_bases_len(TALLOC_CTX *mem_ctx,
     488             :                                      const char *dn,
     489             :                                      struct sdap_search_base **search_bases,
     490             :                                      char **_filter,
     491             :                                      int *_match_len)
     492             : {
     493             :     struct sdap_search_base *base;
     494             :     int basedn_len, dn_len;
     495             :     int len_diff;
     496             :     int i, j;
     497          94 :     bool base_confirmed = false;
     498          94 :     bool comma_found = false;
     499          94 :     bool backslash_found = false;
     500          94 :     char *filter = NULL;
     501          94 :     bool ret = false;
     502             :     int match_len;
     503             : 
     504          94 :     if (dn == NULL) {
     505           0 :         DEBUG(SSSDBG_FUNC_DATA, "dn is NULL\n");
     506           0 :         ret = false;
     507           0 :         goto done;
     508             :     }
     509             : 
     510          94 :     if (search_bases == NULL) {
     511          30 :         DEBUG(SSSDBG_FUNC_DATA, "search_bases is NULL\n");
     512          30 :         ret = false;
     513          30 :         goto done;
     514             :     }
     515             : 
     516          64 :     dn_len = strlen(dn);
     517          87 :     for (i = 0; search_bases[i] != NULL; i++) {
     518          65 :         base = search_bases[i];
     519          65 :         basedn_len = strlen(base->basedn);
     520             : 
     521          65 :         if (basedn_len > dn_len) {
     522           0 :             continue;
     523             :         }
     524             : 
     525          65 :         len_diff = dn_len - basedn_len;
     526          65 :         base_confirmed = (strncasecmp(&dn[len_diff], base->basedn, basedn_len) == 0);
     527          65 :         if (!base_confirmed) {
     528          23 :             continue;
     529             :         }
     530          42 :         match_len = basedn_len;
     531             : 
     532          42 :         switch (base->scope) {
     533             :         case LDAP_SCOPE_BASE:
     534             :             /* dn > base? */
     535           0 :             if (len_diff != 0) {
     536           0 :                 continue;
     537             :             }
     538           0 :             break;
     539             :         case LDAP_SCOPE_ONELEVEL:
     540           0 :             if (len_diff == 0) {
     541             :                 /* Base object doesn't belong to scope=one
     542             :                  * search */
     543           0 :                 continue;
     544             :             }
     545             : 
     546           0 :             comma_found = false;
     547           0 :             for (j = 0; j < len_diff - 1; j++) { /* ignore comma before base */
     548           0 :                 if (dn[j] == '\\') {
     549           0 :                     backslash_found = true;
     550           0 :                 } else if (dn[j] == ',' && !backslash_found) {
     551           0 :                     comma_found = true;
     552           0 :                     break;
     553             :                 } else {
     554           0 :                     backslash_found = false;
     555             :                 }
     556             :             }
     557             : 
     558             :             /* it has at least one more level */
     559           0 :             if (comma_found) {
     560           0 :                 continue;
     561             :             }
     562             : 
     563           0 :             break;
     564             :         case LDAP_SCOPE_SUBTREE:
     565             :             /* dn length >= base dn length && base_confirmed == true */
     566          42 :             break;
     567             :         default:
     568           0 :             DEBUG(SSSDBG_FUNC_DATA, "Unsupported scope: %d\n", base->scope);
     569           0 :             continue;
     570             :         }
     571             : 
     572             :         /*
     573             :          *  If we get here, the dn is valid.
     574             :          *  If no filter is set, than return true immediately.
     575             :          *  Append filter otherwise.
     576             :          */
     577          42 :         ret = true;
     578          42 :         if (_match_len) {
     579          25 :             *_match_len = match_len;
     580             :         }
     581             : 
     582          42 :         if (base->filter == NULL || _filter == NULL) {
     583             :             goto done;
     584             :         } else {
     585           0 :             filter = talloc_strdup_append(filter, base->filter);
     586           0 :             if (filter == NULL) {
     587           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup_append() failed\n");
     588           0 :                 ret = false;
     589           0 :                 goto done;
     590             :             }
     591             :         }
     592             :     }
     593             : 
     594          22 :     if (_filter != NULL) {
     595          16 :         if (filter != NULL) {
     596           0 :             *_filter = talloc_asprintf(mem_ctx, "(|%s)", filter);
     597           0 :             if (*_filter == NULL) {
     598           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     599             :                       "talloc_asprintf_append() failed\n");
     600           0 :                 ret = false;
     601           0 :                 goto done;
     602             :             }
     603             :         } else {
     604          16 :             *_filter = NULL;
     605             :         }
     606             :     }
     607             : 
     608             : done:
     609          94 :     talloc_free(filter);
     610          94 :     return ret;
     611             : }
     612             : 
     613          34 : bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
     614             :                                  const char *dn,
     615             :                                  struct sdap_search_base **search_bases,
     616             :                                  char **_filter)
     617             : {
     618          34 :     return sss_ldap_dn_in_search_bases_len(mem_ctx, dn, search_bases, _filter,
     619             :                                            NULL);
     620             : }
     621             : 
     622           0 : char *sss_ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t flags)
     623             : {
     624             :     char hex[9]; /* 4 bytes in hex + terminating zero */
     625             :     errno_t ret;
     626             : 
     627           0 :     ret = snprintf(hex, 9, "%08x", flags);
     628           0 :     if (ret != 8) {
     629           0 :         return NULL;
     630             :     }
     631             : 
     632           0 :     return talloc_asprintf(mem_ctx, "\\%c%c\\%c%c\\%c%c\\%c%c",
     633           0 :                            hex[6], hex[7], hex[4], hex[5],
     634           0 :                            hex[2], hex[3], hex[0], hex[1]);
     635             : }

Generated by: LCOV version 1.10