"Fossies" - the Fresh Open Source Software Archive

Member "sssd-2.4.2/src/responder/common/responder_common.c" (19 Feb 2021, 58889 Bytes) of package /linux/misc/sssd-2.4.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "responder_common.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.1_vs_2.4.2.

    1 /*
    2    SSSD
    3 
    4    Common Responder methods
    5 
    6    Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
    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 "config.h"
   23 
   24 #include <stdio.h>
   25 #include <sys/types.h>
   26 #include <sys/stat.h>
   27 #include <sys/socket.h>
   28 #include <sys/un.h>
   29 #include <string.h>
   30 #include <sys/time.h>
   31 #include <errno.h>
   32 #include <fcntl.h>
   33 #include <popt.h>
   34 #include <dbus/dbus.h>
   35 
   36 #include "util/util.h"
   37 #include "util/strtonum.h"
   38 #include "db/sysdb.h"
   39 #include "confdb/confdb.h"
   40 #include "responder/common/responder.h"
   41 #include "responder/common/responder_packet.h"
   42 #include "providers/data_provider.h"
   43 #include "util/util_creds.h"
   44 #include "sss_iface/sss_iface_async.h"
   45 
   46 #ifdef HAVE_SYSTEMD
   47 #include <systemd/sd-daemon.h>
   48 #endif
   49 
   50 #define SHELL_REALLOC_INCREMENT 5
   51 #define SHELL_REALLOC_MAX       50
   52 
   53 static errno_t set_close_on_exec(int fd)
   54 {
   55     int v;
   56     int ferr;
   57     errno_t error;
   58 
   59     /* Get the current flags for this file descriptor */
   60     v = fcntl(fd, F_GETFD, 0);
   61 
   62     errno = 0;
   63     /* Set the close-on-exec flags on this fd */
   64     ferr = fcntl(fd, F_SETFD, v | FD_CLOEXEC);
   65     if (ferr < 0) {
   66         error = errno;
   67         DEBUG(SSSDBG_FATAL_FAILURE,
   68               "Unable to set fd close-on-exec: [%d][%s]\n",
   69                   error, strerror(error));
   70         return error;
   71     }
   72     return EOK;
   73 }
   74 
   75 static void client_close_fn(struct tevent_context *ev,
   76                             struct tevent_fd *fde, int fd,
   77                             void *ptr)
   78 {
   79     errno_t ret;
   80     struct cli_ctx *ctx = talloc_get_type(ptr, struct cli_ctx);
   81 
   82     if ((ctx->cfd > 0) && close(ctx->cfd) < 0) {
   83         ret = errno;
   84         DEBUG(SSSDBG_CRIT_FAILURE,
   85               "Failed to close fd [%d]: [%s]\n",
   86                ctx->cfd, strerror(ret));
   87     }
   88 
   89     DEBUG(SSSDBG_TRACE_INTERNAL,
   90           "Terminated client [%p][%d]\n",
   91            ctx, ctx->cfd);
   92 
   93     ctx->cfd = -1;
   94 }
   95 
   96 static errno_t get_client_cred(struct cli_ctx *cctx)
   97 {
   98     SEC_CTX secctx;
   99     int ret;
  100 
  101     cctx->creds = talloc_zero(cctx, struct cli_creds);
  102     if (!cctx->creds) return ENOMEM;
  103 
  104 #ifdef HAVE_UCRED
  105     socklen_t client_cred_len = sizeof(struct ucred);
  106     char proc_path[32];
  107     char cmd_line[255] = { 0 };
  108     int proc_fd;
  109 
  110     cctx->creds->ucred.uid = -1;
  111     cctx->creds->ucred.gid = -1;
  112     cctx->creds->ucred.pid = -1;
  113 
  114     ret = getsockopt(cctx->cfd, SOL_SOCKET, SO_PEERCRED, &cctx->creds->ucred,
  115                      &client_cred_len);
  116     if (ret != EOK) {
  117         ret = errno;
  118         DEBUG(SSSDBG_CRIT_FAILURE,
  119               "getsockopt failed [%d][%s].\n", ret, strerror(ret));
  120         return ret;
  121     }
  122     if (client_cred_len != sizeof(struct ucred)) {
  123         DEBUG(SSSDBG_CRIT_FAILURE,
  124               "getsockopt returned unexpected message size.\n");
  125         return ENOMSG;
  126     }
  127 
  128     if (cctx->creds->ucred.pid > -1) {
  129         snprintf(proc_path, sizeof(proc_path), "/proc/%d/cmdline",
  130                  (int)cctx->creds->ucred.pid);
  131         proc_fd = open(proc_path, O_RDONLY);
  132         if (proc_fd != -1) {
  133             if (sss_fd_nonblocking(proc_fd) == EOK) {
  134                 ret = read(proc_fd, cmd_line, sizeof(cmd_line)-1);
  135                 if (ret > 0) {
  136                     cmd_line[ret] = 0;
  137                 }
  138             }
  139             close(proc_fd);
  140         }
  141     }
  142 
  143     DEBUG(SSSDBG_TRACE_ALL,
  144           "Client [%p][%d] creds: euid[%d] egid[%d] pid[%d] cmd_line['%s'].\n",
  145           cctx, cctx->cfd,
  146           cctx->creds->ucred.uid, cctx->creds->ucred.gid,
  147           cctx->creds->ucred.pid, cmd_line);
  148 #endif
  149 
  150     ret = SELINUX_getpeercon(cctx->cfd, &secctx);
  151     if (ret != 0) {
  152         ret = errno;
  153         DEBUG(SSSDBG_MINOR_FAILURE,
  154               "The following failure is expected to happen in case SELinux is disabled:\n"
  155               "SELINUX_getpeercon failed [%d][%s].\n"
  156               "Please, consider enabling SELinux in your system.\n", ret, strerror(ret));
  157         /* This is not fatal, as SELinux may simply be disabled */
  158         ret = EOK;
  159     } else {
  160         cctx->creds->selinux_ctx = SELINUX_context_new(secctx);
  161         SELINUX_freecon(secctx);
  162     }
  163 
  164     return ret;
  165 }
  166 
  167 uid_t client_euid(struct cli_creds *creds)
  168 {
  169     if (!creds) return -1;
  170     return cli_creds_get_uid(creds);
  171 }
  172 
  173 errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count,
  174                            uid_t *allowed_uids)
  175 {
  176     size_t c;
  177 
  178     if (allowed_uids == NULL) {
  179         return EINVAL;
  180     }
  181 
  182     for (c = 0; c < allowed_uids_count; c++) {
  183         if (uid == allowed_uids[c]) {
  184             return EOK;
  185         }
  186     }
  187 
  188     return EACCES;
  189 }
  190 
  191 errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *csv_string,
  192                                 bool allow_sss_loop,
  193                                 size_t *_uid_count, uid_t **_uids)
  194 {
  195     int ret;
  196     size_t c;
  197     char **list = NULL;
  198     int list_size;
  199     uid_t *uids = NULL;
  200     char *endptr;
  201 
  202     ret = split_on_separator(mem_ctx, csv_string, ',', true, false,
  203                              &list, &list_size);
  204     if (ret != EOK) {
  205         DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed [%d][%s].\n",
  206                                   ret, strerror(ret));
  207         goto done;
  208     }
  209 
  210     uids = talloc_array(mem_ctx, uint32_t, list_size);
  211     if (uids == NULL) {
  212         DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
  213         ret = ENOMEM;
  214         goto done;
  215     }
  216 
  217     if (allow_sss_loop) {
  218         ret = unsetenv("_SSS_LOOPS");
  219         if (ret != EOK) {
  220             DEBUG(SSSDBG_OP_FAILURE, "Failed to unset _SSS_LOOPS, getpwnam "
  221                                       "might not find sssd users.\n");
  222         }
  223     }
  224 
  225     for (c = 0; c < list_size; c++) {
  226         errno = 0;
  227         if (*list[c] == '\0') {
  228             DEBUG(SSSDBG_OP_FAILURE, "Empty list item.\n");
  229             ret = EINVAL;
  230             goto done;
  231         }
  232 
  233         uids[c] = strtouint32(list[c], &endptr, 10);
  234         if (errno != 0 || *endptr != '\0') {
  235             ret = errno;
  236             if (ret == ERANGE) {
  237                 DEBUG(SSSDBG_OP_FAILURE, "List item [%s] is out of range.\n",
  238                                           list[c]);
  239                 goto done;
  240             }
  241 
  242             ret = sss_user_by_name_or_uid(list[c], &uids[c], NULL);
  243             if (ret != EOK) {
  244                 DEBUG(SSSDBG_OP_FAILURE, "List item [%s] is neither a valid "
  245                                          "UID nor a user name which could be "
  246                                          "resolved by getpwnam().\n", list[c]);
  247                 sss_log(SSS_LOG_WARNING, "List item [%s] is neither a valid "
  248                                          "UID nor a user name which could be "
  249                                          "resolved by getpwnam().\n", list[c]);
  250                 goto done;
  251             }
  252         }
  253     }
  254 
  255     *_uid_count = list_size;
  256     *_uids = uids;
  257 
  258     ret = EOK;
  259 
  260 done:
  261     if(setenv("_SSS_LOOPS", "NO", 0) != 0) {
  262         DEBUG(SSSDBG_OP_FAILURE, "Failed to set _SSS_LOOPS.\n");
  263     }
  264     talloc_free(list);
  265     if (ret != EOK) {
  266         talloc_free(uids);
  267     }
  268 
  269     return ret;
  270 }
  271 
  272 static void client_send(struct cli_ctx *cctx)
  273 {
  274     struct cli_protocol *pctx;
  275     int ret;
  276 
  277     pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol);
  278 
  279     ret = sss_packet_send(pctx->creq->out, cctx->cfd);
  280     if (ret == EAGAIN) {
  281         /* not all data was sent, loop again */
  282         return;
  283     }
  284     if (ret != EOK) {
  285         DEBUG(SSSDBG_FATAL_FAILURE, "Failed to send data, aborting client!\n");
  286         talloc_free(cctx);
  287         return;
  288     }
  289 
  290     /* ok all sent */
  291     TEVENT_FD_NOT_WRITEABLE(cctx->cfde);
  292     TEVENT_FD_READABLE(cctx->cfde);
  293     talloc_zfree(pctx->creq);
  294     return;
  295 }
  296 
  297 static int client_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds)
  298 {
  299     struct cli_protocol *pctx;
  300     enum sss_cli_command cmd;
  301 
  302     pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol);
  303     cmd = sss_packet_get_cmd(pctx->creq->in);
  304     return sss_cmd_execute(cctx, cmd, sss_cmds);
  305 }
  306 
  307 static void client_recv(struct cli_ctx *cctx)
  308 {
  309     struct cli_protocol *pctx;
  310     int ret;
  311 
  312     pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol);
  313 
  314     if (!pctx->creq) {
  315         pctx->creq = talloc_zero(cctx, struct cli_request);
  316         if (!pctx->creq) {
  317             DEBUG(SSSDBG_FATAL_FAILURE,
  318                   "Failed to alloc request, aborting client!\n");
  319             talloc_free(cctx);
  320             return;
  321         }
  322     }
  323 
  324     if (!pctx->creq->in) {
  325         ret = sss_packet_new(pctx->creq, SSS_PACKET_MAX_RECV_SIZE,
  326                              0, &pctx->creq->in);
  327         if (ret != EOK) {
  328             DEBUG(SSSDBG_FATAL_FAILURE,
  329                   "Failed to alloc request, aborting client!\n");
  330             talloc_free(cctx);
  331             return;
  332         }
  333     }
  334 
  335     ret = sss_packet_recv(pctx->creq->in, cctx->cfd);
  336     switch (ret) {
  337     case EOK:
  338         /* do not read anymore */
  339         TEVENT_FD_NOT_READABLE(cctx->cfde);
  340         /* execute command */
  341         ret = client_cmd_execute(cctx, cctx->rctx->sss_cmds);
  342         if (ret != EOK) {
  343             DEBUG(SSSDBG_FATAL_FAILURE,
  344                   "Failed to execute request, aborting client!\n");
  345             talloc_free(cctx);
  346         }
  347         /* past this point cctx can be freed at any time by callbacks
  348          * in case of error, do not use it */
  349         return;
  350 
  351     case EAGAIN:
  352         /* need to read still some data, loop again */
  353         break;
  354 
  355     case EINVAL:
  356         DEBUG(SSSDBG_TRACE_FUNC,
  357               "Invalid data from client, closing connection!\n");
  358         talloc_free(cctx);
  359         break;
  360 
  361     case ENODATA:
  362         DEBUG(SSSDBG_FUNC_DATA, "Client disconnected!\n");
  363         talloc_free(cctx);
  364         break;
  365 
  366     default:
  367         DEBUG(SSSDBG_TRACE_FUNC, "Failed to read request, aborting client!\n");
  368         talloc_free(cctx);
  369     }
  370 
  371     return;
  372 }
  373 
  374 static errno_t schedule_responder_idle_timer(struct resp_ctx *rctx);
  375 
  376 static void responder_idle_handler(struct tevent_context *ev,
  377                                    struct tevent_timer *te,
  378                                    struct timeval current_time,
  379                                    void *data)
  380 {
  381     struct resp_ctx *rctx;
  382     time_t now;
  383 
  384     rctx = talloc_get_type(data, struct resp_ctx);
  385 
  386     now = time(NULL);
  387     if (rctx->last_request_time > now) {
  388         DEBUG(SSSDBG_IMPORTANT_INFO,
  389               "Time shift detected, re-scheduling the responder timeout\n");
  390         goto end;
  391     }
  392 
  393     if ((now - rctx->last_request_time) > rctx->idle_timeout) {
  394         /* This responder is idle. Terminate it */
  395         DEBUG(SSSDBG_TRACE_INTERNAL,
  396               "Terminating idle responder [%p]\n", rctx);
  397 
  398         talloc_free(rctx);
  399 
  400         orderly_shutdown(0);
  401     }
  402 
  403     DEBUG(SSSDBG_TRACE_INTERNAL,
  404           "Re-scheduling the idle timeout for the responder [%p]\n", rctx);
  405 
  406 end:
  407     schedule_responder_idle_timer(rctx);
  408 }
  409 
  410 static errno_t schedule_responder_idle_timer(struct resp_ctx *rctx)
  411 {
  412     struct timeval tv;
  413 
  414     tv = tevent_timeval_current_ofs(rctx->idle_timeout / 2, 0);
  415 
  416     talloc_zfree(rctx->idle);
  417     rctx->idle = tevent_add_timer(rctx->ev,
  418                                   rctx,
  419                                   tv,
  420                                   responder_idle_handler,
  421                                   rctx);
  422     if (rctx->idle == NULL) {
  423         DEBUG(SSSDBG_CRIT_FAILURE,
  424               "Failed to allocate time event: responder [%p] shutdown timeout\n",
  425               rctx);
  426         return ENOMEM;
  427     }
  428 
  429     DEBUG(SSSDBG_TRACE_INTERNAL,
  430           "Re-scheduling the idle timeout for the responder [%p]\n", rctx);
  431 
  432     return EOK;
  433 }
  434 
  435 static errno_t setup_responder_idle_timer(struct resp_ctx *rctx)
  436 {
  437     errno_t ret;
  438 
  439     rctx->last_request_time = time(NULL);
  440 
  441     ret = schedule_responder_idle_timer(rctx);
  442     if (ret != EOK) {
  443         DEBUG(SSSDBG_TRACE_INTERNAL,
  444               "Error scheduling the idle timeout for the responder [%p]: "
  445               "%d [%s]\n",
  446               rctx, ret, sss_strerror(ret));
  447         return ret;
  448     }
  449 
  450     DEBUG(SSSDBG_TRACE_INTERNAL,
  451           "Setting up the idle timeout for the responder [%p]\n", rctx);
  452 
  453     return EOK;
  454 }
  455 
  456 static void client_fd_handler(struct tevent_context *ev,
  457                               struct tevent_fd *fde,
  458                               uint16_t flags, void *ptr)
  459 {
  460     sss_client_fd_handler(ptr, client_recv, client_send, flags);
  461 }
  462 
  463 static errno_t setup_client_idle_timer(struct cli_ctx *cctx);
  464 
  465 static int cli_ctx_destructor(struct cli_ctx *cctx)
  466 {
  467     if (cctx->creds == NULL) {
  468         return 0;
  469     }
  470 
  471     if (cctx->creds->selinux_ctx == NULL) {
  472         return 0;
  473     }
  474 
  475     SELINUX_context_free(cctx->creds->selinux_ctx);
  476     cctx->creds->selinux_ctx = NULL;
  477 
  478     return 0;
  479 }
  480 
  481 struct accept_fd_ctx {
  482     struct resp_ctx *rctx;
  483     bool is_private;
  484     connection_setup_t connection_setup;
  485 };
  486 
  487 /*
  488  * Use this function only before the client context is established
  489  */
  490 static void accept_and_terminate_cli(int fd)
  491 {
  492     struct sockaddr_un addr;
  493     int client_fd;
  494     socklen_t len;
  495 
  496     /* accept and close to signal the client we have a problem */
  497     memset(&addr, 0, sizeof(addr));
  498     len = sizeof(addr);
  499     client_fd = accept(fd, (struct sockaddr *)&addr, &len);
  500     if (client_fd == -1) {
  501         return;
  502     }
  503     close(client_fd);
  504     return;
  505 }
  506 
  507 static void accept_fd_handler(struct tevent_context *ev,
  508                               struct tevent_fd *fde,
  509                               uint16_t flags, void *ptr)
  510 {
  511     /* accept and attach new event handler */
  512     struct accept_fd_ctx *accept_ctx =
  513             talloc_get_type(ptr, struct accept_fd_ctx);
  514     struct resp_ctx *rctx = accept_ctx->rctx;
  515     struct cli_ctx *cctx;
  516     socklen_t len;
  517     struct stat stat_buf;
  518     int ret;
  519     int fd = accept_ctx->is_private ? rctx->priv_lfd : rctx->lfd;
  520 
  521     if (accept_ctx->is_private) {
  522         ret = stat(rctx->priv_sock_name, &stat_buf);
  523         if (ret == -1) {
  524             DEBUG(SSSDBG_CRIT_FAILURE,
  525                   "stat on privileged pipe failed: [%d][%s].\n",
  526                   errno, strerror(errno));
  527             accept_and_terminate_cli(fd);
  528             return;
  529         }
  530 
  531         if ( ! (stat_buf.st_uid == 0 && stat_buf.st_gid == 0 &&
  532                (stat_buf.st_mode&(S_IFSOCK|S_IRUSR|S_IWUSR)) == stat_buf.st_mode)) {
  533             DEBUG(SSSDBG_CRIT_FAILURE,
  534                   "privileged pipe has an illegal status.\n");
  535             accept_and_terminate_cli(fd);
  536             return;
  537         }
  538     }
  539 
  540     cctx = talloc_zero(rctx, struct cli_ctx);
  541     if (!cctx) {
  542         DEBUG(SSSDBG_FATAL_FAILURE,
  543               "Out of memory trying to setup client context%s!\n",
  544               accept_ctx->is_private ? " on privileged pipe": "");
  545         accept_and_terminate_cli(fd);
  546         return;
  547     }
  548 
  549     talloc_set_destructor(cctx, cli_ctx_destructor);
  550 
  551     len = sizeof(cctx->addr);
  552     cctx->cfd = accept(fd, (struct sockaddr *)&cctx->addr, &len);
  553     if (cctx->cfd == -1) {
  554         DEBUG(SSSDBG_CRIT_FAILURE, "Accept failed [%s]\n", strerror(errno));
  555         talloc_free(cctx);
  556         return;
  557     }
  558 
  559     cctx->priv = accept_ctx->is_private;
  560 
  561     ret = get_client_cred(cctx);
  562     if (ret != EOK) {
  563         DEBUG(SSSDBG_OP_FAILURE, "get_client_cred failed, "
  564                   "client cred may not be available.\n");
  565     }
  566 
  567     if (rctx->allowed_uids_count != 0) {
  568         if (client_euid(cctx->creds) == -1) {
  569             DEBUG(SSSDBG_CRIT_FAILURE, "allowed_uids configured, " \
  570                                         "but platform does not support " \
  571                                         "reading peer credential from the " \
  572                                         "socket. Access denied.\n");
  573             close(cctx->cfd);
  574             talloc_free(cctx);
  575             return;
  576         }
  577 
  578         ret = check_allowed_uids(client_euid(cctx->creds), rctx->allowed_uids_count,
  579                                  rctx->allowed_uids);
  580         if (ret != EOK) {
  581             if (ret == EACCES) {
  582                 DEBUG(SSSDBG_CRIT_FAILURE,
  583                       "Access denied for uid [%"SPRIuid"].\n",
  584                       client_euid(cctx->creds));
  585             } else {
  586                 DEBUG(SSSDBG_OP_FAILURE, "check_allowed_uids failed.\n");
  587             }
  588             close(cctx->cfd);
  589             talloc_free(cctx);
  590             return;
  591         }
  592     }
  593 
  594     ret = accept_ctx->connection_setup(cctx);
  595     if (ret != EOK) {
  596         close(cctx->cfd);
  597         talloc_free(cctx);
  598         DEBUG(SSSDBG_OP_FAILURE,
  599               "Failed to setup client handler%s\n",
  600                accept_ctx->is_private ? " on privileged pipe" : "");
  601         return;
  602     }
  603 
  604     cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd,
  605                                TEVENT_FD_READ, cctx->cfd_handler,
  606                                cctx);
  607     if (!cctx->cfde) {
  608         close(cctx->cfd);
  609         talloc_free(cctx);
  610         DEBUG(SSSDBG_OP_FAILURE,
  611               "Failed to queue client handler%s\n",
  612                accept_ctx->is_private ? " on privileged pipe" : "");
  613         return;
  614     }
  615     tevent_fd_set_close_fn(cctx->cfde, client_close_fn);
  616 
  617     cctx->ev = ev;
  618     cctx->rctx = rctx;
  619 
  620     /* Record the new time and set up the idle timer */
  621     ret = reset_client_idle_timer(cctx);
  622     if (ret != EOK) {
  623         DEBUG(SSSDBG_MINOR_FAILURE,
  624               "Could not create idle timer for client. "
  625               "This connection may not auto-terminate\n");
  626         /* Non-fatal, continue */
  627     }
  628 
  629     ret = setup_client_idle_timer(cctx);
  630     if (ret != EOK) {
  631         DEBUG(SSSDBG_CRIT_FAILURE,
  632               "Could not create idle timer for client. "
  633                "This connection may not auto-terminate\n");
  634         /* Non-fatal, continue */
  635     }
  636 
  637     DEBUG(SSSDBG_TRACE_FUNC,
  638           "Client [%p][%d] connected%s!\n",
  639           cctx, cctx->cfd,
  640           accept_ctx->is_private ? " to privileged pipe" : "");
  641 
  642     return;
  643 }
  644 
  645 static void client_idle_handler(struct tevent_context *ev,
  646                                 struct tevent_timer *te,
  647                                 struct timeval current_time,
  648                                 void *data)
  649 {
  650     time_t now = time(NULL);
  651     struct cli_ctx *cctx = talloc_get_type(data, struct cli_ctx);
  652 
  653     if (cctx->last_request_time > now) {
  654         DEBUG(SSSDBG_IMPORTANT_INFO,
  655               "Time shift detected, re-scheduling the client timeout\n");
  656         goto done;
  657     }
  658 
  659     if ((now - cctx->last_request_time) > cctx->rctx->client_idle_timeout) {
  660         /* This connection is idle. Terminate it */
  661         DEBUG(SSSDBG_TRACE_INTERNAL,
  662               "Terminating idle client [%p][%d]\n",
  663               cctx, cctx->cfd);
  664 
  665         /* The cli_ctx destructor will handle the rest */
  666         talloc_free(cctx);
  667         return;
  668     }
  669 
  670 done:
  671     setup_client_idle_timer(cctx);
  672 }
  673 
  674 errno_t reset_client_idle_timer(struct cli_ctx *cctx)
  675 {
  676     cctx->last_request_time = time(NULL);
  677 
  678     return EOK;
  679 }
  680 
  681 static errno_t setup_client_idle_timer(struct cli_ctx *cctx)
  682 {
  683     struct timeval tv =
  684             tevent_timeval_current_ofs(cctx->rctx->client_idle_timeout/2, 0);
  685 
  686     talloc_zfree(cctx->idle);
  687 
  688     cctx->idle = tevent_add_timer(cctx->ev, cctx, tv, client_idle_handler, cctx);
  689     if (!cctx->idle) return ENOMEM;
  690 
  691     DEBUG(SSSDBG_TRACE_ALL,
  692           "Idle timer re-set for client [%p][%d]\n",
  693            cctx, cctx->cfd);
  694 
  695     return EOK;
  696 }
  697 
  698 static void
  699 sss_dp_on_reconnect(struct sbus_connection *conn,
  700                     enum sbus_reconnect_status status,
  701                     struct be_conn *be_conn);
  702 
  703 static void
  704 sss_dp_init_done(struct tevent_req *req);
  705 
  706 static errno_t
  707 sss_dp_init(struct resp_ctx *rctx,
  708             const char *conn_name,
  709             const char *cli_name,
  710             struct sss_domain_info *domain)
  711 {
  712     struct tevent_req *req;
  713     struct be_conn *be_conn;
  714     int max_retries;
  715     errno_t ret;
  716 
  717     ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path,
  718                          CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries);
  719     if (ret != EOK) {
  720         DEBUG(SSSDBG_FATAL_FAILURE, "Unable to read confdb [%d]: %s\n",
  721               ret, sss_strerror(ret));
  722         return ret;
  723     }
  724 
  725     be_conn = talloc_zero(rctx, struct be_conn);
  726     if (!be_conn) return ENOMEM;
  727 
  728     be_conn->cli_name = cli_name;
  729     be_conn->domain = domain;
  730     be_conn->rctx = rctx;
  731 
  732     be_conn->sbus_address = sss_iface_domain_address(be_conn, domain);
  733     if (be_conn->sbus_address == NULL) {
  734         DEBUG(SSSDBG_FATAL_FAILURE, "Could not locate DP address.\n");
  735         ret = ENOMEM;
  736         goto done;
  737     }
  738 
  739     be_conn->bus_name = sss_iface_domain_bus(be_conn, domain);
  740     if (be_conn->bus_name == NULL) {
  741         DEBUG(SSSDBG_FATAL_FAILURE, "Could not locate DP address.\n");
  742         ret = ENOMEM;
  743         goto done;
  744     }
  745 
  746     ret = sss_iface_connect_address(be_conn, rctx->ev, conn_name,
  747                                     be_conn->sbus_address, NULL,
  748                                     &be_conn->conn);
  749     if (ret != EOK) {
  750         DEBUG(SSSDBG_FATAL_FAILURE, "Failed to connect to backend server.\n");
  751         goto done;
  752     }
  753 
  754     ret = sss_resp_register_sbus_iface(be_conn->conn, rctx);
  755     if (ret != EOK) {
  756         DEBUG(SSSDBG_FATAL_FAILURE, "Cannot register generic responder "
  757               "interface [%d]: %s\n", ret, sss_strerror(ret));
  758         goto done;
  759     }
  760 
  761     sbus_reconnect_enable(be_conn->conn, max_retries, sss_dp_on_reconnect,
  762                           be_conn);
  763 
  764     DLIST_ADD_END(rctx->be_conns, be_conn, struct be_conn *);
  765 
  766     /* Identify ourselves to the DP */
  767     req = sbus_call_dp_client_Register_send(be_conn, be_conn->conn,
  768                                             be_conn->bus_name,
  769                                             SSS_BUS_PATH, cli_name);
  770     if (req == NULL) {
  771         ret = ENOMEM;
  772         goto done;
  773     }
  774 
  775     tevent_req_set_callback(req, sss_dp_init_done, be_conn);
  776 
  777     ret = EOK;
  778 
  779 done:
  780     if (ret != EOK) {
  781         talloc_free(be_conn);
  782     }
  783 
  784     return ret;
  785 }
  786 
  787 static void
  788 sss_dp_on_reconnect(struct sbus_connection *conn,
  789                     enum sbus_reconnect_status status,
  790                     struct be_conn *be_conn)
  791 {
  792     struct tevent_req *req;
  793 
  794     if (status != SBUS_RECONNECT_SUCCESS) {
  795         DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n",
  796               be_conn->domain->name);
  797         return;
  798     }
  799 
  800     DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n");
  801 
  802     /* Identify ourselves to the DP */
  803     req = sbus_call_dp_client_Register_send(be_conn, be_conn->conn,
  804                                             be_conn->bus_name,
  805                                             SSS_BUS_PATH,
  806                                             be_conn->cli_name);
  807     if (req == NULL) {
  808         DEBUG(SSSDBG_CRIT_FAILURE, "sbus_call_dp_client_Register_send() failed\n");
  809         return;
  810     }
  811 
  812     tevent_req_set_callback(req, sss_dp_init_done, be_conn);
  813 }
  814 
  815 static void
  816 sss_dp_init_done(struct tevent_req *req)
  817 {
  818     errno_t ret;
  819 
  820     ret = sbus_call_dp_client_Register_recv(req);
  821     talloc_zfree(req);
  822 
  823     if (ret != EOK) {
  824         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to register client with DP\n");
  825         return;
  826     }
  827 
  828     DEBUG(SSSDBG_TRACE_FUNC, "Client is registered with DP\n");
  829 }
  830 
  831 int create_pipe_fd(const char *sock_name, int *_fd, mode_t umaskval)
  832 {
  833     struct sockaddr_un addr;
  834     mode_t orig_umaskval;
  835     errno_t ret;
  836     int fd;
  837 
  838     fd = socket(AF_UNIX, SOCK_STREAM, 0);
  839     if (fd == -1) {
  840         return EIO;
  841     }
  842 
  843     orig_umaskval = umask(umaskval);
  844 
  845     ret = sss_fd_nonblocking(fd);
  846     if (ret != EOK) {
  847         goto done;
  848     }
  849 
  850     ret = set_close_on_exec(fd);
  851     if (ret != EOK) {
  852         goto done;
  853     }
  854 
  855     memset(&addr, 0, sizeof(addr));
  856     addr.sun_family = AF_UNIX;
  857     strncpy(addr.sun_path, sock_name, sizeof(addr.sun_path) - 1);
  858     addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
  859 
  860     /* make sure we have no old sockets around */
  861     ret = unlink(sock_name);
  862     if (ret != 0 && errno != ENOENT) {
  863         ret = errno;
  864         DEBUG(SSSDBG_MINOR_FAILURE,
  865               "Cannot remove old socket (errno=%d [%s]), bind might fail!\n",
  866               ret, sss_strerror(ret));
  867     }
  868 
  869     if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  870         ret = errno;
  871         DEBUG(SSSDBG_FATAL_FAILURE,
  872               "Unable to bind on socket '%s' [%d]: %s\n",
  873               sock_name, ret, sss_strerror(ret));
  874         goto done;
  875     }
  876 
  877     if (listen(fd, 10) == -1) {
  878         ret = errno;
  879         DEBUG(SSSDBG_FATAL_FAILURE,
  880               "Unable to listen on socket '%s' [%d]: %s\n",
  881               sock_name, ret, sss_strerror(ret));
  882         goto done;
  883     }
  884 
  885     ret = EOK;
  886 
  887 done:
  888     /* restore previous umask value */
  889     umask(orig_umaskval);
  890     if (ret == EOK) {
  891         *_fd = fd;
  892     } else {
  893         close(fd);
  894     }
  895     return ret;
  896 }
  897 
  898 /* create a unix socket and listen to it */
  899 static int set_unix_socket(struct resp_ctx *rctx,
  900                            connection_setup_t conn_setup)
  901 {
  902     errno_t ret;
  903     struct accept_fd_ctx *accept_ctx = NULL;
  904 
  905 /* for future use */
  906 #if 0
  907     char *default_pipe;
  908     int ret;
  909 
  910     default_pipe = talloc_asprintf(rctx, "%s/%s", PIPE_PATH,
  911                                    rctx->sss_pipe_name);
  912     if (!default_pipe) {
  913         return ENOMEM;
  914     }
  915 
  916     ret = confdb_get_string(rctx->cdb, rctx,
  917                             rctx->confdb_socket_path, "unixSocket",
  918                             default_pipe, &rctx->sock_name);
  919     if (ret != EOK) {
  920         talloc_free(default_pipe);
  921         return ret;
  922     }
  923     talloc_free(default_pipe);
  924 
  925     default_pipe = talloc_asprintf(rctx, "%s/private/%s", PIPE_PATH,
  926                                    rctx->sss_pipe_name);
  927     if (!default_pipe) {
  928         return ENOMEM;
  929     }
  930 
  931     ret = confdb_get_string(rctx->cdb, rctx,
  932                             rctx->confdb_socket_path, "privUnixSocket",
  933                             default_pipe, &rctx->priv_sock_name);
  934     if (ret != EOK) {
  935         talloc_free(default_pipe);
  936         return ret;
  937     }
  938     talloc_free(default_pipe);
  939 #endif
  940 
  941     if (rctx->sock_name != NULL ) {
  942         /* Set the umask so that permissions are set right on the socket.
  943          * It must be readable and writable by anybody on the system. */
  944         if (rctx->lfd == -1) {
  945             ret = create_pipe_fd(rctx->sock_name, &rctx->lfd, SCKT_RSP_UMASK);
  946             if (ret != EOK) {
  947                 return ret;
  948             }
  949         }
  950 
  951         accept_ctx = talloc_zero(rctx, struct accept_fd_ctx);
  952         if(!accept_ctx) goto failed;
  953         accept_ctx->rctx = rctx;
  954         accept_ctx->is_private = false;
  955         accept_ctx->connection_setup = conn_setup;
  956 
  957         rctx->lfde = tevent_add_fd(rctx->ev, rctx, rctx->lfd,
  958                                    TEVENT_FD_READ, accept_fd_handler,
  959                                    accept_ctx);
  960         if (!rctx->lfde) {
  961             DEBUG(SSSDBG_FATAL_FAILURE, "Failed to queue handler on pipe\n");
  962             goto failed;
  963         }
  964     }
  965 
  966     if (rctx->priv_sock_name != NULL ) {
  967         /* create privileged pipe */
  968         if (rctx->priv_lfd == -1) {
  969             ret = create_pipe_fd(rctx->priv_sock_name, &rctx->priv_lfd,
  970                                  DFL_RSP_UMASK);
  971             if (ret != EOK) {
  972                 goto failed;
  973             }
  974         }
  975 
  976         accept_ctx = talloc_zero(rctx, struct accept_fd_ctx);
  977         if(!accept_ctx) goto failed;
  978         accept_ctx->rctx = rctx;
  979         accept_ctx->is_private = true;
  980         accept_ctx->connection_setup = conn_setup;
  981 
  982         rctx->priv_lfde = tevent_add_fd(rctx->ev, rctx, rctx->priv_lfd,
  983                                    TEVENT_FD_READ, accept_fd_handler,
  984                                    accept_ctx);
  985         if (!rctx->priv_lfde) {
  986             DEBUG(SSSDBG_FATAL_FAILURE,
  987                   "Failed to queue handler on privileged pipe\n");
  988             goto failed;
  989         }
  990     }
  991 
  992     return EOK;
  993 
  994 failed:
  995     if (rctx->lfd >= 0) close(rctx->lfd);
  996     if (rctx->priv_lfd >= 0) close(rctx->priv_lfd);
  997     return EIO;
  998 }
  999 
 1000 int activate_unix_sockets(struct resp_ctx *rctx,
 1001                           connection_setup_t conn_setup)
 1002 {
 1003     int ret;
 1004 
 1005 #ifdef HAVE_SYSTEMD
 1006     struct sockaddr_un sockaddr;
 1007     socklen_t sockaddr_len = sizeof(sockaddr);
 1008 
 1009     if (rctx->lfd == -1 && rctx->priv_lfd == -1) {
 1010         int numfds = (rctx->sock_name ? 1 : 0)
 1011                      + (rctx->priv_sock_name ? 1 : 0);
 1012         /* but if systemd support is available, check if the sockets
 1013          * have been opened for us, via socket activation */
 1014         ret = sd_listen_fds(1);
 1015         if (ret < 0) {
 1016             DEBUG(SSSDBG_MINOR_FAILURE,
 1017                   "Unexpected error probing for active sockets. "
 1018                   "Will proceed with no sockets. [Error %d (%s)]\n",
 1019                   -ret, sss_strerror(-ret));
 1020         } else if (ret > numfds) {
 1021             DEBUG(SSSDBG_FATAL_FAILURE,
 1022                   "Too many activated sockets have been found, "
 1023                   "expected %d, found %d\n", numfds, ret);
 1024             ret = E2BIG;
 1025             goto done;
 1026         }
 1027 
 1028         if (ret == numfds) {
 1029             rctx->lfd = SD_LISTEN_FDS_START;
 1030             ret = sd_is_socket_unix(rctx->lfd, SOCK_STREAM, 1, NULL, 0);
 1031             if (ret < 0) {
 1032                 DEBUG(SSSDBG_CRIT_FAILURE,
 1033                       "Activated socket is not a UNIX listening socket\n");
 1034                 ret = EIO;
 1035                 goto done;
 1036             }
 1037 
 1038             ret = getsockname(rctx->lfd, (struct sockaddr *) &sockaddr, &sockaddr_len);
 1039             if (ret == EOK) {
 1040                 if (memcmp(rctx->sock_name, sockaddr.sun_path, strlen(rctx->sock_name)) != 0) {
 1041                     DEBUG(SSSDBG_CONF_SETTINGS,
 1042                           "Warning: socket path defined in systemd unit (%s) and sssd.conf (%s) don't match\n",
 1043                           sockaddr.sun_path, rctx->sock_name);
 1044                 }
 1045             }
 1046 
 1047             ret = sss_fd_nonblocking(rctx->lfd);
 1048             if (ret != EOK) goto done;
 1049             if (numfds == 2) {
 1050                 rctx->priv_lfd = SD_LISTEN_FDS_START + 1;
 1051                 ret = sd_is_socket_unix(rctx->priv_lfd, SOCK_STREAM, 1, NULL, 0);
 1052                 if (ret < 0) {
 1053                     DEBUG(SSSDBG_CRIT_FAILURE,
 1054                           "Activated priv socket is not a UNIX listening socket\n");
 1055                     ret = EIO;
 1056                     goto done;
 1057                 }
 1058 
 1059                 ret = sss_fd_nonblocking(rctx->priv_lfd);
 1060                 if (ret != EOK) goto done;
 1061             }
 1062         }
 1063     }
 1064 #endif
 1065 
 1066     ret = set_unix_socket(rctx, conn_setup);
 1067     if (ret != EOK) {
 1068         DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error initializing sockets\n");
 1069         goto done;
 1070     }
 1071 
 1072 done:
 1073     return ret;
 1074 }
 1075 
 1076 void sss_client_fd_handler(void *ptr,
 1077                            void (*recv_fn) (struct cli_ctx *cctx),
 1078                            void (*send_fn) (struct cli_ctx *cctx),
 1079                            uint16_t flags)
 1080 {
 1081     errno_t ret;
 1082     struct cli_ctx *cctx = talloc_get_type(ptr, struct cli_ctx);
 1083 
 1084     /* Always reset the responder idle timer on any activity */
 1085     cctx->rctx->last_request_time = time(NULL);
 1086 
 1087     /* Always reset the client idle timer on any activity */
 1088     ret = reset_client_idle_timer(cctx);
 1089     if (ret != EOK) {
 1090         DEBUG(SSSDBG_CRIT_FAILURE,
 1091               "Could not create idle timer for the client. "
 1092               "This connection may not auto-terminate.\n");
 1093         /* Non-fatal, continue */
 1094     }
 1095 
 1096     if (flags & TEVENT_FD_READ) {
 1097         recv_fn(cctx);
 1098         return;
 1099     }
 1100 
 1101     if (flags & TEVENT_FD_WRITE) {
 1102         send_fn(cctx);
 1103         return;
 1104     }
 1105 }
 1106 
 1107 int sss_connection_setup(struct cli_ctx *cctx)
 1108 {
 1109     cctx->protocol_ctx = talloc_zero(cctx, struct cli_protocol);
 1110     if (!cctx->protocol_ctx) {
 1111         return ENOMEM;
 1112     }
 1113 
 1114     cctx->cfd_handler = client_fd_handler;
 1115 
 1116     return EOK;
 1117 }
 1118 
 1119 static int sss_responder_ctx_destructor(void *ptr)
 1120 {
 1121     struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx);
 1122 
 1123     /* mark that we are shutting down the responder, so it is propagated
 1124      * into underlying contexts that are freed right before rctx */
 1125     DEBUG(SSSDBG_TRACE_FUNC, "Responder is being shut down\n");
 1126     rctx->shutting_down = true;
 1127 
 1128     return 0;
 1129 }
 1130 
 1131 static errno_t responder_init_ncache(TALLOC_CTX *mem_ctx,
 1132                                      struct confdb_ctx *cdb,
 1133                                      struct sss_nc_ctx **ncache)
 1134 {
 1135     uint32_t neg_timeout;
 1136     uint32_t locals_timeout;
 1137     int tmp_value;
 1138     int ret;
 1139 
 1140     /* neg_timeout */
 1141     ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
 1142                          CONFDB_NSS_ENTRY_NEG_TIMEOUT,
 1143                          15, &tmp_value);
 1144     if (ret != EOK) {
 1145         DEBUG(SSSDBG_FATAL_FAILURE,
 1146               "Fatal failure of setup negative cache timeout.\n");
 1147         ret = ENOENT;
 1148         goto done;
 1149     }
 1150 
 1151     if (tmp_value < 0) {
 1152         ret = EINVAL;
 1153         goto done;
 1154     }
 1155 
 1156     neg_timeout = tmp_value;
 1157 
 1158     /* local_timeout */
 1159     ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
 1160                          CONFDB_RESPONDER_LOCAL_NEG_TIMEOUT,
 1161                          CONFDB_RESPONDER_LOCAL_NEG_TIMEOUT_DEFAULT,
 1162                          &tmp_value);
 1163     if (ret != EOK) {
 1164         DEBUG(SSSDBG_FATAL_FAILURE,
 1165               "Fatal failure of setup negative cache timeout.\n");
 1166         ret = ENOENT;
 1167         goto done;
 1168     }
 1169 
 1170     if (tmp_value < 0) {
 1171         ret = EINVAL;
 1172         goto done;
 1173     }
 1174 
 1175     locals_timeout = tmp_value;
 1176 
 1177     /* negative cache init */
 1178     ret = sss_ncache_init(mem_ctx, neg_timeout, locals_timeout, ncache);
 1179     if (ret != EOK) {
 1180         DEBUG(SSSDBG_FATAL_FAILURE,
 1181               "Fatal failure of initializing negative cache.\n");
 1182         goto done;
 1183     }
 1184 
 1185     ret = EOK;
 1186 
 1187 done:
 1188     return ret;
 1189 }
 1190 
 1191 static errno_t sss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells)
 1192 {
 1193     int i = 0;
 1194     char *sh;
 1195     char **shells = NULL;
 1196     TALLOC_CTX *tmp_ctx;
 1197     errno_t ret;
 1198     int size;
 1199 
 1200     tmp_ctx = talloc_new(NULL);
 1201     if (!tmp_ctx) return ENOMEM;
 1202 
 1203     shells = talloc_array(tmp_ctx, char *, SHELL_REALLOC_INCREMENT);
 1204     if (!shells) {
 1205         ret = ENOMEM;
 1206         goto done;
 1207     }
 1208     size = SHELL_REALLOC_INCREMENT;
 1209 
 1210     setusershell();
 1211     while ((sh = getusershell())) {
 1212         shells[i] = talloc_strdup(shells, sh);
 1213         if (!shells[i]) {
 1214             endusershell();
 1215             ret = ENOMEM;
 1216             goto done;
 1217         }
 1218         DEBUG(SSSDBG_TRACE_FUNC, "Found shell %s in /etc/shells\n", shells[i]);
 1219         i++;
 1220 
 1221         if (i == size) {
 1222             size += SHELL_REALLOC_INCREMENT;
 1223             if (size > SHELL_REALLOC_MAX) {
 1224                 DEBUG(SSSDBG_FATAL_FAILURE,
 1225                       "Reached maximum number of shells [%d]. "
 1226                           "Users may be denied access. "
 1227                           "Please check /etc/shells for sanity\n",
 1228                           SHELL_REALLOC_MAX);
 1229                 break;
 1230             }
 1231             shells = talloc_realloc(NULL, shells, char *,
 1232                                     size);
 1233             if (!shells) {
 1234                 ret = ENOMEM;
 1235                 goto done;
 1236             }
 1237         }
 1238     }
 1239     endusershell();
 1240 
 1241     if (i + 1 < size) {
 1242         shells = talloc_realloc(NULL, shells, char *, i + 1);
 1243         if (!shells) {
 1244             ret = ENOMEM;
 1245             goto done;
 1246         }
 1247     }
 1248     shells[i] = NULL;
 1249 
 1250     *_shells = talloc_move(mem_ctx, &shells);
 1251     ret = EOK;
 1252 done:
 1253     talloc_zfree(tmp_ctx);
 1254     return ret;
 1255 }
 1256 
 1257 int sss_process_init(TALLOC_CTX *mem_ctx,
 1258                      struct tevent_context *ev,
 1259                      struct confdb_ctx *cdb,
 1260                      struct sss_cmd_table sss_cmds[],
 1261                      const char *sss_pipe_name,
 1262                      int pipe_fd,
 1263                      const char *sss_priv_pipe_name,
 1264                      int priv_pipe_fd,
 1265                      const char *confdb_service_path,
 1266                      const char *conn_name,
 1267                      const char *svc_name,
 1268                      connection_setup_t conn_setup,
 1269                      struct resp_ctx **responder_ctx)
 1270 {
 1271     struct resp_ctx *rctx;
 1272     struct sss_domain_info *dom;
 1273     int ret;
 1274     char *tmp = NULL;
 1275 
 1276     rctx = talloc_zero(mem_ctx, struct resp_ctx);
 1277     if (!rctx) {
 1278         DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing resp_ctx\n");
 1279         return ENOMEM;
 1280     }
 1281     rctx->ev = ev;
 1282     rctx->cdb = cdb;
 1283     rctx->sss_cmds = sss_cmds;
 1284     rctx->sock_name = sss_pipe_name;
 1285     rctx->priv_sock_name = sss_priv_pipe_name;
 1286     rctx->lfd = pipe_fd;
 1287     rctx->priv_lfd = priv_pipe_fd;
 1288     rctx->confdb_service_path = confdb_service_path;
 1289     rctx->shutting_down = false;
 1290     rctx->socket_activated = is_socket_activated();
 1291     rctx->dbus_activated = is_dbus_activated();
 1292 
 1293     talloc_set_destructor((TALLOC_CTX*)rctx, sss_responder_ctx_destructor);
 1294 
 1295     ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path,
 1296                          CONFDB_RESPONDER_CLI_IDLE_TIMEOUT,
 1297                          CONFDB_RESPONDER_CLI_IDLE_DEFAULT_TIMEOUT,
 1298                          &rctx->client_idle_timeout);
 1299     if (ret != EOK) {
 1300         DEBUG(SSSDBG_OP_FAILURE,
 1301               "Cannot get the client idle timeout [%d]: %s\n",
 1302                ret, strerror(ret));
 1303         goto fail;
 1304     }
 1305 
 1306     /* Ensure that the client timeout is at least ten seconds */
 1307     if (rctx->client_idle_timeout < 10) {
 1308         rctx->client_idle_timeout = 10;
 1309     }
 1310 
 1311     if (rctx->socket_activated || rctx->dbus_activated) {
 1312         ret = responder_setup_idle_timeout_config(rctx);
 1313         if (ret != EOK) {
 1314             goto fail;
 1315         }
 1316     }
 1317 
 1318     ret = confdb_get_bool(rctx->cdb, rctx->confdb_service_path,
 1319                           CONFDB_RESPONDER_CACHE_FIRST,
 1320                           false, &rctx->cache_first);
 1321     if (ret != EOK) {
 1322         DEBUG(SSSDBG_OP_FAILURE,
 1323               "Cannot get \"cache_first_option\".\n"
 1324               "Querying the caches first before querying the "
 1325               "Data Providers will not be enforced [%d]: %s.\n",
 1326               ret, sss_strerror(ret));
 1327     }
 1328 
 1329     ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path,
 1330                          CONFDB_RESPONDER_GET_DOMAINS_TIMEOUT,
 1331                          GET_DOMAINS_DEFAULT_TIMEOUT, &rctx->domains_timeout);
 1332     if (ret != EOK) {
 1333         DEBUG(SSSDBG_OP_FAILURE,
 1334               "Cannot get the default domain timeout [%d]: %s\n",
 1335                ret, strerror(ret));
 1336         goto fail;
 1337     }
 1338 
 1339     if (rctx->domains_timeout < 0) {
 1340         DEBUG(SSSDBG_CONF_SETTINGS, "timeout can't be set to negative value, setting default\n");
 1341         rctx->domains_timeout = GET_DOMAINS_DEFAULT_TIMEOUT;
 1342     }
 1343 
 1344     ret = confdb_get_domains(rctx->cdb, &rctx->domains);
 1345     if (ret != EOK) {
 1346         DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up domain map\n");
 1347         goto fail;
 1348     }
 1349 
 1350     ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY,
 1351                             CONFDB_MONITOR_DEFAULT_DOMAIN, NULL,
 1352                             &rctx->default_domain);
 1353     if (ret != EOK) {
 1354         DEBUG(SSSDBG_OP_FAILURE,
 1355               "Cannot get the default domain [%d]: %s\n",
 1356                ret, strerror(ret));
 1357         goto fail;
 1358     }
 1359 
 1360     ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY,
 1361                             CONFDB_MONITOR_OVERRIDE_SPACE, NULL,
 1362                             &tmp);
 1363     if (ret != EOK) {
 1364         DEBUG(SSSDBG_OP_FAILURE,
 1365               "Cannot get the space substitution character [%d]: %s\n",
 1366                ret, strerror(ret));
 1367         goto fail;
 1368     }
 1369 
 1370     if (tmp != NULL) {
 1371         if (strlen(tmp) > 1) {
 1372             DEBUG(SSSDBG_MINOR_FAILURE, "Option %s is longer than 1 character "
 1373                   "only the first character %c will be used\n",
 1374                   CONFDB_MONITOR_OVERRIDE_SPACE, tmp[0]);
 1375         }
 1376 
 1377         rctx->override_space = tmp[0];
 1378     }
 1379 
 1380     ret = confdb_get_string(rctx->cdb, rctx,
 1381                             CONFDB_MONITOR_CONF_ENTRY,
 1382                             CONFDB_MONITOR_DOMAIN_RESOLUTION_ORDER, NULL,
 1383                             &tmp);
 1384     if (ret == EOK) {
 1385         rctx->domain_resolution_order = sss_replace_char(rctx, tmp, ',', ':');
 1386     } else {
 1387         DEBUG(SSSDBG_MINOR_FAILURE,
 1388               "Cannot get the \"domain_resolution_order\" option.\n"
 1389               "The set up lookup_order won't be followed [%d]: %s.\n",
 1390               ret, sss_strerror(ret));
 1391     }
 1392 
 1393     /* Read shell settings */
 1394     ret = confdb_get_string(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
 1395                             CONFDB_NSS_OVERRIDE_SHELL, NULL,
 1396                             &rctx->override_shell);
 1397     if (ret != EOK && ret != ENOENT) goto fail;
 1398 
 1399     ret = confdb_get_string_as_list(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
 1400                                     CONFDB_NSS_ALLOWED_SHELL,
 1401                                     &rctx->allowed_shells);
 1402     if (ret != EOK && ret != ENOENT) goto fail;
 1403 
 1404     ret = confdb_get_string_as_list(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
 1405                                     CONFDB_NSS_VETOED_SHELL,
 1406                                     &rctx->vetoed_shells);
 1407     if (ret != EOK && ret != ENOENT) goto fail;
 1408 
 1409     ret = sss_get_etc_shells(rctx, &rctx->etc_shells);
 1410     if (ret != EOK) goto fail;
 1411 
 1412     ret = confdb_get_string(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
 1413                             CONFDB_NSS_SHELL_FALLBACK,
 1414                             CONFDB_DEFAULT_SHELL_FALLBACK,
 1415                             &rctx->shell_fallback);
 1416     if (ret != EOK) goto fail;
 1417 
 1418     ret = confdb_get_string(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
 1419                             CONFDB_NSS_DEFAULT_SHELL,
 1420                             NULL,
 1421                             &rctx->default_shell);
 1422     if (ret != EOK) goto fail;
 1423 
 1424     /* Read session_recording section */
 1425     ret = session_recording_conf_load(rctx, rctx->cdb, &rctx->sr_conf);
 1426     if (ret != EOK) {
 1427         DEBUG(SSSDBG_OP_FAILURE,
 1428               "Failed loading session recording configuration: %s\n",
 1429               strerror(ret));
 1430         goto fail;
 1431     }
 1432 
 1433     for (dom = rctx->domains; dom; dom = get_next_domain(dom, 0)) {
 1434         ret = sss_names_init(rctx->cdb, rctx->cdb, dom->name, &dom->names);
 1435         if (ret != EOK) {
 1436             DEBUG(SSSDBG_FATAL_FAILURE,
 1437                   "fatal error initializing regex data for domain: %s\n",
 1438                    dom->name);
 1439             goto fail;
 1440         }
 1441 
 1442         /* skip local domain, it doesn't have a backend */
 1443         if (local_provider_is_built()
 1444                 && strcasecmp(dom->provider, "local") == 0) {
 1445             continue;
 1446         }
 1447 
 1448         ret = sss_dp_init(rctx, conn_name, svc_name, dom);
 1449         if (ret != EOK) {
 1450             DEBUG(SSSDBG_FATAL_FAILURE,
 1451                   "fatal error setting up backend connector\n");
 1452             goto fail;
 1453         }
 1454     }
 1455 
 1456     ret = sysdb_init(rctx, rctx->domains);
 1457     if (ret != EOK) {
 1458         SYSDB_VERSION_ERROR_DAEMON(ret);
 1459         DEBUG(SSSDBG_FATAL_FAILURE,
 1460               "fatal error initializing sysdb connection\n");
 1461         goto fail;
 1462     }
 1463 
 1464     /* after all initializations we are ready to listen on our socket */
 1465     ret = activate_unix_sockets(rctx, conn_setup);
 1466     if (ret != EOK) {
 1467         DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing socket\n");
 1468         goto fail;
 1469     }
 1470 
 1471     ret = responder_init_ncache(rctx, rctx->cdb, &rctx->ncache);
 1472     if (ret != EOK) {
 1473         DEBUG(SSSDBG_CRIT_FAILURE, "fatal error initializing negcache\n");
 1474         goto fail;
 1475     }
 1476 
 1477     ret = sss_ad_default_names_ctx(rctx, &rctx->global_names);
 1478     if (ret != EOK) {
 1479         DEBUG(SSSDBG_CRIT_FAILURE, "sss_ad_default_names_ctx failed.\n");
 1480         goto fail;
 1481     }
 1482 
 1483     DEBUG(SSSDBG_TRACE_FUNC,
 1484           "Responder initialization complete (%s)\n",
 1485           rctx->socket_activated  ? "socket-activated" :
 1486                                     rctx->dbus_activated ? "dbus-activated" :
 1487                                                             "explicitly configured");
 1488 
 1489     *responder_ctx = rctx;
 1490     return EOK;
 1491 
 1492 fail:
 1493     talloc_free(rctx);
 1494     return ret;
 1495 }
 1496 
 1497 int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
 1498                            struct be_conn **_conn)
 1499 {
 1500     struct be_conn *iter;
 1501 
 1502     if (!rctx->be_conns) return ENOENT;
 1503 
 1504     for (iter = rctx->be_conns; iter; iter = iter->next) {
 1505         if (strcasecmp(domain, iter->domain->name) == 0) break;
 1506     }
 1507 
 1508     if (!iter) return ENOENT;
 1509 
 1510     *_conn = iter;
 1511 
 1512     return EOK;
 1513 }
 1514 
 1515 struct sss_domain_info *
 1516 responder_get_domain(struct resp_ctx *rctx, const char *name)
 1517 {
 1518     struct sss_domain_info *dom;
 1519     struct sss_domain_info *ret_dom = NULL;
 1520 
 1521     for (dom = rctx->domains; dom;
 1522             dom = get_next_domain(dom, SSS_GND_DESCEND)) {
 1523         if (sss_domain_get_state(dom) == DOM_DISABLED) {
 1524             continue;
 1525         }
 1526 
 1527         if (strcasecmp(dom->name, name) == 0 ||
 1528             (dom->flat_name != NULL &&
 1529              strcasecmp(dom->flat_name, name) == 0)) {
 1530             ret_dom = dom;
 1531             break;
 1532         }
 1533     }
 1534 
 1535     if (!ret_dom) {
 1536         DEBUG(SSSDBG_OP_FAILURE, "Unknown domain [%s]\n", name);
 1537     }
 1538 
 1539     return ret_dom;
 1540 }
 1541 
 1542 errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id,
 1543                                    struct sss_domain_info **_ret_dom)
 1544 {
 1545     struct sss_domain_info *dom;
 1546     struct sss_domain_info *ret_dom = NULL;
 1547     size_t id_len;
 1548     size_t dom_id_len;
 1549     int ret;
 1550 
 1551     if (id == NULL || _ret_dom == NULL) {
 1552         return EINVAL;
 1553     }
 1554 
 1555     id_len = strlen(id);
 1556 
 1557     for (dom = rctx->domains; dom;
 1558             dom = get_next_domain(dom, SSS_GND_DESCEND)) {
 1559         if (sss_domain_get_state(dom) == DOM_DISABLED ||
 1560                 dom->domain_id == NULL) {
 1561             continue;
 1562         }
 1563 
 1564         dom_id_len = strlen(dom->domain_id);
 1565         if ((id_len >= dom_id_len) &&
 1566             strncasecmp(dom->domain_id, id, dom_id_len) == 0) {
 1567             if (IS_SUBDOMAIN(dom) &&
 1568                 ((time(NULL) - dom->parent->subdomains_last_checked.tv_sec) >
 1569                                                       rctx->domains_timeout)) {
 1570                 DEBUG(SSSDBG_TRACE_FUNC, "Domain entry with id [%s] " \
 1571                                           "is expired.\n", id);
 1572                 ret = EAGAIN;
 1573                 goto done;
 1574             }
 1575             ret_dom = dom;
 1576             break;
 1577         }
 1578     }
 1579 
 1580     if (ret_dom == NULL) {
 1581         DEBUG(SSSDBG_OP_FAILURE, "Unknown domain id [%s], checking for "
 1582                                   "possible subdomains!\n", id);
 1583         ret = ENOENT;
 1584     } else {
 1585         *_ret_dom = ret_dom;
 1586         ret = EOK;
 1587     }
 1588 
 1589 done:
 1590     return ret;
 1591 }
 1592 
 1593 errno_t
 1594 responder_logrotate(TALLOC_CTX *mem_ctx,
 1595                     struct sbus_request *sbus_req,
 1596                     struct resp_ctx *rctx)
 1597 {
 1598     return server_common_rotate_logs(rctx->cdb, rctx->confdb_service_path);
 1599 
 1600     return EOK;
 1601 }
 1602 
 1603 void responder_set_fd_limit(rlim_t fd_limit)
 1604 {
 1605     struct rlimit current_limit, new_limit;
 1606     int limret;
 1607 
 1608     /* First, let's see if we have permission to just set
 1609      * the value as-is.
 1610      */
 1611     new_limit.rlim_cur = fd_limit;
 1612     new_limit.rlim_max = fd_limit;
 1613     limret = setrlimit(RLIMIT_NOFILE, &new_limit);
 1614     if (limret == 0) {
 1615         DEBUG(SSSDBG_CONF_SETTINGS,
 1616               "Maximum file descriptors set to [%"SPRIrlim"]\n",
 1617                new_limit.rlim_cur);
 1618         return;
 1619     }
 1620 
 1621     /* We couldn't set the soft and hard limits to this
 1622      * value. Let's see how high we CAN set it.
 1623      */
 1624 
 1625     /* Determine the maximum hard limit */
 1626     limret = getrlimit(RLIMIT_NOFILE, &current_limit);
 1627     if (limret == 0) {
 1628         DEBUG(SSSDBG_TRACE_INTERNAL,
 1629               "Current fd limit: [%"SPRIrlim"]\n",
 1630                current_limit.rlim_cur);
 1631         /* Choose the lesser of the requested and the hard limit */
 1632         if (current_limit.rlim_max < fd_limit) {
 1633             new_limit.rlim_cur = current_limit.rlim_max;
 1634         } else {
 1635             new_limit.rlim_cur = fd_limit;
 1636         }
 1637         new_limit.rlim_max = current_limit.rlim_max;
 1638 
 1639         limret = setrlimit(RLIMIT_NOFILE, &new_limit);
 1640         if (limret == 0) {
 1641             DEBUG(SSSDBG_CONF_SETTINGS,
 1642                   "Maximum file descriptors set to [%"SPRIrlim"]\n",
 1643                    new_limit.rlim_cur);
 1644         } else {
 1645             DEBUG(SSSDBG_CRIT_FAILURE,
 1646                   "Could not set new fd limits. Proceeding with "
 1647                    "[%"SPRIrlim"]\n", current_limit.rlim_cur);
 1648         }
 1649     } else {
 1650         DEBUG(SSSDBG_CRIT_FAILURE,
 1651               "Could not determine fd limits. "
 1652                "Proceeding with system values\n");
 1653     }
 1654 }
 1655 
 1656 errno_t responder_setup_idle_timeout_config(struct resp_ctx *rctx)
 1657 {
 1658     errno_t ret;
 1659 
 1660     ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path,
 1661                          CONFDB_RESPONDER_IDLE_TIMEOUT,
 1662                          CONFDB_RESPONDER_IDLE_DEFAULT_TIMEOUT,
 1663                          &rctx->idle_timeout);
 1664     if (ret != EOK) {
 1665         DEBUG(SSSDBG_OP_FAILURE,
 1666               "Cannot get the responder idle timeout [%d]: %s\n",
 1667               ret, sss_strerror(ret));
 1668         goto fail;
 1669     }
 1670 
 1671     /* Idle timeout set to 0 means that no timeout will be set up to
 1672      * the responder */
 1673     if (rctx->idle_timeout == 0) {
 1674         DEBUG(SSSDBG_TRACE_INTERNAL,
 1675               "Responder idle timeout won't be set up as the "
 1676               "responder_idle_timeout is set to 0");
 1677     } else {
 1678         /* Ensure that the responder timeout is at least sixty seconds */
 1679         if (rctx->idle_timeout < 60) {
 1680             DEBUG(SSSDBG_TRACE_INTERNAL,
 1681                   "responder_idle_timeout is set to a value lower than "
 1682                   "the minimum allowed (60s).\n"
 1683                   "The minimum allowed value will be used.");
 1684 
 1685             rctx->idle_timeout = 60;
 1686         }
 1687 
 1688         ret = setup_responder_idle_timer(rctx);
 1689         if (ret != EOK) {
 1690             DEBUG(SSSDBG_MINOR_FAILURE,
 1691                   "An error occurred when setting up the responder's idle "
 1692                   "timeout for the responder [%p]: %s [%d].\n"
 1693                   "The responder won't be automatically shutdown after %d "
 1694                   "seconds inactive. \n",
 1695                   rctx, sss_strerror(ret), ret,
 1696                   rctx->idle_timeout);
 1697         }
 1698     }
 1699 
 1700     ret = EOK;
 1701 
 1702 fail:
 1703     return ret;
 1704 
 1705 }
 1706 
 1707 /* ====== Helper functions for the domain resolution order ======= */
 1708 static errno_t
 1709 sss_resp_new_cr_domains_from_ipa_id_view(TALLOC_CTX *mem_ctx,
 1710                                          struct sss_domain_info *domains,
 1711                                          struct sysdb_ctx *sysdb,
 1712                                          struct cache_req_domain **_cr_domains)
 1713 {
 1714     TALLOC_CTX *tmp_ctx;
 1715     struct cache_req_domain *cr_domains = NULL;
 1716     const char *domain_resolution_order = NULL;
 1717     errno_t ret;
 1718 
 1719     tmp_ctx = talloc_new(NULL);
 1720     if (tmp_ctx == NULL) {
 1721         return ENOMEM;
 1722     }
 1723 
 1724     ret = sysdb_get_view_domain_resolution_order(tmp_ctx, sysdb,
 1725                                                  &domain_resolution_order);
 1726     if (ret != EOK && ret != ENOENT) {
 1727         DEBUG(SSSDBG_MINOR_FAILURE,
 1728               "sysdb_get_view_cache_req_domain() failed [%d]: [%s].\n",
 1729               ret, sss_strerror(ret));
 1730         goto done;
 1731     }
 1732 
 1733     if (ret == ENOENT) {
 1734         goto done;
 1735     }
 1736 
 1737     ret = cache_req_domain_new_list_from_domain_resolution_order(
 1738                         mem_ctx, domains, domain_resolution_order, &cr_domains);
 1739     if (ret != EOK) {
 1740         DEBUG(SSSDBG_DEFAULT,
 1741               "cache_req_domain_new_list_from_domain_resolution_order() "
 1742               "failed [%d]: [%s].\n",
 1743               ret, sss_strerror(ret));
 1744         goto done;
 1745     }
 1746 
 1747     *_cr_domains = cr_domains;
 1748 
 1749     ret = EOK;
 1750 
 1751 done:
 1752     talloc_free(tmp_ctx);
 1753     return ret;
 1754 }
 1755 
 1756 static errno_t
 1757 sss_resp_new_cr_domains_from_ipa_config(TALLOC_CTX *mem_ctx,
 1758                                         struct sss_domain_info *domains,
 1759                                         struct sysdb_ctx *sysdb,
 1760                                         const char *domain,
 1761                                         struct cache_req_domain **_cr_domains)
 1762 {
 1763     TALLOC_CTX *tmp_ctx;
 1764     const char *domain_resolution_order = NULL;
 1765     errno_t ret;
 1766 
 1767     *_cr_domains = NULL;
 1768 
 1769     tmp_ctx = talloc_new(NULL);
 1770     if (tmp_ctx == NULL) {
 1771         return ENOMEM;
 1772     }
 1773 
 1774     ret = sysdb_domain_get_domain_resolution_order(tmp_ctx, sysdb, domain,
 1775                                                    &domain_resolution_order);
 1776 
 1777     if (ret != EOK && ret != ENOENT) {
 1778         DEBUG(SSSDBG_MINOR_FAILURE,
 1779               "sysdb_domain_get_cache_req_domain() failed [%d]: [%s].\n",
 1780               ret, sss_strerror(ret));
 1781         goto done;
 1782     }
 1783 
 1784     if (ret == ENOENT) {
 1785         goto done;
 1786     }
 1787 
 1788     ret = cache_req_domain_new_list_from_domain_resolution_order(
 1789                         mem_ctx, domains, domain_resolution_order, _cr_domains);
 1790     if (ret != EOK) {
 1791         DEBUG(SSSDBG_DEFAULT,
 1792               "cache_req_domain_new_list_from_domain_resolution_order() "
 1793               "failed [%d]: [%s].\n",
 1794               ret, sss_strerror(ret));
 1795         goto done;
 1796     }
 1797 
 1798     ret = EOK;
 1799 
 1800 done:
 1801     talloc_free(tmp_ctx);
 1802     return ret;
 1803 }
 1804 
 1805 errno_t sss_resp_populate_cr_domains(struct resp_ctx *rctx)
 1806 {
 1807     struct cache_req_domain *cr_domains = NULL;
 1808     struct sss_domain_info *dom;
 1809     errno_t ret;
 1810 
 1811     if (rctx->domain_resolution_order != NULL) {
 1812         ret = cache_req_domain_new_list_from_domain_resolution_order(
 1813                 rctx, rctx->domains,
 1814                 rctx->domain_resolution_order, &cr_domains);
 1815         if (ret == EOK) {
 1816             DEBUG(SSSDBG_TRACE_FUNC,
 1817                   "Using domain_resolution_order from sssd.conf\n");
 1818             goto done;
 1819         } else {
 1820             DEBUG(SSSDBG_MINOR_FAILURE,
 1821                   "Failed to use domain_resolution_order set in the config file.\n"
 1822                   "Trying to fallback to use ipaDomainOrderResolution setup by "
 1823                   "IPA.\n");
 1824         }
 1825     }
 1826 
 1827     for (dom = rctx->domains; dom != NULL; dom = dom->next) {
 1828         if (dom->provider != NULL && strcmp(dom->provider, "ipa") == 0) {
 1829             break;
 1830         }
 1831     }
 1832 
 1833     if (dom == NULL) {
 1834         ret = cache_req_domain_new_list_from_domain_resolution_order(
 1835                                         rctx, rctx->domains, NULL, &cr_domains);
 1836         if (ret != EOK) {
 1837             DEBUG(SSSDBG_CRIT_FAILURE,
 1838                   "Failed to flatten the list of domains.\n");
 1839         }
 1840         goto done;
 1841     }
 1842 
 1843     if (dom->has_views) {
 1844         ret = sss_resp_new_cr_domains_from_ipa_id_view(rctx, rctx->domains,
 1845                                                        dom->sysdb,
 1846                                                        &cr_domains);
 1847         if (ret == EOK) {
 1848             DEBUG(SSSDBG_TRACE_FUNC,
 1849                   "Using domain_resolution_order from IPA ID View\n");
 1850             goto done;
 1851         }
 1852 
 1853         if (ret != ENOENT) {
 1854             DEBUG(SSSDBG_MINOR_FAILURE,
 1855                   "Failed to use ipaDomainResolutionOrder set for the "
 1856                   "view \"%s\".\n"
 1857                   "Trying to fallback to use ipaDomainOrderResolution "
 1858                   "set in ipaConfig for the domain: %s.\n",
 1859                   dom->view_name, dom->name);
 1860         }
 1861     }
 1862 
 1863     ret = sss_resp_new_cr_domains_from_ipa_config(rctx, rctx->domains,
 1864                                                   dom->sysdb, dom->name,
 1865                                                   &cr_domains);
 1866     if (ret == EOK) {
 1867         DEBUG(SSSDBG_TRACE_FUNC,
 1868               "Using domain_resolution_order from IPA Config\n");
 1869         goto done;
 1870     }
 1871 
 1872     if (ret != ENOENT) {
 1873         DEBUG(SSSDBG_MINOR_FAILURE,
 1874               "Failed to use ipaDomainResolutionOrder set in ipaConfig "
 1875               "for the domain: \"%s\".\n"
 1876               "No ipaDomainResolutionOrder will be followed.\n",
 1877               dom->name);
 1878     }
 1879 
 1880     ret = cache_req_domain_new_list_from_domain_resolution_order(
 1881                                         rctx, rctx->domains, NULL, &cr_domains);
 1882     if (ret != EOK) {
 1883         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to flatten the list of domains.\n");
 1884         goto done;
 1885     }
 1886 
 1887     ret = EOK;
 1888 
 1889 done:
 1890     cache_req_domain_list_zfree(&rctx->cr_domains);
 1891     rctx->cr_domains = cr_domains;
 1892 
 1893     return ret;
 1894 }
 1895 
 1896 /**
 1897  * Helper functions to format output names
 1898  */
 1899 int sized_output_name(TALLOC_CTX *mem_ctx,
 1900                       struct resp_ctx *rctx,
 1901                       const char *orig_name,
 1902                       struct sss_domain_info *name_dom,
 1903                       struct sized_string **_name)
 1904 {
 1905     TALLOC_CTX *tmp_ctx = NULL;
 1906     errno_t ret;
 1907     char *name_str;
 1908     struct sized_string *name;
 1909 
 1910     tmp_ctx = talloc_new(NULL);
 1911     if (tmp_ctx == NULL) {
 1912         return ENOMEM;
 1913     }
 1914 
 1915     name = talloc_zero(tmp_ctx, struct sized_string);
 1916     if (name == NULL) {
 1917         ret = ENOMEM;
 1918         goto done;
 1919     }
 1920 
 1921     ret = sss_output_fqname(name, name_dom, orig_name,
 1922                             rctx->override_space, &name_str);
 1923     if (ret != EOK) {
 1924         goto done;
 1925     }
 1926 
 1927     to_sized_string(name, name_str);
 1928     *_name = talloc_steal(mem_ctx, name);
 1929     ret = EOK;
 1930 done:
 1931     talloc_zfree(tmp_ctx);
 1932     return ret;
 1933 }
 1934 
 1935 int sized_domain_name(TALLOC_CTX *mem_ctx,
 1936                       struct resp_ctx *rctx,
 1937                       const char *member_name,
 1938                       struct sized_string **_name)
 1939 {
 1940     TALLOC_CTX *tmp_ctx = NULL;
 1941     errno_t ret;
 1942     char *domname;
 1943     struct sss_domain_info *member_dom;
 1944 
 1945     tmp_ctx = talloc_new(NULL);
 1946     if (tmp_ctx == NULL) {
 1947         return ENOMEM;
 1948     }
 1949 
 1950     ret = sss_parse_internal_fqname(tmp_ctx, member_name, NULL, &domname);
 1951     if (ret != EOK) {
 1952         DEBUG(SSSDBG_CRIT_FAILURE, "sss_parse_internal_fqname failed\n");
 1953         goto done;
 1954     }
 1955 
 1956     if (domname == NULL) {
 1957         ret = ERR_WRONG_NAME_FORMAT;
 1958         goto done;
 1959     }
 1960 
 1961     member_dom = find_domain_by_name(get_domains_head(rctx->domains),
 1962                                      domname, true);
 1963     if (member_dom == NULL) {
 1964         ret = ERR_DOMAIN_NOT_FOUND;
 1965         goto done;
 1966     }
 1967 
 1968     ret = sized_output_name(mem_ctx, rctx, member_name,
 1969                             member_dom, _name);
 1970 done:
 1971     talloc_free(tmp_ctx);
 1972     return ret;
 1973 }