1 /* ldap-wrapper.c - LDAP access via a wrapper process
2 * Copyright (C) 2004, 2005, 2007, 2008, 2018 g10 Code GmbH
3 * Copyright (C) 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG 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.
12 * GnuPG 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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
22 * We can't use LDAP directly for these reasons:
24 * 1. On some systems the LDAP library uses (indirectly) pthreads and
25 * that is not compatible with GNU Pth. Since 2.1 we use nPth
26 * instead of GNU Pth which does not have this problem anymore
27 * because it will use pthreads if the platform supports it. Thus
28 * this was a historical reasons.
30 * 2. It is huge library in particular if TLS comes into play. So
31 * problems with unfreed memory might turn up and we don't want
32 * this in a long running daemon.
34 * 3. There is no easy way for timeouts. In particular the timeout
35 * value does not work for DNS lookups (well, this is usual) and it
36 * seems not to work while loading a large attribute like a
37 * CRL. Having a separate process allows us to either tell the
38 * process to commit suicide or have our own housekepping function
39 * kill it after some time. The latter also allows proper
40 * cancellation of a query at any point of time.
42 * 4. Given that we are going out to the network and usually get back
43 * a long response, the fork/exec overhead is acceptable.
45 * Note that under WindowsCE the number of processes is strongly
46 * limited (32 processes including the kernel processes) and thus we
47 * don't use the process approach but implement a different wrapper in
64 #include "../common/exechelp.h"
66 #include "ldap-wrapper.h"
69 #ifdef HAVE_W32_SYSTEM
70 #define setenv(a,b,c) SetEnvironmentVariable ((a),(b))
72 #define pth_close(fd) close(fd)
75 #ifndef USE_LDAPWRAPPER
76 # error This module is not expected to be build.
79 /* In case sysconf does not return a value we need to have a limit. */
80 #ifdef _POSIX_OPEN_MAX
81 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
83 #define MAX_OPEN_FDS 20
86 #define INACTIVITY_TIMEOUT (opt.ldaptimeout + 60*5) /* seconds */
88 #define TIMERTICK_INTERVAL 2
90 /* To keep track of the LDAP wrapper state we use this structure. */
91 struct wrapper_context_s
93 struct wrapper_context_s *next;
95 pid_t pid; /* The pid of the wrapper process. */
96 int printable_pid; /* Helper to print diagnostics after the process has
98 estream_t fp; /* Connected with stdout of the ldap wrapper. */
99 gpg_error_t fp_err; /* Set to the gpg_error of the last read error
101 estream_t log_fp; /* Connected with stderr of the ldap wrapper. */
102 ctrl_t ctrl; /* Connection data. */
103 int ready; /* Internally used to mark to be removed contexts. */
104 ksba_reader_t reader;/* The ksba reader object or NULL. */
105 char *line; /* Used to print the log lines (malloced). */
106 size_t linesize; /* Allocated size of LINE. */
107 size_t linelen; /* Use size of LINE. */
108 time_t stamp; /* The last time we noticed ativity. */
109 int reaper_idx; /* Private to ldap_wrapper_thread. */
114 /* We keep a global list of spawned wrapper process. A separate
115 * thread makes use of this list to log error messages and to watch
116 * out for finished processes. Access to list is protected by a
117 * mutex. The condition variable is used to wakeup the reaper
119 static struct wrapper_context_s *reaper_list;
120 static npth_mutex_t reaper_list_mutex = NPTH_MUTEX_INITIALIZER;
121 static npth_cond_t reaper_run_cond = NPTH_COND_INITIALIZER;
123 /* We need to know whether we are shutting down the process. */
124 static int shutting_down;
128 /* Close the estream fp and set it to NULL. */
129 #define SAFE_CLOSE(fp) \
130 do { estream_t _fp = fp; es_fclose (_fp); fp = NULL; } while (0)
137 lock_reaper_list (void)
139 if (npth_mutex_lock (&reaper_list_mutex))
140 log_fatal ("%s: failed to acquire mutex: %s\n", __func__,
141 gpg_strerror (gpg_error_from_syserror ()));
146 unlock_reaper_list (void)
148 if (npth_mutex_unlock (&reaper_list_mutex))
149 log_fatal ("%s: failed to release mutex: %s\n", __func__,
150 gpg_strerror (gpg_error_from_syserror ()));
155 /* Read a fixed amount of data from READER into BUFFER. */
157 read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count)
164 err = ksba_reader_read (reader, buffer, count, &nread);
174 /* Release the wrapper context and kill a running wrapper process. */
176 destroy_wrapper (struct wrapper_context_s *ctx)
178 if (ctx->pid != (pid_t)(-1))
180 gnupg_kill_process (ctx->pid);
181 gnupg_release_process (ctx->pid);
183 ksba_reader_release (ctx->reader);
184 SAFE_CLOSE (ctx->fp);
185 SAFE_CLOSE (ctx->log_fp);
191 /* Print the content of LINE to thye log stream but make sure to only
192 print complete lines. Using NULL for LINE will flush any pending
193 output. LINE may be modified by this function. */
195 print_log_line (struct wrapper_context_s *ctx, char *line)
202 if (ctx->line && ctx->linelen)
205 log_info ("%s\n", ctx->line);
211 while ((s = strchr (line, '\n')))
214 if (ctx->line && ctx->linelen)
216 log_info ("%s", ctx->line);
218 log_printf ("%s\n", line);
221 log_info ("%s\n", line);
227 if (ctx->linelen + n + 1 >= ctx->linesize)
232 newsize = ctx->linesize + ((n + 255) & ~255) + 1;
233 tmp = (ctx->line ? xtryrealloc (ctx->line, newsize)
234 : xtrymalloc (newsize));
237 log_error (_("error printing log line: %s\n"), strerror (errno));
241 ctx->linesize = newsize;
243 memcpy (ctx->line + ctx->linelen, line, n);
245 ctx->line[ctx->linelen] = 0;
250 /* Read data from the log stream. Returns true if the log stream
251 * indicated EOF or error. */
253 read_log_data (struct wrapper_context_s *ctx)
259 rc = es_read (ctx->log_fp, line, sizeof line - 1, &n);
260 if (rc || !n) /* Error or EOF. */
264 gpg_error_t err = gpg_error_from_syserror ();
265 if (gpg_err_code (err) == GPG_ERR_EAGAIN)
267 log_error (_("error reading log from ldap wrapper %d: %s\n"),
268 (int)ctx->pid, gpg_strerror (err));
270 print_log_line (ctx, NULL); /* Flush. */
271 SAFE_CLOSE (ctx->log_fp);
276 print_log_line (ctx, line);
277 if (ctx->stamp != (time_t)(-1))
278 ctx->stamp = time (NULL);
283 /* This function is run by a separate thread to maintain the list of
284 wrappers and to log error messages from these wrappers. */
286 ldap_reaper_thread (void *dummy)
289 struct wrapper_context_s *ctx;
290 struct wrapper_context_s *ctx_prev;
291 struct timespec abstime;
292 struct timespec curtime;
293 struct timespec timeout;
295 gpgrt_poll_t *fparray = NULL;
303 npth_clock_gettime (&abstime);
304 abstime.tv_sec += TIMERTICK_INTERVAL;
310 /* Wait until we are needed and then setup the FPARRAY. */
311 /* Note: There is one unlock inside the block! */
314 while (!reaper_list && !shutting_down)
316 if (npth_cond_wait (&reaper_run_cond, &reaper_list_mutex))
317 log_error ("ldap-reaper: waiting on condition failed: %s\n",
318 gpg_strerror (gpg_error_from_syserror ()));
321 for (count = 0, ctx = reaper_list; ctx; ctx = ctx->next)
324 if (count > fparraysize || !fparray)
326 /* Need to realloc the array. We simply discard it and
327 * replace it by a new one. */
329 fparray = xtrycalloc (count? count : 1, sizeof *fparray);
332 err = gpg_error_from_syserror ();
333 log_error ("ldap-reaper can't allocate poll array: %s"
334 " - waiting 1s\n", gpg_strerror (err));
335 /* Note: Here we unlock and continue! */
336 unlock_reaper_list ();
342 for (count = 0, ctx = reaper_list; ctx; ctx = ctx->next)
346 log_assert (count < fparraysize);
347 fparray[count].stream = ctx->log_fp;
348 fparray[count].want_read = 1;
349 fparray[count].ignore = 0;
350 ctx->reaper_idx = count;
355 ctx->reaper_idx = -1;
356 fparray[count].ignore = 1;
359 for (i=count; i < fparraysize; i++)
360 fparray[i].ignore = 1;
362 unlock_reaper_list (); /* Note the one unlock inside the block. */
364 /* Compute the next timeout. */
365 npth_clock_gettime (&curtime);
366 if (!(npth_timercmp (&curtime, &abstime, <)))
368 /* Inactivity is checked below. Nothing else to do. */
369 npth_clock_gettime (&abstime);
370 abstime.tv_sec += TIMERTICK_INTERVAL;
372 npth_timersub (&abstime, &curtime, &timeout);
373 millisecs = timeout.tv_sec * 1000;
374 millisecs += timeout.tv_nsec / 1000000;
380 log_debug ("ldap-reaper: next run (count=%d size=%d, timeout=%d)\n",
381 count, fparraysize, millisecs);
382 for (count=0; count < fparraysize; count++)
383 if (!fparray[count].ignore)
384 log_debug ("ldap-reaper: fp[%d] stream=%p want=%d\n",
385 count, fparray[count].stream,fparray[count].want_read);
388 ret = es_poll (fparray, fparraysize, millisecs);
391 err = gpg_error_from_syserror ();
392 log_error ("ldap-reaper failed to poll: %s"
393 " - waiting 1s\n", gpg_strerror (err));
394 /* In case the reason for the error is a too large array, we
395 * release it so that it will be allocated smaller in the
406 for (count=0; count < fparraysize; count++)
407 if (!fparray[count].ignore)
408 log_debug ("ldap-reaper: fp[%d] stream=%p r=%d %c%c%c%c%c%c%c\n",
409 count, fparray[count].stream, ret,
410 fparray[count].got_read? 'r':'-',
411 fparray[count].got_write?'w':'-',
412 fparray[count].got_oob? 'o':'-',
413 fparray[count].got_rdhup?'H':'-',
414 fparray[count].got_err? 'e':'-',
415 fparray[count].got_hup? 'h':'-',
416 fparray[count].got_nval? 'n':'-');
419 /* All timestamps before exptime should be considered expired. */
420 exptime = time (NULL);
421 if (exptime > INACTIVITY_TIMEOUT)
422 exptime -= INACTIVITY_TIMEOUT;
426 for (ctx = reaper_list; ctx; ctx = ctx->next)
428 /* Check whether there is any logging to be done. We need
429 * to check FPARRAYSIZE because it can be 0 in case
430 * es_poll returned a timeout. */
431 if (fparraysize && ctx->log_fp && ctx->reaper_idx >= 0)
433 log_assert (ctx->reaper_idx < fparraysize);
434 if (fparray[ctx->reaper_idx].got_read)
436 if (read_log_data (ctx))
438 SAFE_CLOSE (ctx->log_fp);
444 /* Check whether the process is still running. */
445 if (ctx->pid != (pid_t)(-1))
449 err = gnupg_wait_process ("[dirmngr_ldap]", ctx->pid, 0,
454 log_info (_("ldap wrapper %d ready"), (int)ctx->pid);
456 gnupg_release_process (ctx->pid);
457 ctx->pid = (pid_t)(-1);
460 else if (gpg_err_code (err) == GPG_ERR_GENERAL)
463 log_info (_("ldap wrapper %d ready: timeout\n"),
466 log_info (_("ldap wrapper %d ready: exitcode=%d\n"),
467 (int)ctx->pid, status);
469 gnupg_release_process (ctx->pid);
470 ctx->pid = (pid_t)(-1);
473 else if (gpg_err_code (err) != GPG_ERR_TIMEOUT)
475 log_error (_("waiting for ldap wrapper %d failed: %s\n"),
476 (int)ctx->pid, gpg_strerror (err));
481 /* Check whether we should terminate the process. */
482 if (ctx->pid != (pid_t)(-1)
483 && ctx->stamp != (time_t)(-1) && ctx->stamp < exptime)
485 gnupg_kill_process (ctx->pid);
486 ctx->stamp = (time_t)(-1);
487 log_info (_("ldap wrapper %d stalled - killing\n"),
489 /* We need to close the log stream because the cleanup
490 * loop waits for it. */
491 SAFE_CLOSE (ctx->log_fp);
496 /* If something has been printed to the log file or we got an
497 * EOF from a wrapper, we now print the list of active
499 if (any_action && DBG_EXTPROG)
501 log_debug ("ldap worker stati:\n");
502 for (ctx = reaper_list; ctx; ctx = ctx->next)
503 log_debug (" c=%p pid=%d/%d rdr=%p logfp=%p"
504 " ctrl=%p/%d la=%lu rdy=%d\n",
506 (int)ctx->pid, (int)ctx->printable_pid,
507 ctx->reader, ctx->log_fp,
508 ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0,
509 (unsigned long)ctx->stamp, ctx->ready);
512 /* An extra loop to check whether ready marked wrappers may be
513 * removed. We may only do so if the ksba reader object is
514 * not anymore in use or we are in shutdown state. */
516 for (ctx_prev=NULL, ctx=reaper_list; ctx; ctx_prev=ctx, ctx=ctx->next)
519 && ((!ctx->log_fp && !ctx->reader) || shutting_down))
522 ctx_prev->next = ctx->next;
524 reaper_list = ctx->next;
525 destroy_wrapper (ctx);
530 unlock_reaper_list ();
534 return NULL; /* Make the compiler happy. */
539 /* Start the reaper thread for the ldap wrapper. */
541 ldap_reaper_launch_thread (void)
552 #ifdef HAVE_W32_SYSTEM
553 /* Static init does not yet work in W32 nPth. */
554 if (npth_cond_init (&reaper_run_cond, NULL))
555 log_fatal ("%s: failed to init condition variabale: %s\n",
556 __func__, gpg_strerror (gpg_error_from_syserror ()));
559 npth_attr_init (&tattr);
560 npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
562 if (npth_create (&thread, &tattr, ldap_reaper_thread, NULL))
564 err = gpg_error_from_syserror ();
565 log_error ("error spawning ldap reaper reaper thread: %s\n",
566 gpg_strerror (err) );
569 npth_setname_np (thread, "ldap-reaper");
570 npth_attr_destroy (&tattr);
575 /* Wait until all ldap wrappers have terminated. We assume that the
576 kill has already been sent to all of them. */
578 ldap_wrapper_wait_connections ()
583 if (npth_cond_signal (&reaper_run_cond))
584 log_error ("%s: Ooops: signaling condition failed: %s\n",
585 __func__, gpg_strerror (gpg_error_from_syserror ()));
587 unlock_reaper_list ();
593 /* This function is to be used to release a context associated with the
594 given reader object. */
596 ldap_wrapper_release_context (ksba_reader_t reader)
598 struct wrapper_context_s *ctx;
605 for (ctx=reaper_list; ctx; ctx=ctx->next)
606 if (ctx->reader == reader)
609 log_debug ("releasing ldap worker c=%p pid=%d/%d rdr=%p"
610 " ctrl=%p/%d\n", ctx,
611 (int)ctx->pid, (int)ctx->printable_pid,
613 ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0);
616 SAFE_CLOSE (ctx->fp);
619 ctx->ctrl->refcount--;
623 log_info ("%s: reading from ldap wrapper %d failed: %s\n",
624 __func__, ctx->printable_pid, gpg_strerror (ctx->fp_err));
628 unlock_reaper_list ();
632 /* Cleanup all resources held by the connection associated with
633 CTRL. This is used after a cancel to kill running wrappers. */
635 ldap_wrapper_connection_cleanup (ctrl_t ctrl)
637 struct wrapper_context_s *ctx;
641 for (ctx=reaper_list; ctx; ctx=ctx->next)
642 if (ctx->ctrl && ctx->ctrl == ctrl)
644 ctx->ctrl->refcount--;
646 if (ctx->pid != (pid_t)(-1))
647 gnupg_kill_process (ctx->pid);
649 log_info ("%s: reading from ldap wrapper %d failed: %s\n",
650 __func__, ctx->printable_pid, gpg_strerror (ctx->fp_err));
653 unlock_reaper_list ();
657 /* This is the callback used by the ldap wrapper to feed the ksba
658 * reader with the wrapper's stdout. See the description of
659 * ksba_reader_set_cb for details. */
661 reader_callback (void *cb_value, char *buffer, size_t count, size_t *nread)
663 struct wrapper_context_s *ctx = cb_value;
664 size_t nleft = count;
665 struct timespec abstime;
666 struct timespec curtime;
667 struct timespec timeout;
669 gpgrt_poll_t fparray[1];
674 /* FIXME: We might want to add some internal buffering because the
675 ksba code does not do any buffering for itself (because a ksba
676 reader may be detached from another stream to read other data and
677 then it would be cumbersome to get back already buffered stuff). */
679 if (!buffer && !count && !nread)
680 return -1; /* Rewind is not supported. */
682 /* If we ever encountered a read error, don't continue (we don't want to
683 possibly overwrite the last error cause). Bail out also if the
684 file descriptor has been closed. */
685 if (ctx->fp_err || !ctx->fp)
691 memset (fparray, 0, sizeof fparray);
692 fparray[0].stream = ctx->fp;
693 fparray[0].want_read = 1;
695 npth_clock_gettime (&abstime);
696 abstime.tv_sec += TIMERTICK_INTERVAL;
700 npth_clock_gettime (&curtime);
701 if (!(npth_timercmp (&curtime, &abstime, <)))
703 err = dirmngr_tick (ctx->ctrl);
707 SAFE_CLOSE (ctx->fp);
710 npth_clock_gettime (&abstime);
711 abstime.tv_sec += TIMERTICK_INTERVAL;
713 npth_timersub (&abstime, &curtime, &timeout);
714 millisecs = timeout.tv_sec * 1000;
715 millisecs += timeout.tv_nsec / 1000000;
721 log_debug ("%s: fp[0] stream=%p want=%d\n",
722 __func__, fparray[0].stream,fparray[0].want_read);
725 ret = es_poll (fparray, DIM (fparray), millisecs);
728 ctx->fp_err = gpg_error_from_syserror ();
729 log_error ("error polling stdout of ldap wrapper %d: %s\n",
730 ctx->printable_pid, gpg_strerror (ctx->fp_err));
731 SAFE_CLOSE (ctx->fp);
736 log_debug ("%s: fp[0] stream=%p r=%d %c%c%c%c%c%c%c\n",
737 __func__, fparray[0].stream, ret,
738 fparray[0].got_read? 'r':'-',
739 fparray[0].got_write?'w':'-',
740 fparray[0].got_oob? 'o':'-',
741 fparray[0].got_rdhup?'H':'-',
742 fparray[0].got_err? 'e':'-',
743 fparray[0].got_hup? 'h':'-',
744 fparray[0].got_nval? 'n':'-');
748 /* Timeout. Will be handled when calculating the next timeout. */
752 if (fparray[0].got_read)
756 if (es_read (ctx->fp, buffer, nleft, &n))
758 ctx->fp_err = gpg_error_from_syserror ();
759 if (gpg_err_code (ctx->fp_err) == GPG_ERR_EAGAIN)
763 log_error ("%s: error reading: %s (%d)\n",
764 __func__, gpg_strerror (ctx->fp_err), ctx->fp_err);
765 SAFE_CLOSE (ctx->fp);
769 else if (!n) /* EOF */
772 return -1; /* EOF. */
777 if (n > 0 && ctx->stamp != (time_t)(-1))
778 ctx->stamp = time (NULL);
781 *nread = count - nleft;
787 /* Fork and exec the LDAP wrapper and return a new libksba reader
788 object at READER. ARGV is a NULL terminated list of arguments for
789 the wrapper. The function returns 0 on success or an error code.
791 Special hack to avoid passing a password through the command line
792 which is globally visible: If the first element of ARGV is "--pass"
793 it will be removed and instead the environment variable
794 DIRMNGR_LDAP_PASS will be set to the next value of ARGV. On modern
795 OSes the environment is not visible to other users. For those old
796 systems where it can't be avoided, we don't want to go into the
797 hassle of passing the password via stdin; it's just too complicated
798 and an LDAP password used for public directory lookups should not
799 be that confidential. */
801 ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[])
805 struct wrapper_context_s *ctx;
808 const char **arg_list;
810 estream_t outfp, errfp;
812 /* It would be too simple to connect stderr just to our logging
813 stream. The problem is that if we are running multi-threaded
814 everything gets intermixed. Clearly we don't want this. So the
815 only viable solutions are either to have another thread
816 responsible for logging the messages or to add an option to the
817 wrapper module to do the logging on its own. Given that we anyway
818 need a way to reap the child process and this is best done using a
819 general reaping thread, that thread can do the logging too. */
820 ldap_reaper_launch_thread ();
824 /* Files: We need to prepare stdin and stdout. We get stderr from
826 if (!opt.ldap_wrapper_program || !*opt.ldap_wrapper_program)
827 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR_LDAP);
829 pgmname = opt.ldap_wrapper_program;
831 /* Create command line argument array. */
832 for (i = 0; argv[i]; i++)
834 arg_list = xtrycalloc (i + 2, sizeof *arg_list);
837 err = gpg_error_from_syserror ();
838 log_error (_("error allocating memory: %s\n"), strerror (errno));
841 for (i = j = 0; argv[i]; i++, j++)
842 if (!i && argv[i + 1] && !strcmp (*argv, "--pass"))
844 arg_list[j] = "--env-pass";
845 setenv ("DIRMNGR_LDAP_PASS", argv[1], 1);
849 arg_list[j] = (char*) argv[i];
851 ctx = xtrycalloc (1, sizeof *ctx);
854 err = gpg_error_from_syserror ();
855 log_error (_("error allocating memory: %s\n"), strerror (errno));
860 err = gnupg_spawn_process (pgmname, arg_list,
861 NULL, NULL, GNUPG_SPAWN_NONBLOCK,
862 NULL, &outfp, &errfp, &pid);
867 log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err));
872 ctx->printable_pid = (int) pid;
877 ctx->stamp = time (NULL);
879 err = ksba_reader_new (reader);
881 err = ksba_reader_set_cb (*reader, reader_callback, ctx);
884 log_error (_("error initializing reader object: %s\n"),
886 destroy_wrapper (ctx);
887 ksba_reader_release (*reader);
892 /* Hook the context into our list of running wrappers. */
895 ctx->reader = *reader;
896 ctx->next = reaper_list;
898 if (npth_cond_signal (&reaper_run_cond))
899 log_error ("ldap-wrapper: Ooops: signaling condition failed: %s (%d)\n",
900 gpg_strerror (gpg_error_from_syserror ()), errno);
902 unlock_reaper_list ();
905 log_debug ("ldap wrapper %d started (%p, %s)\n",
906 (int)ctx->pid, ctx->reader, pgmname);
908 /* Need to wait for the first byte so we are able to detect an empty
909 output and not let the consumer see an EOF without further error
910 indications. The CRL loading logic assumes that after return
911 from this function, a failed search (e.g. host not found ) is
912 indicated right away. */
916 err = read_buffer (*reader, &c, 1);
919 ldap_wrapper_release_context (*reader);
920 ksba_reader_release (*reader);
922 if (gpg_err_code (err) == GPG_ERR_EOF)
923 return gpg_error (GPG_ERR_NO_DATA);
927 ksba_reader_unread (*reader, &c, 1);