From ab7ff7de49129edc31a46563ff098bd611af51b5 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Mon, 8 Nov 2010 11:59:40 +0800 Subject: [PATCH] * Fri Nov 8 2010 Ian Kent - 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. --- ...-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 ++++ ...ix-direct-map-not-updating-on-reread.patch | 40 ++ autofs-5.0.5-fix-submount-shutdown-wait.patch | 43 ++ ...it-for-master-map-available-at-start.patch | 142 ++++++ autofs.spec | 24 +- 8 files changed, 1122 insertions(+), 1 deletion(-) create mode 100644 autofs-5.0.4-always-read-file-maps-mount-lookup-map-read-fix.patch create mode 100644 autofs-5.0.5-add-dump-maps-option.patch create mode 100644 autofs-5.0.5-add-external-bind-method.patch create mode 100644 autofs-5.0.5-fix-add-simple-bind-auth.patch create mode 100644 autofs-5.0.5-fix-direct-map-not-updating-on-reread.patch create mode 100644 autofs-5.0.5-fix-submount-shutdown-wait.patch create mode 100644 autofs-5.0.5-wait-for-master-map-available-at-start.patch 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 + +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 + +Modified by Ian Kent +--- + + 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 + +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 + #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=""\fP ++.sp ++This specifies the path of the file containing the client certificate. ++.sp ++\fBexternal_key=""\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=""\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 ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 + +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 ++ + #ifdef WITH_SASL + #include + #include +@@ -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 + #include + #include +-#include + #include + + #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 + #include + #include +-#include + + #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 + +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 + +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 + +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 - 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 - 1:5.0.5-31.fc15 - fix status privilege error (bz627605).