2010-07-23 16:16:14 +00:00
|
|
|
|
/* ldap-wrapper.c - LDAP access via a wrapper process
|
2018-04-27 12:03:41 +02:00
|
|
|
|
* Copyright (C) 2004, 2005, 2007, 2008, 2018 g10 Code GmbH
|
2010-07-23 16:16:14 +00:00
|
|
|
|
* Copyright (C) 2010 Free Software Foundation, Inc.
|
|
|
|
|
*
|
|
|
|
|
* This file is part of GnuPG.
|
|
|
|
|
*
|
|
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2016-11-05 12:02:19 +01:00
|
|
|
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
2010-07-23 16:16:14 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
2018-04-27 12:03:41 +02:00
|
|
|
|
* We can't use LDAP directly for these reasons:
|
|
|
|
|
*
|
|
|
|
|
* 1. On some systems the LDAP library uses (indirectly) pthreads and
|
|
|
|
|
* that is not compatible with GNU Pth. Since 2.1 we use nPth
|
|
|
|
|
* instead of GNU Pth which does not have this problem anymore
|
|
|
|
|
* because it will use pthreads if the platform supports it. Thus
|
|
|
|
|
* this was a historical reasons.
|
|
|
|
|
*
|
|
|
|
|
* 2. It is huge library in particular if TLS comes into play. So
|
|
|
|
|
* problems with unfreed memory might turn up and we don't want
|
|
|
|
|
* this in a long running daemon.
|
|
|
|
|
*
|
|
|
|
|
* 3. There is no easy way for timeouts. In particular the timeout
|
|
|
|
|
* value does not work for DNS lookups (well, this is usual) and it
|
|
|
|
|
* seems not to work while loading a large attribute like a
|
|
|
|
|
* CRL. Having a separate process allows us to either tell the
|
|
|
|
|
* process to commit suicide or have our own housekepping function
|
|
|
|
|
* kill it after some time. The latter also allows proper
|
|
|
|
|
* cancellation of a query at any point of time.
|
|
|
|
|
*
|
|
|
|
|
* 4. Given that we are going out to the network and usually get back
|
|
|
|
|
* a long response, the fork/exec overhead is acceptable.
|
|
|
|
|
*
|
|
|
|
|
* Note that under WindowsCE the number of processes is strongly
|
|
|
|
|
* limited (32 processes including the kernel processes) and thus we
|
|
|
|
|
* don't use the process approach but implement a different wrapper in
|
|
|
|
|
* ldap-wrapper-ce.c.
|
|
|
|
|
*/
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <time.h>
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
#include <npth.h>
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
#include "dirmngr.h"
|
2017-03-07 20:21:23 +09:00
|
|
|
|
#include "../common/exechelp.h"
|
2010-07-23 16:16:14 +00:00
|
|
|
|
#include "misc.h"
|
|
|
|
|
#include "ldap-wrapper.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
#define setenv(a,b,c) SetEnvironmentVariable ((a),(b))
|
|
|
|
|
#else
|
|
|
|
|
#define pth_close(fd) close(fd)
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-07-26 14:01:32 +00:00
|
|
|
|
#ifndef USE_LDAPWRAPPER
|
|
|
|
|
# error This module is not expected to be build.
|
|
|
|
|
#endif
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
/* In case sysconf does not return a value we need to have a limit. */
|
|
|
|
|
#ifdef _POSIX_OPEN_MAX
|
|
|
|
|
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
|
|
|
|
#else
|
|
|
|
|
#define MAX_OPEN_FDS 20
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define INACTIVITY_TIMEOUT (opt.ldaptimeout + 60*5) /* seconds */
|
|
|
|
|
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
#define TIMERTICK_INTERVAL 2
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
/* To keep track of the LDAP wrapper state we use this structure. */
|
|
|
|
|
struct wrapper_context_s
|
|
|
|
|
{
|
|
|
|
|
struct wrapper_context_s *next;
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
pid_t pid; /* The pid of the wrapper process. */
|
|
|
|
|
int printable_pid; /* Helper to print diagnostics after the process has
|
|
|
|
|
* been cleaned up. */
|
|
|
|
|
estream_t fp; /* Connected with stdout of the ldap wrapper. */
|
|
|
|
|
gpg_error_t fp_err; /* Set to the gpg_error of the last read error
|
|
|
|
|
* if any. */
|
|
|
|
|
estream_t log_fp; /* Connected with stderr of the ldap wrapper. */
|
|
|
|
|
ctrl_t ctrl; /* Connection data. */
|
|
|
|
|
int ready; /* Internally used to mark to be removed contexts. */
|
|
|
|
|
ksba_reader_t reader;/* The ksba reader object or NULL. */
|
|
|
|
|
char *line; /* Used to print the log lines (malloced). */
|
|
|
|
|
size_t linesize; /* Allocated size of LINE. */
|
|
|
|
|
size_t linelen; /* Use size of LINE. */
|
|
|
|
|
time_t stamp; /* The last time we noticed ativity. */
|
|
|
|
|
int reaper_idx; /* Private to ldap_wrapper_thread. */
|
2010-07-23 16:16:14 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
/* We keep a global list of spawned wrapper process. A separate
|
|
|
|
|
* thread makes use of this list to log error messages and to watch
|
|
|
|
|
* out for finished processes. Access to list is protected by a
|
|
|
|
|
* mutex. The condition variable is used to wakeup the reaper
|
|
|
|
|
* thread. */
|
|
|
|
|
static struct wrapper_context_s *reaper_list;
|
|
|
|
|
static npth_mutex_t reaper_list_mutex = NPTH_MUTEX_INITIALIZER;
|
|
|
|
|
static npth_cond_t reaper_run_cond = NPTH_COND_INITIALIZER;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
/* We need to know whether we are shutting down the process. */
|
|
|
|
|
static int shutting_down;
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
/* Close the estream fp and set it to NULL. */
|
|
|
|
|
#define SAFE_CLOSE(fp) \
|
|
|
|
|
do { estream_t _fp = fp; es_fclose (_fp); fp = NULL; } while (0)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
lock_reaper_list (void)
|
|
|
|
|
{
|
|
|
|
|
if (npth_mutex_lock (&reaper_list_mutex))
|
|
|
|
|
log_fatal ("%s: failed to acquire mutex: %s\n", __func__,
|
|
|
|
|
gpg_strerror (gpg_error_from_syserror ()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
unlock_reaper_list (void)
|
|
|
|
|
{
|
|
|
|
|
if (npth_mutex_unlock (&reaper_list_mutex))
|
|
|
|
|
log_fatal ("%s: failed to release mutex: %s\n", __func__,
|
|
|
|
|
gpg_strerror (gpg_error_from_syserror ()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
/* Read a fixed amount of data from READER into BUFFER. */
|
|
|
|
|
static gpg_error_t
|
|
|
|
|
read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count)
|
|
|
|
|
{
|
|
|
|
|
gpg_error_t err;
|
|
|
|
|
size_t nread;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
while (count)
|
|
|
|
|
{
|
|
|
|
|
err = ksba_reader_read (reader, buffer, count, &nread);
|
|
|
|
|
if (err)
|
|
|
|
|
return err;
|
|
|
|
|
buffer += nread;
|
|
|
|
|
count -= nread;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Release the wrapper context and kill a running wrapper process. */
|
|
|
|
|
static void
|
2011-02-04 12:57:53 +01:00
|
|
|
|
destroy_wrapper (struct wrapper_context_s *ctx)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
|
|
|
|
if (ctx->pid != (pid_t)(-1))
|
|
|
|
|
{
|
|
|
|
|
gnupg_kill_process (ctx->pid);
|
|
|
|
|
gnupg_release_process (ctx->pid);
|
|
|
|
|
}
|
|
|
|
|
ksba_reader_release (ctx->reader);
|
2018-04-27 12:03:41 +02:00
|
|
|
|
SAFE_CLOSE (ctx->fp);
|
|
|
|
|
SAFE_CLOSE (ctx->log_fp);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
xfree (ctx->line);
|
|
|
|
|
xfree (ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Print the content of LINE to thye log stream but make sure to only
|
|
|
|
|
print complete lines. Using NULL for LINE will flush any pending
|
2015-11-16 12:41:46 +01:00
|
|
|
|
output. LINE may be modified by this function. */
|
2010-07-23 16:16:14 +00:00
|
|
|
|
static void
|
|
|
|
|
print_log_line (struct wrapper_context_s *ctx, char *line)
|
|
|
|
|
{
|
|
|
|
|
char *s;
|
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
|
|
if (!line)
|
|
|
|
|
{
|
|
|
|
|
if (ctx->line && ctx->linelen)
|
|
|
|
|
{
|
|
|
|
|
|
2011-02-04 12:57:53 +01:00
|
|
|
|
log_info ("%s\n", ctx->line);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
ctx->linelen = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
while ((s = strchr (line, '\n')))
|
|
|
|
|
{
|
|
|
|
|
*s = 0;
|
|
|
|
|
if (ctx->line && ctx->linelen)
|
|
|
|
|
{
|
2011-02-04 12:57:53 +01:00
|
|
|
|
log_info ("%s", ctx->line);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
ctx->linelen = 0;
|
|
|
|
|
log_printf ("%s\n", line);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
log_info ("%s\n", line);
|
|
|
|
|
line = s + 1;
|
|
|
|
|
}
|
|
|
|
|
n = strlen (line);
|
|
|
|
|
if (n)
|
|
|
|
|
{
|
|
|
|
|
if (ctx->linelen + n + 1 >= ctx->linesize)
|
|
|
|
|
{
|
|
|
|
|
char *tmp;
|
|
|
|
|
size_t newsize;
|
|
|
|
|
|
|
|
|
|
newsize = ctx->linesize + ((n + 255) & ~255) + 1;
|
|
|
|
|
tmp = (ctx->line ? xtryrealloc (ctx->line, newsize)
|
|
|
|
|
: xtrymalloc (newsize));
|
|
|
|
|
if (!tmp)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("error printing log line: %s\n"), strerror (errno));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ctx->line = tmp;
|
|
|
|
|
ctx->linesize = newsize;
|
|
|
|
|
}
|
|
|
|
|
memcpy (ctx->line + ctx->linelen, line, n);
|
|
|
|
|
ctx->linelen += n;
|
|
|
|
|
ctx->line[ctx->linelen] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Read data from the log stream. Returns true if the log stream
|
2018-04-27 12:03:41 +02:00
|
|
|
|
* indicated EOF or error. */
|
2010-07-23 16:16:14 +00:00
|
|
|
|
static int
|
|
|
|
|
read_log_data (struct wrapper_context_s *ctx)
|
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
int rc;
|
|
|
|
|
size_t n;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
char line[256];
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
rc = es_read (ctx->log_fp, line, sizeof line - 1, &n);
|
|
|
|
|
if (rc || !n) /* Error or EOF. */
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
if (rc)
|
2018-04-27 15:20:45 +02:00
|
|
|
|
{
|
|
|
|
|
gpg_error_t err = gpg_error_from_syserror ();
|
|
|
|
|
if (gpg_err_code (err) == GPG_ERR_EAGAIN)
|
|
|
|
|
return 0;
|
|
|
|
|
log_error (_("error reading log from ldap wrapper %d: %s\n"),
|
|
|
|
|
(int)ctx->pid, gpg_strerror (err));
|
|
|
|
|
}
|
2018-04-27 12:03:41 +02:00
|
|
|
|
print_log_line (ctx, NULL); /* Flush. */
|
|
|
|
|
SAFE_CLOSE (ctx->log_fp);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
line[n] = 0;
|
|
|
|
|
print_log_line (ctx, line);
|
|
|
|
|
if (ctx->stamp != (time_t)(-1))
|
|
|
|
|
ctx->stamp = time (NULL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This function is run by a separate thread to maintain the list of
|
|
|
|
|
wrappers and to log error messages from these wrappers. */
|
|
|
|
|
void *
|
2018-04-27 15:20:45 +02:00
|
|
|
|
ldap_reaper_thread (void *dummy)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
gpg_error_t err;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
struct wrapper_context_s *ctx;
|
|
|
|
|
struct wrapper_context_s *ctx_prev;
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
struct timespec abstime;
|
|
|
|
|
struct timespec curtime;
|
|
|
|
|
struct timespec timeout;
|
2018-04-27 12:03:41 +02:00
|
|
|
|
int millisecs;
|
|
|
|
|
gpgrt_poll_t *fparray = NULL;
|
|
|
|
|
int fparraysize = 0;
|
2018-04-27 15:20:45 +02:00
|
|
|
|
int count, i;
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
int ret;
|
|
|
|
|
time_t exptime;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
(void)dummy;
|
|
|
|
|
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_clock_gettime (&abstime);
|
|
|
|
|
abstime.tv_sec += TIMERTICK_INTERVAL;
|
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
int any_action = 0;
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
/* Wait until we are needed and then setup the FPARRAY. */
|
|
|
|
|
/* Note: There is one unlock inside the block! */
|
|
|
|
|
lock_reaper_list ();
|
|
|
|
|
{
|
|
|
|
|
while (!reaper_list && !shutting_down)
|
|
|
|
|
{
|
|
|
|
|
if (npth_cond_wait (&reaper_run_cond, &reaper_list_mutex))
|
|
|
|
|
log_error ("ldap-reaper: waiting on condition failed: %s\n",
|
|
|
|
|
gpg_strerror (gpg_error_from_syserror ()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (count = 0, ctx = reaper_list; ctx; ctx = ctx->next)
|
|
|
|
|
if (ctx->log_fp)
|
|
|
|
|
count++;
|
|
|
|
|
if (count > fparraysize || !fparray)
|
|
|
|
|
{
|
|
|
|
|
/* Need to realloc the array. We simply discard it and
|
|
|
|
|
* replace it by a new one. */
|
|
|
|
|
xfree (fparray);
|
|
|
|
|
fparray = xtrycalloc (count? count : 1, sizeof *fparray);
|
|
|
|
|
if (!fparray)
|
|
|
|
|
{
|
|
|
|
|
err = gpg_error_from_syserror ();
|
|
|
|
|
log_error ("ldap-reaper can't allocate poll array: %s"
|
|
|
|
|
" - waiting 1s\n", gpg_strerror (err));
|
|
|
|
|
/* Note: Here we unlock and continue! */
|
|
|
|
|
unlock_reaper_list ();
|
|
|
|
|
npth_sleep (1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
fparraysize = count;
|
|
|
|
|
}
|
|
|
|
|
for (count = 0, ctx = reaper_list; ctx; ctx = ctx->next)
|
|
|
|
|
{
|
|
|
|
|
if (ctx->log_fp)
|
|
|
|
|
{
|
|
|
|
|
log_assert (count < fparraysize);
|
|
|
|
|
fparray[count].stream = ctx->log_fp;
|
|
|
|
|
fparray[count].want_read = 1;
|
|
|
|
|
fparray[count].ignore = 0;
|
|
|
|
|
ctx->reaper_idx = count;
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ctx->reaper_idx = -1;
|
|
|
|
|
fparray[count].ignore = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (i=count; i < fparraysize; i++)
|
|
|
|
|
fparray[i].ignore = 1;
|
|
|
|
|
}
|
|
|
|
|
unlock_reaper_list (); /* Note the one unlock inside the block. */
|
|
|
|
|
|
|
|
|
|
/* Compute the next timeout. */
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_clock_gettime (&curtime);
|
|
|
|
|
if (!(npth_timercmp (&curtime, &abstime, <)))
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
/* Inactivity is checked below. Nothing else to do. */
|
|
|
|
|
npth_clock_gettime (&abstime);
|
|
|
|
|
abstime.tv_sec += TIMERTICK_INTERVAL;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_timersub (&abstime, &curtime, &timeout);
|
2018-04-27 12:03:41 +02:00
|
|
|
|
millisecs = timeout.tv_sec * 1000;
|
|
|
|
|
millisecs += timeout.tv_nsec / 1000000;
|
|
|
|
|
if (millisecs < 0)
|
|
|
|
|
millisecs = 1;
|
|
|
|
|
|
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
{
|
2018-04-27 15:20:45 +02:00
|
|
|
|
log_debug ("ldap-reaper: next run (count=%d size=%d, timeout=%d)\n",
|
|
|
|
|
count, fparraysize, millisecs);
|
2018-04-27 12:03:41 +02:00
|
|
|
|
for (count=0; count < fparraysize; count++)
|
|
|
|
|
if (!fparray[count].ignore)
|
|
|
|
|
log_debug ("ldap-reaper: fp[%d] stream=%p want=%d\n",
|
|
|
|
|
count, fparray[count].stream,fparray[count].want_read);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = es_poll (fparray, fparraysize, millisecs);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
err = gpg_error_from_syserror ();
|
|
|
|
|
log_error ("ldap-reaper failed to poll: %s"
|
|
|
|
|
" - waiting 1s\n", gpg_strerror (err));
|
|
|
|
|
/* In case the reason for the error is a too large array, we
|
|
|
|
|
* release it so that it will be allocated smaller in the
|
|
|
|
|
* next round. */
|
|
|
|
|
xfree (fparray);
|
|
|
|
|
fparray = NULL;
|
|
|
|
|
fparraysize = 0;
|
|
|
|
|
npth_sleep (1);
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
{
|
|
|
|
|
for (count=0; count < fparraysize; count++)
|
|
|
|
|
if (!fparray[count].ignore)
|
2018-04-27 15:20:45 +02:00
|
|
|
|
log_debug ("ldap-reaper: fp[%d] stream=%p r=%d %c%c%c%c%c%c%c\n",
|
|
|
|
|
count, fparray[count].stream, ret,
|
|
|
|
|
fparray[count].got_read? 'r':'-',
|
|
|
|
|
fparray[count].got_write?'w':'-',
|
|
|
|
|
fparray[count].got_oob? 'o':'-',
|
|
|
|
|
fparray[count].got_rdhup?'H':'-',
|
|
|
|
|
fparray[count].got_err? 'e':'-',
|
|
|
|
|
fparray[count].got_hup? 'h':'-',
|
|
|
|
|
fparray[count].got_nval? 'n':'-');
|
2018-04-27 12:03:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
/* All timestamps before exptime should be considered expired. */
|
|
|
|
|
exptime = time (NULL);
|
|
|
|
|
if (exptime > INACTIVITY_TIMEOUT)
|
|
|
|
|
exptime -= INACTIVITY_TIMEOUT;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
lock_reaper_list ();
|
|
|
|
|
{
|
|
|
|
|
for (ctx = reaper_list; ctx; ctx = ctx->next)
|
|
|
|
|
{
|
|
|
|
|
/* Check whether there is any logging to be done. We need
|
|
|
|
|
* to check FPARRAYSIZE because it can be 0 in case
|
|
|
|
|
* es_poll returned a timeout. */
|
|
|
|
|
if (fparraysize && ctx->log_fp && ctx->reaper_idx >= 0)
|
|
|
|
|
{
|
|
|
|
|
log_assert (ctx->reaper_idx < fparraysize);
|
|
|
|
|
if (fparray[ctx->reaper_idx].got_read)
|
|
|
|
|
{
|
|
|
|
|
if (read_log_data (ctx))
|
|
|
|
|
{
|
|
|
|
|
SAFE_CLOSE (ctx->log_fp);
|
|
|
|
|
any_action = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check whether the process is still running. */
|
|
|
|
|
if (ctx->pid != (pid_t)(-1))
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
err = gnupg_wait_process ("[dirmngr_ldap]", ctx->pid, 0,
|
|
|
|
|
&status);
|
|
|
|
|
if (!err)
|
|
|
|
|
{
|
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
log_info (_("ldap wrapper %d ready"), (int)ctx->pid);
|
|
|
|
|
ctx->ready = 1;
|
|
|
|
|
gnupg_release_process (ctx->pid);
|
|
|
|
|
ctx->pid = (pid_t)(-1);
|
|
|
|
|
any_action = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (gpg_err_code (err) == GPG_ERR_GENERAL)
|
|
|
|
|
{
|
|
|
|
|
if (status == 10)
|
|
|
|
|
log_info (_("ldap wrapper %d ready: timeout\n"),
|
|
|
|
|
(int)ctx->pid);
|
|
|
|
|
else
|
|
|
|
|
log_info (_("ldap wrapper %d ready: exitcode=%d\n"),
|
|
|
|
|
(int)ctx->pid, status);
|
|
|
|
|
ctx->ready = 1;
|
|
|
|
|
gnupg_release_process (ctx->pid);
|
|
|
|
|
ctx->pid = (pid_t)(-1);
|
|
|
|
|
any_action = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (gpg_err_code (err) != GPG_ERR_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("waiting for ldap wrapper %d failed: %s\n"),
|
|
|
|
|
(int)ctx->pid, gpg_strerror (err));
|
|
|
|
|
any_action = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check whether we should terminate the process. */
|
|
|
|
|
if (ctx->pid != (pid_t)(-1)
|
|
|
|
|
&& ctx->stamp != (time_t)(-1) && ctx->stamp < exptime)
|
|
|
|
|
{
|
|
|
|
|
gnupg_kill_process (ctx->pid);
|
|
|
|
|
ctx->stamp = (time_t)(-1);
|
|
|
|
|
log_info (_("ldap wrapper %d stalled - killing\n"),
|
|
|
|
|
(int)ctx->pid);
|
|
|
|
|
/* We need to close the log stream because the cleanup
|
|
|
|
|
* loop waits for it. */
|
|
|
|
|
SAFE_CLOSE (ctx->log_fp);
|
|
|
|
|
any_action = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
/* If something has been printed to the log file or we got an
|
|
|
|
|
* EOF from a wrapper, we now print the list of active
|
|
|
|
|
* wrappers. */
|
|
|
|
|
if (any_action && DBG_EXTPROG)
|
|
|
|
|
{
|
|
|
|
|
log_debug ("ldap worker stati:\n");
|
|
|
|
|
for (ctx = reaper_list; ctx; ctx = ctx->next)
|
|
|
|
|
log_debug (" c=%p pid=%d/%d rdr=%p logfp=%p"
|
|
|
|
|
" ctrl=%p/%d la=%lu rdy=%d\n",
|
|
|
|
|
ctx,
|
|
|
|
|
(int)ctx->pid, (int)ctx->printable_pid,
|
|
|
|
|
ctx->reader, ctx->log_fp,
|
|
|
|
|
ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0,
|
|
|
|
|
(unsigned long)ctx->stamp, ctx->ready);
|
|
|
|
|
}
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
/* An extra loop to check whether ready marked wrappers may be
|
|
|
|
|
* removed. We may only do so if the ksba reader object is
|
|
|
|
|
* not anymore in use or we are in shutdown state. */
|
|
|
|
|
again:
|
|
|
|
|
for (ctx_prev=NULL, ctx=reaper_list; ctx; ctx_prev=ctx, ctx=ctx->next)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
2018-04-27 15:20:45 +02:00
|
|
|
|
if (ctx->ready
|
|
|
|
|
&& ((!ctx->log_fp && !ctx->reader) || shutting_down))
|
|
|
|
|
{
|
|
|
|
|
if (ctx_prev)
|
|
|
|
|
ctx_prev->next = ctx->next;
|
|
|
|
|
else
|
|
|
|
|
reaper_list = ctx->next;
|
|
|
|
|
destroy_wrapper (ctx);
|
|
|
|
|
goto again;
|
|
|
|
|
}
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
2018-04-27 15:20:45 +02:00
|
|
|
|
}
|
|
|
|
|
unlock_reaper_list ();
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
2018-04-27 15:20:45 +02:00
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
/*NOTREACHED*/
|
|
|
|
|
return NULL; /* Make the compiler happy. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Start the reaper thread for the ldap wrapper. */
|
|
|
|
|
void
|
2018-04-27 15:20:45 +02:00
|
|
|
|
ldap_reaper_launch_thread (void)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
|
|
|
|
static int done;
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_attr_t tattr;
|
|
|
|
|
npth_t thread;
|
|
|
|
|
int err;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
if (done)
|
|
|
|
|
return;
|
|
|
|
|
done = 1;
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
/* Static init does not yet work in W32 nPth. */
|
|
|
|
|
if (npth_cond_init (&reaper_run_cond, NULL))
|
|
|
|
|
log_fatal ("%s: failed to init condition variabale: %s\n",
|
|
|
|
|
__func__, gpg_strerror (gpg_error_from_syserror ()));
|
|
|
|
|
#endif
|
|
|
|
|
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_attr_init (&tattr);
|
|
|
|
|
npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
if (npth_create (&thread, &tattr, ldap_reaper_thread, NULL))
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
2018-04-27 15:20:45 +02:00
|
|
|
|
err = gpg_error_from_syserror ();
|
|
|
|
|
log_error ("error spawning ldap reaper reaper thread: %s\n",
|
|
|
|
|
gpg_strerror (err) );
|
2010-07-23 16:16:14 +00:00
|
|
|
|
dirmngr_exit (1);
|
|
|
|
|
}
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_setname_np (thread, "ldap-reaper");
|
|
|
|
|
npth_attr_destroy (&tattr);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Wait until all ldap wrappers have terminated. We assume that the
|
|
|
|
|
kill has already been sent to all of them. */
|
|
|
|
|
void
|
|
|
|
|
ldap_wrapper_wait_connections ()
|
|
|
|
|
{
|
2018-04-27 15:20:45 +02:00
|
|
|
|
lock_reaper_list ();
|
|
|
|
|
{
|
|
|
|
|
shutting_down = 1;
|
|
|
|
|
if (npth_cond_signal (&reaper_run_cond))
|
|
|
|
|
log_error ("%s: Ooops: signaling condition failed: %s\n",
|
|
|
|
|
__func__, gpg_strerror (gpg_error_from_syserror ()));
|
|
|
|
|
}
|
|
|
|
|
unlock_reaper_list ();
|
|
|
|
|
while (reaper_list)
|
2012-02-28 17:26:32 +01:00
|
|
|
|
npth_usleep (200);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This function is to be used to release a context associated with the
|
|
|
|
|
given reader object. */
|
|
|
|
|
void
|
|
|
|
|
ldap_wrapper_release_context (ksba_reader_t reader)
|
|
|
|
|
{
|
|
|
|
|
struct wrapper_context_s *ctx;
|
|
|
|
|
|
|
|
|
|
if (!reader )
|
|
|
|
|
return;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
lock_reaper_list ();
|
|
|
|
|
{
|
|
|
|
|
for (ctx=reaper_list; ctx; ctx=ctx->next)
|
|
|
|
|
if (ctx->reader == reader)
|
|
|
|
|
{
|
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
log_debug ("releasing ldap worker c=%p pid=%d/%d rdr=%p"
|
|
|
|
|
" ctrl=%p/%d\n", ctx,
|
|
|
|
|
(int)ctx->pid, (int)ctx->printable_pid,
|
|
|
|
|
ctx->reader,
|
|
|
|
|
ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0);
|
|
|
|
|
|
|
|
|
|
ctx->reader = NULL;
|
|
|
|
|
SAFE_CLOSE (ctx->fp);
|
|
|
|
|
if (ctx->ctrl)
|
|
|
|
|
{
|
|
|
|
|
ctx->ctrl->refcount--;
|
|
|
|
|
ctx->ctrl = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (ctx->fp_err)
|
|
|
|
|
log_info ("%s: reading from ldap wrapper %d failed: %s\n",
|
|
|
|
|
__func__, ctx->printable_pid, gpg_strerror (ctx->fp_err));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unlock_reaper_list ();
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
/* Cleanup all resources held by the connection associated with
|
|
|
|
|
CTRL. This is used after a cancel to kill running wrappers. */
|
|
|
|
|
void
|
|
|
|
|
ldap_wrapper_connection_cleanup (ctrl_t ctrl)
|
|
|
|
|
{
|
|
|
|
|
struct wrapper_context_s *ctx;
|
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
lock_reaper_list ();
|
|
|
|
|
{
|
|
|
|
|
for (ctx=reaper_list; ctx; ctx=ctx->next)
|
|
|
|
|
if (ctx->ctrl && ctx->ctrl == ctrl)
|
|
|
|
|
{
|
|
|
|
|
ctx->ctrl->refcount--;
|
|
|
|
|
ctx->ctrl = NULL;
|
|
|
|
|
if (ctx->pid != (pid_t)(-1))
|
|
|
|
|
gnupg_kill_process (ctx->pid);
|
|
|
|
|
if (ctx->fp_err)
|
|
|
|
|
log_info ("%s: reading from ldap wrapper %d failed: %s\n",
|
|
|
|
|
__func__, ctx->printable_pid, gpg_strerror (ctx->fp_err));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unlock_reaper_list ();
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
/* This is the callback used by the ldap wrapper to feed the ksba
|
2018-04-27 12:03:41 +02:00
|
|
|
|
* reader with the wrapper's stdout. See the description of
|
|
|
|
|
* ksba_reader_set_cb for details. */
|
2011-02-04 12:57:53 +01:00
|
|
|
|
static int
|
2010-07-23 16:16:14 +00:00
|
|
|
|
reader_callback (void *cb_value, char *buffer, size_t count, size_t *nread)
|
|
|
|
|
{
|
|
|
|
|
struct wrapper_context_s *ctx = cb_value;
|
|
|
|
|
size_t nleft = count;
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
struct timespec abstime;
|
|
|
|
|
struct timespec curtime;
|
|
|
|
|
struct timespec timeout;
|
2018-04-27 12:03:41 +02:00
|
|
|
|
int millisecs;
|
|
|
|
|
gpgrt_poll_t fparray[1];
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
int ret;
|
2018-04-27 12:03:41 +02:00
|
|
|
|
gpg_error_t err;
|
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
/* FIXME: We might want to add some internal buffering because the
|
|
|
|
|
ksba code does not do any buffering for itself (because a ksba
|
|
|
|
|
reader may be detached from another stream to read other data and
|
2018-04-27 12:03:41 +02:00
|
|
|
|
then it would be cumbersome to get back already buffered stuff). */
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
if (!buffer && !count && !nread)
|
|
|
|
|
return -1; /* Rewind is not supported. */
|
|
|
|
|
|
More cleanup of "allow to".
* README, agent/command.c, agent/keyformat.txt, common/i18n.c,
common/iobuf.c, common/keyserver.h, dirmngr/cdblib.c,
dirmngr/ldap-wrapper.c, doc/DETAILS, doc/TRANSLATE,
doc/announce-2.1.txt, doc/gpg.texi, doc/gpgsm.texi,
doc/scdaemon.texi, doc/tools.texi, doc/whats-new-in-2.1.txt,
g10/export.c, g10/getkey.c, g10/import.c, g10/keyedit.c, m4/ksba.m4,
m4/libgcrypt.m4, m4/ntbtls.m4, po/ca.po, po/cs.po, po/da.po,
po/de.po, po/el.po, po/eo.po, po/es.po, po/et.po, po/fi.po,
po/fr.po, po/gl.po, po/hu.po, po/id.po, po/it.po, po/ja.po,
po/nb.po, po/pl.po, po/pt.po, po/ro.po, po/ru.po, po/sk.po,
po/sv.po, po/tr.po, po/uk.po, po/zh_CN.po, po/zh_TW.po,
scd/app-p15.c, scd/ccid-driver.c, scd/command.c, sm/gpgsm.c,
sm/sign.c, tools/gpgconf-comp.c, tools/gpgtar.h: replace "Allow to"
with clearer text.
In standard English, the normal construction is "${XXX} allows ${YYY}
to" -- that is, the subject (${XXX}) of the sentence is allowing the
object (${YYY}) to do something. When the object is missing, the
phrasing sounds awkward, even if the object is implied by context.
There's almost always a better construction that isn't as awkward.
These changes should make the language a bit clearer.
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2016-08-01 22:19:17 -04:00
|
|
|
|
/* If we ever encountered a read error, don't continue (we don't want to
|
|
|
|
|
possibly overwrite the last error cause). Bail out also if the
|
2010-07-23 16:16:14 +00:00
|
|
|
|
file descriptor has been closed. */
|
2018-04-27 12:03:41 +02:00
|
|
|
|
if (ctx->fp_err || !ctx->fp)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
|
|
|
|
*nread = 0;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
memset (fparray, 0, sizeof fparray);
|
|
|
|
|
fparray[0].stream = ctx->fp;
|
|
|
|
|
fparray[0].want_read = 1;
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
|
|
|
|
|
npth_clock_gettime (&abstime);
|
|
|
|
|
abstime.tv_sec += TIMERTICK_INTERVAL;
|
|
|
|
|
|
2010-07-23 16:16:14 +00:00
|
|
|
|
while (nleft > 0)
|
|
|
|
|
{
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_clock_gettime (&curtime);
|
|
|
|
|
if (!(npth_timercmp (&curtime, &abstime, <)))
|
|
|
|
|
{
|
|
|
|
|
err = dirmngr_tick (ctx->ctrl);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
if (err)
|
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
ctx->fp_err = err;
|
|
|
|
|
SAFE_CLOSE (ctx->fp);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
npth_clock_gettime (&abstime);
|
|
|
|
|
abstime.tv_sec += TIMERTICK_INTERVAL;
|
|
|
|
|
}
|
|
|
|
|
npth_timersub (&abstime, &curtime, &timeout);
|
2018-04-27 12:03:41 +02:00
|
|
|
|
millisecs = timeout.tv_sec * 1000;
|
|
|
|
|
millisecs += timeout.tv_nsec / 1000000;
|
|
|
|
|
if (millisecs < 0)
|
|
|
|
|
millisecs = 1;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
2018-04-27 15:20:45 +02:00
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
{
|
|
|
|
|
log_debug ("%s: fp[0] stream=%p want=%d\n",
|
|
|
|
|
__func__, fparray[0].stream,fparray[0].want_read);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
ret = es_poll (fparray, DIM (fparray), millisecs);
|
|
|
|
|
if (ret < 0)
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
ctx->fp_err = gpg_error_from_syserror ();
|
|
|
|
|
log_error ("error polling stdout of ldap wrapper %d: %s\n",
|
|
|
|
|
ctx->printable_pid, gpg_strerror (ctx->fp_err));
|
|
|
|
|
SAFE_CLOSE (ctx->fp);
|
Port to npth.
* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
2012-01-03 22:12:37 +01:00
|
|
|
|
return -1;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
2018-04-27 15:20:45 +02:00
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
{
|
|
|
|
|
log_debug ("%s: fp[0] stream=%p r=%d %c%c%c%c%c%c%c\n",
|
|
|
|
|
__func__, fparray[0].stream, ret,
|
|
|
|
|
fparray[0].got_read? 'r':'-',
|
|
|
|
|
fparray[0].got_write?'w':'-',
|
|
|
|
|
fparray[0].got_oob? 'o':'-',
|
|
|
|
|
fparray[0].got_rdhup?'H':'-',
|
|
|
|
|
fparray[0].got_err? 'e':'-',
|
|
|
|
|
fparray[0].got_hup? 'h':'-',
|
|
|
|
|
fparray[0].got_nval? 'n':'-');
|
|
|
|
|
}
|
2018-04-27 12:03:41 +02:00
|
|
|
|
if (!ret)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
/* Timeout. Will be handled when calculating the next timeout. */
|
|
|
|
|
continue;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
2018-04-27 12:03:41 +02:00
|
|
|
|
|
|
|
|
|
if (fparray[0].got_read)
|
2010-07-23 16:16:14 +00:00
|
|
|
|
{
|
2018-04-27 12:03:41 +02:00
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
|
|
if (es_read (ctx->fp, buffer, nleft, &n))
|
|
|
|
|
{
|
|
|
|
|
ctx->fp_err = gpg_error_from_syserror ();
|
2018-04-27 15:20:45 +02:00
|
|
|
|
if (gpg_err_code (ctx->fp_err) == GPG_ERR_EAGAIN)
|
|
|
|
|
ctx->fp_err = 0;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_error ("%s: error reading: %s (%d)\n",
|
|
|
|
|
__func__, gpg_strerror (ctx->fp_err), ctx->fp_err);
|
|
|
|
|
SAFE_CLOSE (ctx->fp);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2018-04-27 12:03:41 +02:00
|
|
|
|
}
|
|
|
|
|
else if (!n) /* EOF */
|
|
|
|
|
{
|
|
|
|
|
if (nleft == count)
|
|
|
|
|
return -1; /* EOF. */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
nleft -= n;
|
|
|
|
|
buffer += n;
|
|
|
|
|
if (n > 0 && ctx->stamp != (time_t)(-1))
|
|
|
|
|
ctx->stamp = time (NULL);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*nread = count - nleft;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
|
2015-03-19 11:14:52 +01:00
|
|
|
|
/* Fork and exec the LDAP wrapper and return a new libksba reader
|
2010-07-23 16:16:14 +00:00
|
|
|
|
object at READER. ARGV is a NULL terminated list of arguments for
|
|
|
|
|
the wrapper. The function returns 0 on success or an error code.
|
|
|
|
|
|
|
|
|
|
Special hack to avoid passing a password through the command line
|
|
|
|
|
which is globally visible: If the first element of ARGV is "--pass"
|
|
|
|
|
it will be removed and instead the environment variable
|
|
|
|
|
DIRMNGR_LDAP_PASS will be set to the next value of ARGV. On modern
|
|
|
|
|
OSes the environment is not visible to other users. For those old
|
|
|
|
|
systems where it can't be avoided, we don't want to go into the
|
|
|
|
|
hassle of passing the password via stdin; it's just too complicated
|
|
|
|
|
and an LDAP password used for public directory lookups should not
|
|
|
|
|
be that confidential. */
|
|
|
|
|
gpg_error_t
|
|
|
|
|
ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[])
|
|
|
|
|
{
|
|
|
|
|
gpg_error_t err;
|
|
|
|
|
pid_t pid;
|
|
|
|
|
struct wrapper_context_s *ctx;
|
|
|
|
|
int i;
|
|
|
|
|
int j;
|
|
|
|
|
const char **arg_list;
|
|
|
|
|
const char *pgmname;
|
2018-04-27 12:03:41 +02:00
|
|
|
|
estream_t outfp, errfp;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
/* It would be too simple to connect stderr just to our logging
|
|
|
|
|
stream. The problem is that if we are running multi-threaded
|
|
|
|
|
everything gets intermixed. Clearly we don't want this. So the
|
|
|
|
|
only viable solutions are either to have another thread
|
|
|
|
|
responsible for logging the messages or to add an option to the
|
|
|
|
|
wrapper module to do the logging on its own. Given that we anyway
|
2016-10-31 19:52:31 -04:00
|
|
|
|
need a way to reap the child process and this is best done using a
|
|
|
|
|
general reaping thread, that thread can do the logging too. */
|
2018-04-27 15:20:45 +02:00
|
|
|
|
ldap_reaper_launch_thread ();
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
*reader = NULL;
|
|
|
|
|
|
|
|
|
|
/* Files: We need to prepare stdin and stdout. We get stderr from
|
|
|
|
|
the function. */
|
|
|
|
|
if (!opt.ldap_wrapper_program || !*opt.ldap_wrapper_program)
|
|
|
|
|
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR_LDAP);
|
|
|
|
|
else
|
|
|
|
|
pgmname = opt.ldap_wrapper_program;
|
|
|
|
|
|
|
|
|
|
/* Create command line argument array. */
|
|
|
|
|
for (i = 0; argv[i]; i++)
|
|
|
|
|
;
|
|
|
|
|
arg_list = xtrycalloc (i + 2, sizeof *arg_list);
|
|
|
|
|
if (!arg_list)
|
|
|
|
|
{
|
|
|
|
|
err = gpg_error_from_syserror ();
|
|
|
|
|
log_error (_("error allocating memory: %s\n"), strerror (errno));
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
for (i = j = 0; argv[i]; i++, j++)
|
|
|
|
|
if (!i && argv[i + 1] && !strcmp (*argv, "--pass"))
|
|
|
|
|
{
|
|
|
|
|
arg_list[j] = "--env-pass";
|
|
|
|
|
setenv ("DIRMNGR_LDAP_PASS", argv[1], 1);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
arg_list[j] = (char*) argv[i];
|
|
|
|
|
|
|
|
|
|
ctx = xtrycalloc (1, sizeof *ctx);
|
|
|
|
|
if (!ctx)
|
|
|
|
|
{
|
|
|
|
|
err = gpg_error_from_syserror ();
|
|
|
|
|
log_error (_("error allocating memory: %s\n"), strerror (errno));
|
|
|
|
|
xfree (arg_list);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
err = gnupg_spawn_process (pgmname, arg_list,
|
|
|
|
|
NULL, NULL, GNUPG_SPAWN_NONBLOCK,
|
|
|
|
|
NULL, &outfp, &errfp, &pid);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
xfree (arg_list);
|
|
|
|
|
if (err)
|
|
|
|
|
{
|
|
|
|
|
xfree (ctx);
|
2018-04-27 12:03:41 +02:00
|
|
|
|
log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err));
|
2010-07-23 16:16:14 +00:00
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx->pid = pid;
|
|
|
|
|
ctx->printable_pid = (int) pid;
|
2018-04-27 12:03:41 +02:00
|
|
|
|
ctx->fp = outfp;
|
|
|
|
|
ctx->log_fp = errfp;
|
2010-07-23 16:16:14 +00:00
|
|
|
|
ctx->ctrl = ctrl;
|
|
|
|
|
ctrl->refcount++;
|
|
|
|
|
ctx->stamp = time (NULL);
|
|
|
|
|
|
|
|
|
|
err = ksba_reader_new (reader);
|
|
|
|
|
if (!err)
|
|
|
|
|
err = ksba_reader_set_cb (*reader, reader_callback, ctx);
|
|
|
|
|
if (err)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("error initializing reader object: %s\n"),
|
|
|
|
|
gpg_strerror (err));
|
|
|
|
|
destroy_wrapper (ctx);
|
|
|
|
|
ksba_reader_release (*reader);
|
|
|
|
|
*reader = NULL;
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hook the context into our list of running wrappers. */
|
2018-04-27 15:20:45 +02:00
|
|
|
|
lock_reaper_list ();
|
|
|
|
|
{
|
|
|
|
|
ctx->reader = *reader;
|
|
|
|
|
ctx->next = reaper_list;
|
|
|
|
|
reaper_list = ctx;
|
|
|
|
|
if (npth_cond_signal (&reaper_run_cond))
|
|
|
|
|
log_error ("ldap-wrapper: Ooops: signaling condition failed: %s (%d)\n",
|
|
|
|
|
gpg_strerror (gpg_error_from_syserror ()), errno);
|
|
|
|
|
}
|
|
|
|
|
unlock_reaper_list ();
|
|
|
|
|
|
2018-04-27 12:03:41 +02:00
|
|
|
|
if (DBG_EXTPROG)
|
|
|
|
|
log_debug ("ldap wrapper %d started (%p, %s)\n",
|
|
|
|
|
(int)ctx->pid, ctx->reader, pgmname);
|
2010-07-23 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
/* Need to wait for the first byte so we are able to detect an empty
|
|
|
|
|
output and not let the consumer see an EOF without further error
|
|
|
|
|
indications. The CRL loading logic assumes that after return
|
|
|
|
|
from this function, a failed search (e.g. host not found ) is
|
|
|
|
|
indicated right away. */
|
|
|
|
|
{
|
|
|
|
|
unsigned char c;
|
|
|
|
|
|
|
|
|
|
err = read_buffer (*reader, &c, 1);
|
|
|
|
|
if (err)
|
|
|
|
|
{
|
|
|
|
|
ldap_wrapper_release_context (*reader);
|
|
|
|
|
ksba_reader_release (*reader);
|
|
|
|
|
*reader = NULL;
|
|
|
|
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
|
|
|
|
return gpg_error (GPG_ERR_NO_DATA);
|
|
|
|
|
else
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
ksba_reader_unread (*reader, &c, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|