---
daemon/automount.c | 31 ++++++++++++++++++++++++++-----
include/log.h | 4 +++-
lib/log.c | 9 ++++++++-
man/automount.8 | 9 +++++++--
modules/lookup_ldap.c | 37 +++++++++++++++++++++++++++++++++++++
5 files changed, 81 insertions(+), 9 deletions(-)
diff --git a/daemon/automount.c b/daemon/automount.c
index 32f95a5..ce79078 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1413,6 +1413,21 @@ static unsigned long getnumopt(char *str, char option)
return val;
}
+static long getsnumopt(char *str, char option)
+{
+ long val;
+ char *end;
+
+ val = strtol(str, &end, 0);
+ if (!*str || *end) {
+ fprintf(stderr,
+ "%s: option -%c requires a numeric argument, got %s\n",
+ program, option, str);
+ exit(1);
+ }
+ return val;
+}
+
static void do_master_cleanup_unlock(void *arg)
{
int status;
@@ -2017,7 +2032,9 @@ static void usage(void)
" maximum wait time (seconds) for master\n"
" map to become available\n"
" -v --verbose be verbose\n"
- " -d --debug log debuging info\n"
+ " -d[level]\n"
+ " --debug[=level]\n"
+ " log debugging info\n"
" -Dvariable=value, --define variable=value\n"
" define global macro variable\n"
" -S --systemd-service\n"
@@ -2282,18 +2299,19 @@ int main(int argc, char *argv[])
int logpri = -1;
unsigned int flags;
unsigned int logging;
+ int debug_level = 0;
unsigned master_read;
int master_wait;
time_t timeout;
time_t age = monotonic_time(NULL);
struct rlimit rlim;
- const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM:";
+ const char *options = "+hp:t:vmd::D:SfVrO:l:n:CFUM:";
static const struct option long_options[] = {
{"help", 0, 0, 'h'},
{"pid-file", 1, 0, 'p'},
{"timeout", 1, 0, 't'},
{"verbose", 0, 0, 'v'},
- {"debug", 0, 0, 'd'},
+ {"debug", 2, 0, 'd'},
{"define", 1, 0, 'D'},
{"systemd-service", 0, 0, 'S'},
{"foreground", 0, 0, 'f'},
@@ -2363,6 +2381,8 @@ int main(int argc, char *argv[])
case 'd':
logging |= LOGOPT_DEBUG;
+ if (optarg)
+ debug_level = getsnumopt(optarg, opt);
break;
case 'D':
@@ -2439,7 +2459,8 @@ int main(int argc, char *argv[])
case '?':
case ':':
- printf("%s: Ambiguous or unknown options\n", program);
+ fprintf(stderr, "%s: Ambiguous or unknown options\n", program);
+ fprintf(stderr, "Try `%s --help` for more information\n", program);
exit(1);
}
}
@@ -2448,7 +2469,7 @@ int main(int argc, char *argv[])
set_log_verbose();
if (logging & LOGOPT_DEBUG)
- set_log_debug();
+ set_log_debug(debug_level);
if (geteuid() != 0) {
fprintf(stderr, "%s: this program must be run by root.\n",
diff --git a/include/log.h b/include/log.h
index a7b09f9..3ec8f0c 100644
--- a/include/log.h
+++ b/include/log.h
@@ -31,12 +31,14 @@ struct autofs_point;
extern void set_log_norm(void);
extern void set_log_verbose(void);
-extern void set_log_debug(void);
+extern void set_log_debug(int level);
extern void set_log_norm_ap(struct autofs_point *ap);
extern void set_log_verbose_ap(struct autofs_point *ap);
extern void set_log_debug_ap(struct autofs_point *ap);
extern void set_mnt_logging(unsigned global_logopt);
+extern int get_log_debug_level(void);
+
extern void open_log(void);
extern void log_to_stderr(void);
diff --git a/lib/log.c b/lib/log.c
index 43eccc0..9567460 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -31,6 +31,7 @@ static unsigned int logging_to_syslog = 0;
/* log notification level */
static unsigned int do_verbose = 0; /* Verbose feedback option */
static unsigned int do_debug = 0; /* Full debug output */
+static unsigned int debug_level = 0; /* Level for libldap debug output */
static char *prepare_attempt_prefix(const char *msg)
{
@@ -57,6 +58,11 @@ static char *prepare_attempt_prefix(const char *msg)
return prefixed_msg;
}
+int get_log_debug_level(void)
+{
+ return debug_level;
+}
+
void set_log_norm(void)
{
do_verbose = 0;
@@ -70,9 +76,10 @@ void set_log_verbose(void)
return;
}
-void set_log_debug(void)
+void set_log_debug(int level)
{
do_debug = 1;
+ debug_level = level;
return;
}
diff --git a/man/automount.8 b/man/automount.8
index 1061c9d..2d2b56f 100644
--- a/man/automount.8
+++ b/man/automount.8
@@ -48,9 +48,14 @@ Set the default timeout for caching failed key lookups. The default is 60 second
Enables logging of general status and progress messages for all
autofs managed mounts.
.TP
-.I "\-d, \-\-debug"
+\fB\-d\fR[\fILEVEL\fR], \fB\-\-debug\fR[=\fILEVEL\fR]
Enables logging of general status and progress messages as well as
-debugging messages for all autofs managed mounts.
+debugging messages for all autofs managed mounts. The default \fILEVEL\fR is 0.
+automounter must perform OpenLDAP authenticated binds for optional argument
+\fILEVEL\fR to have any effect. OpenLDAP uses a bitmap to enable debugging for
+specific components. Debug \fILEVEL\fR=0 disables libldap deugging.
+For further details see
+.BR slapd (8).
.TP
.I "\-Dvariable=value, --define variable=value"
Define a global macro substitution variable. Global definitions
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 14589c3..df9376e 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -155,6 +155,18 @@ int ldap_parse_page_control(LDAP *ldap, LDAPControl **controls,
}
#endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */
+static void autofs_ldap_debug(const char *buf)
+{
+ char *msg;
+
+ if (buf) {
+ msg = strdup(buf);
+ msg[strcspn(msg, "\n")] = '\0';
+ log_debug(LOGOPT_DEBUG, "libldap: %s", msg);
+ free(msg);
+ }
+}
+
static void ldapinit_mutex_lock(void)
{
int status = pthread_mutex_lock(&ldapinit_mutex);
@@ -259,11 +271,36 @@ LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_conte
LDAP *ldap = NULL;
struct timeval timeout = { ctxt->timeout, 0 };
struct timeval net_timeout = { ctxt->network_timeout, 0 };
+ int ldap_library_debug_level;
int rv;
ctxt->version = 3;
+ ldap_library_debug_level = get_log_debug_level();
+ if (ldap_library_debug_level == -1 || ldap_library_debug_level > 0) {
+ rv = ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
+ &ldap_library_debug_level);
+ if (rv != LBER_OPT_SUCCESS)
+ info(logopt, MODPREFIX
+ "failed to set LBER debug level to %d, ignored",
+ ldap_library_debug_level);
+ rv = ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN,
+ autofs_ldap_debug);
+ if (rv != LBER_OPT_SUCCESS)
+ info(logopt, MODPREFIX
+ "Failed to set LBER_OPT_LOG_PRINT_FN, ignored");
+ rv = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL,
+ &ldap_library_debug_level);
+ if (rv != LDAP_OPT_SUCCESS)
+ info(logopt, MODPREFIX
+ "failed to set LDAP debug level to %d, ignored",
+ ldap_library_debug_level);
+ }
+
/* Initialize the LDAP context. */
+ debug(logopt, MODPREFIX
+ "ldap_initialize( %s )",
+ uri ? uri : "default");
rv = ldap_initialize(&ldap, uri);
if (rv != LDAP_OPT_SUCCESS) {
info(logopt, MODPREFIX