[autofs] * Fri Nov 8 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-32.fc15 - always read file maps mount lookup

Ian Kent iankent at fedoraproject.org
Mon Nov 8 04:01:13 UTC 2010


commit ab7ff7de49129edc31a46563ff098bd611af51b5
Author: Ian Kent <raven at themaw.net>
Date:   Mon Nov 8 11:59:40 2010 +0800

    * Fri Nov 8 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-32.fc15
    - always read file maps mount lookup map read fix.
    - fix direct map not updating on reread.
    - add external bind method.
    - fix add simple bind auth.
    - add option to dump configured automount maps.
    - wait for master map to be available at start.

 ...-read-file-maps-mount-lookup-map-read-fix.patch |   44 +++
 autofs-5.0.5-add-dump-maps-option.patch            |  354 +++++++++++++++++
 autofs-5.0.5-add-external-bind-method.patch        |  404 ++++++++++++++++++++
 autofs-5.0.5-fix-add-simple-bind-auth.patch        |   72 ++++
 ...0.5-fix-direct-map-not-updating-on-reread.patch |   40 ++
 autofs-5.0.5-fix-submount-shutdown-wait.patch      |   43 ++
 ....5-wait-for-master-map-available-at-start.patch |  142 +++++++
 autofs.spec                                        |   24 ++-
 8 files changed, 1122 insertions(+), 1 deletions(-)
---
diff --git a/autofs-5.0.4-always-read-file-maps-mount-lookup-map-read-fix.patch b/autofs-5.0.4-always-read-file-maps-mount-lookup-map-read-fix.patch
new file mode 100644
index 0000000..07f7e7f
--- /dev/null
+++ b/autofs-5.0.4-always-read-file-maps-mount-lookup-map-read-fix.patch
@@ -0,0 +1,44 @@
+autofs-5.0.5 - always read file maps mount lookup map read fix
+
+From: Ian Kent <raven at themaw.net>
+
+If, during a mount lookup, a file map is found to have changed and the
+browse option is not being used, the file map won't be refreshed, even
+though file maps should always be read into the cache.
+
+A previous change for the "always read file maps" optimization moved
+the check for the browse option into the map module read function so
+checking for this in send_map_update_request() is not needed and
+causes nobrowse file maps to not be read if they have changed. This
+isn't quite optimal as there will be a partial read of the file map
+to satisfy the lookup and a full read of the map done by the queued
+update request. I don't think anything can be done about that though.
+---
+
+ CHANGELOG    |    1 +
+ lib/master.c |    3 ---
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -49,6 +49,7 @@
+ - remove ERR_remove_state() openssl call.
+ - fix init script restart option.
+ - fix init script status privilege error.
++- always read file maps mount lookup map read fix.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/lib/master.c
++++ autofs-5.0.5/lib/master.c
+@@ -489,9 +489,6 @@ void send_map_update_request(struct auto
+ 	struct map_source *map;
+ 	int status, need_update = 0;
+ 
+-	if (!(ap->flags & MOUNT_FLAG_GHOST))
+-		return;
+-
+ 	status = pthread_mutex_lock(&instance_mutex);
+ 	if (status)
+ 		fatal(status);
diff --git a/autofs-5.0.5-add-dump-maps-option.patch b/autofs-5.0.5-add-dump-maps-option.patch
new file mode 100644
index 0000000..c9d5994
--- /dev/null
+++ b/autofs-5.0.5-add-dump-maps-option.patch
@@ -0,0 +1,354 @@
+autofs-5.0.5 - add dump maps option
+
+From: Ondrej Valousek <webserv at s3group.cz>
+
+Modified by Ian Kent <raven at themaw.net>
+---
+
+ CHANGELOG          |    1 
+ daemon/automount.c |   52 +++++++++++++++------
+ include/log.h      |    1 
+ include/master.h   |    1 
+ lib/log.c          |   14 ++++-
+ lib/master.c       |  126 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ man/automount.8    |    3 +
+ 7 files changed, 180 insertions(+), 18 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -53,6 +53,7 @@
+ - fix direct map not updating on reread.
+ - add external bind method.
+ - fix add simple bind auth.
++- add option to dump configured automount maps.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/daemon/automount.c
++++ autofs-5.0.5/daemon/automount.c
+@@ -1664,6 +1664,7 @@ static void usage(void)
+ 		"	-f --foreground do not fork into background\n"
+ 		"	-r --random-multimount-selection\n"
+ 		"			use ramdom replicated server selection\n"
++		"	-m --dumpmaps	dump automounter maps and exit\n"
+ 		"	-n --negative-timeout n\n"
+ 		"			set the timeout for failed key lookups.\n"
+ 		"	-O --global-options\n"
+@@ -1813,7 +1814,7 @@ int main(int argc, char *argv[])
+ 	int res, opt, status;
+ 	int logpri = -1;
+ 	unsigned ghost, logging, daemon_check;
+-	unsigned foreground, have_global_options;
++	unsigned dumpmaps, foreground, have_global_options;
+ 	time_t timeout;
+ 	time_t age = time(NULL);
+ 	struct rlimit rlim;
+@@ -1827,6 +1828,7 @@ int main(int argc, char *argv[])
+ 		{"foreground", 0, 0, 'f'},
+ 		{"random-multimount-selection", 0, 0, 'r'},
+ 		{"negative-timeout", 1, 0, 'n'},
++		{"dumpmaps", 0, 0, 'm'},
+ 		{"global-options", 1, 0, 'O'},
+ 		{"version", 0, 0, 'V'},
+ 		{"set-log-priority", 1, 0, 'l'},
+@@ -1857,10 +1859,11 @@ int main(int argc, char *argv[])
+ 	global_options = NULL;
+ 	have_global_options = 0;
+ 	foreground = 0;
++	dumpmaps = 0;
+ 	daemon_check = 1;
+ 
+ 	opterr = 0;
+-	while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:CF", long_options, NULL)) != EOF) {
++	while ((opt = getopt_long(argc, argv, "+hp:t:vmdD:fVrO:l:n:CF", long_options, NULL)) != EOF) {
+ 		switch (opt) {
+ 		case 'h':
+ 			usage();
+@@ -1902,6 +1905,10 @@ int main(int argc, char *argv[])
+ 			global_negative_timeout = getnumopt(optarg, opt);
+ 			break;
+ 
++		case 'm':
++			dumpmaps = 1;
++			break;
++
+ 		case 'O':
+ 			if (!have_global_options) {
+ 				global_options = strdup(optarg);
+@@ -1988,7 +1995,8 @@ int main(int argc, char *argv[])
+ 	}
+ #endif
+ 
+-	if (!query_kproto_ver() || get_kver_major() < 5) {
++	/* Don't need the kernel module just to look at the configured maps */
++	if (!dumpmaps && (!query_kproto_ver() || get_kver_major() < 5)) {
+ 		fprintf(stderr,
+ 			"%s: test mount forbidden or "
+ 			"incorrect kernel protocol version, "
+@@ -2001,34 +2009,50 @@ int main(int argc, char *argv[])
+ 	rlim.rlim_max = MAX_OPEN_FILES;
+ 	res = setrlimit(RLIMIT_NOFILE, &rlim);
+ 	if (res)
+-		warn(logging,
+-		     "can't increase open file limit - continuing");
++		printf("%s: can't increase open file limit - continuing",
++			argv[0]);
+ 
+ #if ENABLE_CORES
+ 	rlim.rlim_cur = RLIM_INFINITY;
+ 	rlim.rlim_max = RLIM_INFINITY;
+ 	res = setrlimit(RLIMIT_CORE, &rlim);
+ 	if (res)
+-		warn(logging,
+-		     "can't increase core file limit - continuing");
++		printf("%s: can't increase core file limit - continuing",
++			argv[0]);
+ #endif
+ 
+-	become_daemon(foreground, daemon_check);
+-
+ 	if (argc == 0)
+ 		master_list = master_new(NULL, timeout, ghost);
+ 	else
+ 		master_list = master_new(argv[0], timeout, ghost);
+ 
+ 	if (!master_list) {
+-		logerr("%s: can't create master map %s",
+-			program, argv[0]);
+-		res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
+-		close(start_pipefd[1]);
+-		release_flag_file();
++		printf("%s: can't create master map %s", program, argv[0]);
+ 		exit(1);
+ 	}
+ 
++	if (dumpmaps) {
++		struct mapent_cache *nc;
++
++		open_log();
++
++		master_init_scan();
++
++		nc = cache_init_null_cache(master_list);
++		if (!nc) {
++			printf("%s: failed to init null map cache for %s",
++				master_list->name, argv[0]);
++			exit(1);
++		}
++		master_list->nc = nc;
++
++		lookup_nss_read_master(master_list, 0);
++		master_show_mounts(master_list);
++		exit(0);
++	}
++
++	become_daemon(foreground, daemon_check);
++
+ 	if (pthread_attr_init(&th_attr)) {
+ 		logerr("%s: failed to init thread attribute struct!",
+ 		     program);
+--- autofs-5.0.5.orig/include/log.h
++++ autofs-5.0.5/include/log.h
+@@ -35,6 +35,7 @@ extern void set_log_verbose_ap(struct au
+ extern void set_log_debug_ap(struct autofs_point *ap);
+ extern void set_mnt_logging(unsigned global_logopt);
+ 
++extern void open_log(void);
+ extern void log_to_syslog(void);
+ extern void log_to_stderr(void);
+  
+--- autofs-5.0.5.orig/include/master.h
++++ autofs-5.0.5/include/master.h
+@@ -110,6 +110,7 @@ int master_submount_list_empty(struct au
+ int master_notify_submount(struct autofs_point *, const char *path, enum states);
+ void master_notify_state_change(struct master *, int);
+ int master_mount_mounts(struct master *, time_t, int);
++int master_show_mounts(struct master *);
+ extern inline unsigned int master_get_logopt(void);
+ int master_list_empty(struct master *);
+ int master_done(struct master *);
+--- autofs-5.0.5.orig/lib/log.c
++++ autofs-5.0.5/lib/log.c
+@@ -193,17 +193,23 @@ void logmsg(const char *msg, ...)
+ 	return;
+ }
+ 
+-void log_to_syslog(void)
++void open_log(void)
+ {
+-	char buf[MAX_ERR_BUF];
+-	int nullfd;
+-
+ 	if (!syslog_open) {
+ 		syslog_open = 1;
+ 		openlog("automount", LOG_PID, LOG_DAEMON);
+ 	}
+ 
+ 	logging_to_syslog = 1;
++	return;
++}
++
++void log_to_syslog(void)
++{
++	char buf[MAX_ERR_BUF];
++	int nullfd;
++
++	open_log();
+ 
+ 	/* Redirect all our file descriptors to /dev/null */
+ 	nullfd = open("/dev/null", O_RDWR);
+--- autofs-5.0.5.orig/lib/master.c
++++ autofs-5.0.5/lib/master.c
+@@ -30,6 +30,7 @@
+ /* The root of the map entry tree */
+ struct master *master_list = NULL;
+ 
++extern const char *global_options;
+ extern long global_negative_timeout;
+ 
+ /* Attribute to create a joinable thread */
+@@ -1189,6 +1190,131 @@ int master_mount_mounts(struct master *m
+ 	return 1;
+ }
+ 
++/* The nss source instances end up in reverse order. */
++static void list_source_instances(struct map_source *source, struct map_source *instance)
++{
++	if (!source || !instance) {
++		printf("none");
++		return;
++	}
++
++	if (instance->next)
++		list_source_instances(source, instance->next);
++
++	/*
++	 * For convienience we map nss instance type "files" to "file".
++	 * Check for that and report corrected instance type.
++	 */
++	if (strcmp(instance->type, "file"))
++		printf("%s ", instance->type);
++	else {
++		if (source->argv && *(source->argv[0]) != '/')
++			printf("files ");
++		else
++			printf("%s ", instance->type);
++	}
++
++	return;
++}
++
++int master_show_mounts(struct master *master)
++{
++	struct list_head *p, *head;
++
++	printf("\nautofs dump map information\n"
++		 "===========================\n\n");
++
++	printf("global options: ");
++	if (!global_options)
++		printf("none configured\n");
++	else {
++		printf("%s\n", global_options);
++		unsigned int append_options = defaults_get_append_options();
++		const char *append = append_options ? "will" : "will not";
++		printf("global options %s be appended to map entries\n", append);
++	}
++
++	if (list_empty(&master->mounts)) {
++		printf("no master map entries found\n\n");
++		return 1;
++	}
++
++	head = &master->mounts;
++	p = head->next;
++	while (p != head) {
++		struct map_source *source;
++		struct master_mapent *this;
++		struct autofs_point *ap;
++		time_t now = time(NULL);
++		int i;
++
++		this = list_entry(p, struct master_mapent, list);
++		p = p->next;
++
++		ap = this->ap;
++
++		printf("\nMount point: %s\n", ap->path);
++		printf("\nsource(s):\n");
++
++		/* Read the map content into the cache */
++		if (lookup_nss_read_map(ap, NULL, now))
++			lookup_prune_cache(ap, now);
++		else {
++			printf("  failed to read map\n\n");
++			continue;
++		}
++
++		if (!this->maps) {
++			printf("  no map sources found\n\n");
++			continue;
++		}
++
++		source = this->maps;
++		while (source) {
++			struct mapent *me;
++
++			if (source->type)
++				printf("\n  type: %s\n", source->type);
++			else {
++				printf("\n  instance type(s): ");
++				list_source_instances(source, source->instance);
++				printf("\n");
++			}
++
++			if (source->argc >= 1) {
++				i = 0;
++				if (source->argv[0] && *source->argv[0] != '-') {
++					printf("  map: %s\n", source->argv[0]);
++					i = 1;
++				}
++				if (source->argc > 1) {
++					printf("  arguments: ");
++					for (; i < source->argc; i++)
++						printf("%s ", source->argv[i]);
++					printf("\n");
++				}
++			}
++
++			printf("\n");
++
++			me = cache_lookup_first(source->mc);
++			if (!me)
++				printf("  no keys found in map\n");
++			else {
++				do {
++					printf("  %s | %s\n", me->key, me->mapent);
++				} while ((me = cache_lookup_next(source->mc, me)));
++			}
++
++			source = source->next;
++		}
++
++		printf("\n");
++	}
++
++	return 1;
++}
++
+ int master_list_empty(struct master *master)
+ {
+ 	int res = 0;
+--- autofs-5.0.5.orig/man/automount.8
++++ autofs-5.0.5/man/automount.8
+@@ -57,6 +57,9 @@ Run the daemon in the forground and log 
+ Enables the use of ramdom selection when choosing a host from a
+ list of replicated servers.
+ .TP
++.I "\-m, \-\-dumpmaps"
++Dump configured automounter maps, then exit.
++.TP
+ .I "\-O, \-\-global-options"
+ Allows the specification of global mount options used for all master
+ map entries. These options will either replace or be appened to options
diff --git a/autofs-5.0.5-add-external-bind-method.patch b/autofs-5.0.5-add-external-bind-method.patch
new file mode 100644
index 0000000..65929cf
--- /dev/null
+++ b/autofs-5.0.5-add-external-bind-method.patch
@@ -0,0 +1,404 @@
+autofs-5.0.5 - add external bind method
+
+From: Ian Kent <raven at themaw.net>
+
+Add sasl external bind handler.
+---
+
+ CHANGELOG                      |    1 
+ include/lookup_ldap.h          |    7 ++
+ man/autofs_ldap_auth.conf.5.in |   24 +++++++-
+ modules/Makefile               |    5 +
+ modules/cyrus-sasl-extern.c    |  117 +++++++++++++++++++++++++++++++++++++++++
+ modules/cyrus-sasl.c           |   20 +++++++
+ modules/lookup_ldap.c          |   78 ++++++++++++++++++++++-----
+ 7 files changed, 234 insertions(+), 18 deletions(-)
+ create mode 100644 modules/cyrus-sasl-extern.c
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -51,6 +51,7 @@
+ - fix init script status privilege error.
+ - always read file maps mount lookup map read fix.
+ - fix direct map not updating on reread.
++- add external bind method.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/include/lookup_ldap.h
++++ autofs-5.0.5/include/lookup_ldap.h
+@@ -10,6 +10,7 @@
+ #include <krb5.h>
+ #endif
+ 
++#include "list.h"
+ #include "dclist.h"
+ 
+ struct ldap_schema {
+@@ -76,9 +77,13 @@ struct lookup_context {
+ 	int          kinit_done;
+ 	int          kinit_successful;
+ #ifdef WITH_SASL
++	/* Kerberos */
+ 	krb5_context krb5ctxt;
+ 	krb5_ccache  krb5_ccache;
+ 	sasl_conn_t  *sasl_conn;
++	/* SASL external */
++	char	     *extern_cert;
++	char	     *extern_key;
+ #endif
+ 	/* keytab file name needs to be added */
+ 
+@@ -111,6 +116,8 @@ int autofs_sasl_bind(unsigned logopt, LD
+ void autofs_sasl_unbind(struct lookup_context *ctxt);
+ void autofs_sasl_dispose(struct lookup_context *ctxt);
+ void autofs_sasl_done(void);
++/* cyrus-sasl-extern */
++int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt);
+ #endif
+ 
+ #endif
+--- autofs-5.0.5.orig/man/autofs_ldap_auth.conf.5.in
++++ autofs-5.0.5/man/autofs_ldap_auth.conf.5.in
+@@ -60,12 +60,30 @@ authentication  mechanism. If no suitabl
+ to the ldap server are made without authentication. Finally, if it is set to
+ simple, then simple authentication will be used instead of SASL.
+ .TP
+-\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5"\fP
++\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5|EXTERNAL"\fP
+ This attribute can be used to specify a preferred authentication mechanism.
+- In normal operations, the automounter will attempt to authenticate to the
++In normal operations, the automounter will attempt to authenticate to the
+ ldap server using the list of supportedSASLmechanisms obtained from the
+ directory server.  Explicitly setting the authtype will bypass this selection
+-and only try the mechanism specified.
++and only try the mechanism specified. The EXTERNAL mechanism may be used to
++authenticate using a client certificate and requires that authrequired
++set to "yes" if using SSL or usetls, tlsrequired and authrequired all set to
++"yes" if using TLS, in addition to authtype being set to EXTERNAL.
++.sp
++If using authtype EXTERNAL two additional configuration entries are
++required:
++.sp
++\fBexternal_cert="<client certificate path>"\fP
++.sp
++This specifies the path of the file containing the client certificate.
++.sp
++\fBexternal_key="<client certificate key path>"\fP
++.sp
++This specifies the path of the file containing the client certificate key.
++.sp
++These two configuration entries are mandatory when using the EXTERNAL method
++as the HOME environment variable cannot be assumed to be set or, if it is,
++to be set to the location we expect.
+ .TP
+ \fBuser="<username>"\fP
+ This attribute holds the authentication identity used by authentication
+--- autofs-5.0.5.orig/modules/Makefile
++++ autofs-5.0.5/modules/Makefile
+@@ -41,7 +41,7 @@ ifeq ($(LDAP), 1)
+   SRCS += lookup_ldap.c
+   MODS += lookup_ldap.so
+   ifeq ($(SASL), 1)
+-    SASL_OBJ = cyrus-sasl.o
++    SASL_OBJ = cyrus-sasl.o cyrus-sasl-extern.o
+     LDAP_FLAGS += $(SASL_FLAGS) $(XML_FLAGS) $(KRB5_FLAGS) -DLDAP_THREAD_SAFE
+     LIBLDAP += $(LIBSASL) $(XML_LIBS) $(KRB5_LIBS)
+   endif
+@@ -92,6 +92,9 @@ lookup_hesiod.so: lookup_hesiod.c
+ cyrus-sasl.o: cyrus-sasl.c
+ 	$(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
+ 
++cyrus-sasl-extern.o: cyrus-sasl-extern.c
++	$(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
++
+ lookup_ldap.so: lookup_ldap.c dclist.o $(SASL_OBJ)
+ 	$(CC) $(SOLDFLAGS) $(CFLAGS) $(LDAP_FLAGS) -o lookup_ldap.so \
+ 		lookup_ldap.c dclist.o $(SASL_OBJ) \
+--- /dev/null
++++ autofs-5.0.5/modules/cyrus-sasl-extern.c
+@@ -0,0 +1,117 @@
++/*
++ * cyrus-sasl-extern.c - Module for Cyrus sasl external authentication.
++ *
++ *   Copyright 2010 Ian Kent <raven at themaw.net>
++ *   Copyright 2010 Red Hat, Inc.
++ *   All rights reserved.
++ *
++ *   This program 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, Inc., 675 Mass Ave, Cambridge MA 02139,
++ *   USA; either version 2 of the License, or (at your option) any later
++ *   version.
++ *
++ *   This program 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.
++ */
++
++#include "config.h"
++
++#ifdef WITH_SASL
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <sasl/sasl.h>
++#include <ldap.h>
++#include <ldap_cdefs.h>
++#include <lber_types.h>
++
++#include "lookup_ldap.h"
++
++struct values {
++	char *mech;
++	char *realm;
++	char *authcid;
++	char *authzid;
++	char *password;
++	char **resps;
++	int nresps;
++};
++
++static int interaction(unsigned flags, sasl_interact_t *interact, void *values)
++{
++	const char *val = interact->defresult;
++	struct values *vals = values;
++
++	switch(interact->id) {
++	case SASL_CB_GETREALM:
++		if (values)
++			val = vals->realm;
++		break;
++
++	case SASL_CB_AUTHNAME:
++		if (values)
++			val = vals->authcid;
++		break;
++
++	case SASL_CB_PASS:
++		if (values)
++			val = vals->password;
++		break;
++
++	case SASL_CB_USER:
++		if (values)
++			val = vals->authzid;
++		break;
++
++	case SASL_CB_NOECHOPROMPT:
++	case SASL_CB_ECHOPROMPT:
++		break;
++	}
++
++	if (val && !*val)
++		val = NULL;
++
++	if (val || interact->id == SASL_CB_USER) {
++		interact->result = (val && *val) ? val : "";
++		interact->len = strlen(interact->result);
++	}
++
++	return LDAP_SUCCESS;
++}
++
++int sasl_extern_interact(LDAP *ldap, unsigned flags, void *values, void *list)
++{
++	sasl_interact_t *interact = list;
++
++	if (!ldap)
++		return LDAP_PARAM_ERROR;
++
++	while (interact->id != SASL_CB_LIST_END) {
++		int rc = interaction(flags, interact, values);
++		if (rc)
++			return rc;
++		interact++;
++	}
++
++	return LDAP_SUCCESS;
++}
++
++int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt)
++{
++	int flags = LDAP_SASL_QUIET;
++	char *mech = ctxt->sasl_mech;
++	struct values values;
++	int rc;
++
++	memset(&values, 0, sizeof(struct values));
++	values.mech = mech;
++
++	rc = ldap_sasl_interactive_bind_s(ldap, NULL, mech, NULL, NULL,
++					  flags, sasl_extern_interact, &values);
++	return rc;
++}
++#endif
+--- autofs-5.0.5.orig/modules/cyrus-sasl.c
++++ autofs-5.0.5/modules/cyrus-sasl.c
+@@ -875,6 +875,26 @@ autofs_sasl_bind(unsigned logopt, LDAP *
+ 	if (ctxt->sasl_conn)
+ 		return 0;
+ 
++	if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
++		int result;
++
++		debug(logopt,
++		      "Attempting sasl bind with mechanism %s",
++		      ctxt->sasl_mech);
++
++		result = do_sasl_extern(ldap, ctxt);
++		if (result)
++			debug(logopt,
++			      "Failed to authenticate with mech %s",
++			      ctxt->sasl_mech);
++		else
++			debug(logopt,
++			      "sasl bind with mechanism %s succeeded",
++			      ctxt->sasl_mech);
++
++		return result;
++	}
++
+ 	sasl_auth_id = ctxt->user;
+ 	sasl_auth_secret = ctxt->secret;
+ 
+--- autofs-5.0.5.orig/modules/lookup_ldap.c
++++ autofs-5.0.5/modules/lookup_ldap.c
+@@ -41,6 +41,9 @@
+ 
+ int lookup_version = AUTOFS_LOOKUP_VERSION;	/* Required by protocol */
+ 
++#define ENV_LDAPTLS_CERT	"LDAPTLS_CERT"
++#define ENV_LDAPTLS_KEY		"LDAPTLS_KEY"
++
+ static struct ldap_schema common_schema[] = {
+ 	{"nisMap", "nisMapName", "nisObject", "cn", "nisMapEntry"},
+ 	{"automountMap", "ou", "automount", "cn", "automountInformation"},
+@@ -61,6 +64,16 @@ struct ldap_search_params {
+ 
+ static int decode_percent_hack(const char *, char **);
+ 
++static int set_env(unsigned logopt, const char *name, const char *val)
++{
++	int ret = setenv(name, val, 1);
++	if (ret == -1) {
++		error(logopt, "failed to set config value for %s", name);
++		return 0;
++	}
++	return 1;
++}
++
+ #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
+ int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize,
+ 			     struct berval *cookie, char isCritical,
+@@ -578,13 +591,17 @@ static LDAP *do_connect(unsigned logopt,
+ {
+ 	LDAP *ldap;
+ 
+-	ldap = init_ldap_connection(logopt, uri, ctxt);
+-	if (!ldap)
+-		return NULL;
++	if (ctxt->extern_cert && ctxt->extern_key) {
++		set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert);
++		set_env(logopt, ENV_LDAPTLS_KEY, ctxt->extern_key);
++	}
+ 
+-	if (!do_bind(logopt, ldap, uri, ctxt)) {
+-		unbind_ldap_connection(logopt, ldap, ctxt);
+-		return NULL;
++	ldap = init_ldap_connection(logopt, uri, ctxt);
++	if (ldap) {
++		if (!do_bind(logopt, ldap, uri, ctxt)) {
++			unbind_ldap_connection(logopt, ldap, ctxt);
++			ldap = NULL;
++		}
+ 	}
+ 
+ 	return ldap;
+@@ -839,6 +856,7 @@ int parse_ldap_config(unsigned logopt, s
+ 	xmlNodePtr   root = NULL;
+ 	char         *authrequired, *auth_conf, *authtype;
+ 	char         *user = NULL, *secret = NULL;
++	char         *extern_cert = NULL, *extern_key = NULL;
+ 	char         *client_princ = NULL, *client_cc = NULL;
+ 	char	     *usetls, *tlsrequired;
+ 
+@@ -1023,6 +1041,26 @@ int parse_ldap_config(unsigned logopt, s
+ 			ret = -1;
+ 			goto out;
+ 		}
++	} else if (auth_required == LDAP_AUTH_REQUIRED &&
++		  (authtype && !strncmp(authtype, "EXTERNAL", 8))) {
++		ret = get_property(logopt, root, "external_cert",  &extern_cert);
++		ret |= get_property(logopt, root, "external_key",  &extern_key);
++		/*
++		 * For EXTERNAL auth to function we need a client certificate
++		 * and and certificate key. The ca certificate used to verify
++		 * the server certificate must also be set correctly in the
++		 * global configuration as the connection must be encrypted
++		 * and the server and client certificates must have been
++		 * verified for the EXTERNAL method to be offerred by the
++		 * server. If the cert and key have not been set in the autofs
++		 * configuration they must be set in the ldap rc file.
++		 */
++		if (ret != 0 || !extern_cert || !extern_key) {
++			if (extern_cert)
++				free(extern_cert);
++			if (extern_key)
++				free(extern_key);
++		}
+ 	}
+ 
+ 	/*
+@@ -1043,6 +1081,8 @@ int parse_ldap_config(unsigned logopt, s
+ 	ctxt->secret = secret;
+ 	ctxt->client_princ = client_princ;
+ 	ctxt->client_cc = client_cc;
++	ctxt->extern_cert = extern_cert;
++	ctxt->extern_key = extern_key;
+ 
+ 	debug(logopt, MODPREFIX
+ 	      "ldap authentication configured with the following options:");
+@@ -1052,14 +1092,20 @@ int parse_ldap_config(unsigned logopt, s
+ 	      "auth_required: %u, "
+ 	      "sasl_mech: %s",
+ 	      use_tls, tls_required, auth_required, authtype);
+-	debug(logopt, MODPREFIX
+-	      "user: %s, "
+-	      "secret: %s, "
+-	      "client principal: %s "
+-	      "credential cache: %s",
+-	      user, secret ? "specified" : "unspecified",
+-	      client_princ, client_cc);
+-
++	if (authtype && !strncmp(authtype, "EXTERNAL", 8)) {
++		debug(logopt, MODPREFIX "external cert: %s",
++		      extern_cert ? extern_cert : "ldap default");
++		debug(logopt, MODPREFIX "external key: %s ",
++		      extern_key ? extern_key : "ldap default");
++	} else {
++		debug(logopt, MODPREFIX
++		      "user: %s, "
++		      "secret: %s, "
++		      "client principal: %s "
++		      "credential cache: %s",
++		      user, secret ? "specified" : "unspecified",
++		      client_princ, client_cc);
++	}
+ out:
+ 	xmlFreeDoc(doc);
+ 
+@@ -1326,6 +1372,10 @@ static void free_context(struct lookup_c
+ 		defaults_free_searchdns(ctxt->sdns);
+ 	if (ctxt->dclist)
+ 		free_dclist(ctxt->dclist);
++	if (ctxt->extern_cert)
++		free(ctxt->extern_cert);
++	if (ctxt->extern_key)
++		free(ctxt->extern_key);
+ 	free(ctxt);
+ 
+ 	return;
diff --git a/autofs-5.0.5-fix-add-simple-bind-auth.patch b/autofs-5.0.5-fix-add-simple-bind-auth.patch
new file mode 100644
index 0000000..e0a620f
--- /dev/null
+++ b/autofs-5.0.5-fix-add-simple-bind-auth.patch
@@ -0,0 +1,72 @@
+autofs-5.0.5 - fix add simple bind auth
+
+From: Ian Kent <raven at themaw.net>
+
+Simple authentication should not require SASL.
+---
+
+ CHANGELOG             |    1 +
+ include/lookup_ldap.h |    5 +++++
+ modules/cyrus-sasl.c  |    1 -
+ modules/lookup_ldap.c |    1 -
+ 4 files changed, 6 insertions(+), 2 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -52,6 +52,7 @@
+ - always read file maps mount lookup map read fix.
+ - fix direct map not updating on reread.
+ - add external bind method.
++- fix add simple bind auth.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/include/lookup_ldap.h
++++ autofs-5.0.5/include/lookup_ldap.h
+@@ -1,6 +1,8 @@
+ #ifndef LOOKUP_LDAP_H
+ #define LOOKUP_LDAP_H
+ 
++#include <ldap.h>
++
+ #ifdef WITH_SASL
+ #include <openssl/ssl.h>
+ #include <openssl/evp.h>
+@@ -102,6 +104,8 @@ struct lookup_context {
+ #define LDAP_AUTH_NOTREQUIRED	0x0001
+ #define LDAP_AUTH_REQUIRED	0x0002
+ #define LDAP_AUTH_AUTODETECT	0x0004
++#endif
++
+ #define LDAP_AUTH_USESIMPLE	0x0008
+ 
+ /* lookup_ldap.c */
+@@ -109,6 +113,7 @@ LDAP *init_ldap_connection(unsigned logo
+ int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
+ int authtype_requires_creds(const char *authtype);
+ 
++#ifdef WITH_SASL
+ /* cyrus-sasl.c */
+ int autofs_sasl_client_init(unsigned logopt);
+ int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
+--- autofs-5.0.5.orig/modules/cyrus-sasl.c
++++ autofs-5.0.5/modules/cyrus-sasl.c
+@@ -51,7 +51,6 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <ldap.h>
+ #include <sasl/sasl.h>
+ 
+ #include "automount.h"
+--- autofs-5.0.5.orig/modules/lookup_ldap.c
++++ autofs-5.0.5/modules/lookup_ldap.c
+@@ -28,7 +28,6 @@
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ #include <lber.h>
+-#include <ldap.h>
+ 
+ #define MODULE_LOOKUP
+ #include "automount.h"
diff --git a/autofs-5.0.5-fix-direct-map-not-updating-on-reread.patch b/autofs-5.0.5-fix-direct-map-not-updating-on-reread.patch
new file mode 100644
index 0000000..f3105a9
--- /dev/null
+++ b/autofs-5.0.5-fix-direct-map-not-updating-on-reread.patch
@@ -0,0 +1,40 @@
+autofs-5.0.5 - fix direct map not updating on reread
+
+From: Ian Kent <raven at themaw.net>
+
+If the map type is explicitly specified for a map the map isn't
+properly updated when a re-read is requested. This is because
+the map stale flag is incorrectly cleared after after the lookup
+module reads the map instead of at the completion of the update
+procedure. The map stale flag should only be cleared if the map
+read fails for some reason, otherwise it is updated when the
+refresh is completed.
+---
+
+ CHANGELOG       |    1 +
+ daemon/lookup.c |    3 ++-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -50,6 +50,7 @@
+ - fix init script restart option.
+ - fix init script status privilege error.
+ - always read file maps mount lookup map read fix.
++- fix direct map not updating on reread.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/daemon/lookup.c
++++ autofs-5.0.5/daemon/lookup.c
+@@ -295,7 +295,8 @@ static int do_read_map(struct autofs_poi
+ 
+ 	status = lookup->lookup_read_map(ap, age, lookup->context);
+ 
+-	map->stale = 0;
++	if (status != NSS_STATUS_SUCCESS)
++		map->stale = 0;
+ 
+ 	/*
+ 	 * For maps that don't support enumeration return success
diff --git a/autofs-5.0.5-fix-submount-shutdown-wait.patch b/autofs-5.0.5-fix-submount-shutdown-wait.patch
new file mode 100644
index 0000000..a1b732d
--- /dev/null
+++ b/autofs-5.0.5-fix-submount-shutdown-wait.patch
@@ -0,0 +1,43 @@
+autofs-5.0.5 - fix submount shutdown wait
+
+From: Ian Kent <raven at themaw.net>
+
+When expiring a mount that has submounts we determine if a submount is
+still in use by its state being other than ST_SHUTDOWN. But a submount
+that is in the process of exiting could also be in one of the states
+ST_SHUTDOWN_PENDING or ST_SHUTDOWN_FORCE, in which case we should also
+continue to wait for the submount entry to be removed from the list or
+for it to reach another state.
+---
+
+ lib/master.c |    9 ++++++---
+ 1 files changed, 6 insertions(+), 3 deletions(-)
+
+
+diff --git a/lib/master.c b/lib/master.c
+index ad3aa77..95bd3fb 100644
+--- a/lib/master.c
++++ b/lib/master.c
+@@ -905,8 +905,9 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
+ 		st_wait_task(this, state, 0);
+ 
+ 		/*
+-		 * If our submount gets to state ST_SHUTDOWN we need to
+-		 * wait until it goes away or changes to ST_READY.
++		 * If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or
++		 * ST_SHUTDOWN_FORCE we need to wait until it goes away or changes
++		 * to ST_READY.
+ 		 */
+ 		mounts_mutex_lock(ap);
+ 		st_mutex_lock();
+@@ -914,7 +915,9 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
+ 			struct timespec t = { 0, 300000000 };
+ 			struct timespec r;
+ 
+-			if (this->state != ST_SHUTDOWN) {
++			if (this->state != ST_SHUTDOWN &&
++			    this->state != ST_SHUTDOWN_PENDING &&
++			    this->state != ST_SHUTDOWN_FORCE) {
+ 				ret = 0;
+ 				break;
+ 			}
diff --git a/autofs-5.0.5-wait-for-master-map-available-at-start.patch b/autofs-5.0.5-wait-for-master-map-available-at-start.patch
new file mode 100644
index 0000000..9e8b954
--- /dev/null
+++ b/autofs-5.0.5-wait-for-master-map-available-at-start.patch
@@ -0,0 +1,142 @@
+autofs-5.0.5 - wait for master map available at start
+
+From: Ian Kent <raven at themaw.net>
+
+If the network map source isn't available at start the master map
+can't be read. In this case we should wait until it is available
+so we can get a startup map.
+---
+
+ CHANGELOG           |    1 +
+ daemon/automount.c  |   22 +++++++++++++++++++++-
+ daemon/lookup.c     |    7 +++++++
+ lib/master.c        |    4 +++-
+ modules/lookup_yp.c |   13 +++++++++----
+ 5 files changed, 41 insertions(+), 6 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -54,6 +54,7 @@
+ - add external bind method.
+ - fix add simple bind auth.
+ - add option to dump configured automount maps.
++- wait for master map to be available at start.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/daemon/automount.c
++++ autofs-5.0.5/daemon/automount.c
+@@ -1809,6 +1809,21 @@ static int convert_log_priority(char *pr
+ 	return -1;
+ }
+ 
++static int do_master_read_master(struct master *master, time_t age, int readall)
++{
++	while (1) {
++		struct timespec t = { 0, 500000000 };
++
++		if (master_read_master(master, age, readall))
++			return 1;
++
++		if (nanosleep(&t, NULL) == -1)
++			break;
++	}
++
++	return 0;
++}
++
+ int main(int argc, char *argv[])
+ {
+ 	int res, opt, status;
+@@ -2143,7 +2158,12 @@ int main(int argc, char *argv[])
+ 		dh_tirpc = dlopen("libitirpc.so.1", RTLD_NOW);
+ #endif
+ 
+-	if (!master_read_master(master_list, age, 0)) {
++	/*
++	 * Read master map, waiting until it is available, unless
++	 * a signal is received, in which case exit returning an
++	 * error.
++	 */
++	if (!do_master_read_master(master_list, age, 0)) {
+ 		master_kill(master_list);
+ 		*pst_stat = 3;
+ 		res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
+--- autofs-5.0.5.orig/daemon/lookup.c
++++ autofs-5.0.5/daemon/lookup.c
+@@ -216,6 +216,7 @@ int lookup_nss_read_master(struct master
+ 	}
+ 
+ 	/* First one gets it */
++	result = NSS_STATUS_UNKNOWN;
+ 	head = &nsslist;
+ 	list_for_each(p, head) {
+ 		struct nss_source *this;
+@@ -223,6 +224,12 @@ int lookup_nss_read_master(struct master
+ 
+ 		this = list_entry(p, struct nss_source, list);
+ 
++		if (strncmp(this->source, "files", 5) &&
++		    strncmp(this->source, "nis", 3) &&
++		    strncmp(this->source, "nisplus", 7) &&
++		    strncmp(this->source, "ldap", 4))
++			continue;
++
+ 		debug(logopt,
+ 		      "reading master %s %s", this->source, master->name);
+ 
+--- autofs-5.0.5.orig/lib/master.c
++++ autofs-5.0.5/lib/master.c
+@@ -836,7 +836,9 @@ int master_read_master(struct master *ma
+ 		master_mount_mounts(master, age, readall);
+ 	else {
+ 		master->read_fail = 0;
+-		if (!readall)
++		if (readall)
++			return 0;
++		else
+ 			master_mount_mounts(master, age, readall);
+ 	}
+ 
+--- autofs-5.0.5.orig/modules/lookup_yp.c
++++ autofs-5.0.5/modules/lookup_yp.c
+@@ -214,9 +214,9 @@ int lookup_read_master(struct master *ma
+ 	char *mapname;
+ 	int err;
+ 
+-	mapname = alloca(strlen(ctxt->mapname) + 1);
++	mapname = malloc(strlen(ctxt->mapname) + 1);
+ 	if (!mapname)
+-		return 0;
++		return NSS_STATUS_UNKNOWN;
+ 
+ 	strcpy(mapname, ctxt->mapname);
+ 
+@@ -240,19 +240,24 @@ int lookup_read_master(struct master *ma
+ 			err = yp_all((char *) ctxt->domainname, mapname, &ypcb);
+ 		}
+ 
+-		if (err == YPERR_SUCCESS)
++		if (err == YPERR_SUCCESS) {
++			free(mapname);
+ 			return NSS_STATUS_SUCCESS;
++		}
+ 
+ 		info(logopt,
+ 		     MODPREFIX "read of master map %s failed: %s",
+ 		     mapname, yperr_string(err));
+ 
+-		if (err == YPERR_PMAP || err == YPERR_YPSERV)
++		if (err == YPERR_PMAP || err == YPERR_YPSERV) {
++			free(mapname);
+ 			return NSS_STATUS_UNAVAIL;
++		}
+ 
+ 		return NSS_STATUS_NOTFOUND;
+ 	}
+ 
++	free(mapname);
+ 	return NSS_STATUS_SUCCESS;
+ }
+ 
diff --git a/autofs.spec b/autofs.spec
index b8ebea5..70b8046 100644
--- a/autofs.spec
+++ b/autofs.spec
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems
 Name: autofs
 Version: 5.0.5
-Release: 31%{?dist}
+Release: 32%{?dist}
 Epoch: 1
 License: GPLv2+
 Group: System Environment/Daemons
@@ -62,6 +62,13 @@ Patch50: autofs-5.0.5-make-verbose-mode-a-little-less-verbose.patch
 Patch51: autofs-5.0.5-remove-ERR_remove_state-openssl-call.patch
 Patch52: autofs-5.0.5-fix-restart.patch
 Patch53: autofs-5.0.5-fix-status-privilege-error.patch
+Patch54: autofs-5.0.4-always-read-file-maps-mount-lookup-map-read-fix.patch
+Patch55: autofs-5.0.5-fix-direct-map-not-updating-on-reread.patch
+Patch56: autofs-5.0.5-add-external-bind-method.patch
+Patch57: autofs-5.0.5-fix-add-simple-bind-auth.patch
+Patch58: autofs-5.0.5-add-dump-maps-option.patch
+Patch59: autofs-5.0.5-fix-submount-shutdown-wait.patch
+Patch60: autofs-5.0.5-wait-for-master-map-available-at-start.patch
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel
 Conflicts: cyrus-sasl-lib < 2.1.23-9
@@ -157,6 +164,13 @@ echo %{version}-%{release} > .version
 %patch51 -p1
 %patch52 -p1
 %patch53 -p1
+%patch54 -p1
+%patch55 -p1
+%patch56 -p1
+%patch57 -p1
+%patch58 -p1
+%patch59 -p1
+%patch60 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -209,6 +223,14 @@ fi
 %{_libdir}/autofs/
 
 %changelog
+* Fri Nov 8 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-32.fc15
+- always read file maps mount lookup map read fix.
+- fix direct map not updating on reread.
+- add external bind method.
+- fix add simple bind auth.
+- add option to dump configured automount maps.
+- wait for master map to be available at start.
+
 * Fri Aug 27 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-31.fc15
 - fix status privilege error (bz627605).
 


More information about the scm-commits mailing list