rpms/autofs/F-8 autofs-5.0.2-add-multiple-server-selection-option-fix.patch, NONE, 1.1 autofs-5.0.2-basedn-with-spaces-fix-2.patch, NONE, 1.1 autofs-5.0.2-basedn-with-spaces-fix.patch, NONE, 1.1 autofs-5.0.2-external-cred-cache.patch, NONE, 1.1 autofs-5.0.2-fix-off-by-one-lookup.patch, NONE, 1.1 autofs-5.0.2-improve-server-unavail-fix.patch, NONE, 1.1 autofs-5.0.2-improve-server-unavail.patch, NONE, 1.1 autofs-5.0.2-instance-stale-mark-update.patch, NONE, 1.1 autofs-5.0.2-ldap-page-control.patch, NONE, 1.1 autofs-5.0.2-ldap-search-basedn-list-fix.patch, NONE, 1.1 autofs-5.0.2-percent-hack-fix.patch, NONE, 1.1 autofs-5.0.2-quell-mount-module-message.patch, NONE, 1.1 autofs-5.0.2-quote-exports-fix.patch, NONE, 1.1 autofs-5.0.2-remove-unsed-export-validation-code.patch, NONE, 1.1 autofs-5.0.2-start-pipe-buff-size.patch, NONE, 1.1 autofs-5.0.2-submount-shutdown-race.patch, NONE, 1.1 autofs-5.0.3-basedn-with-spaces-fix-3.patch, NONE, 1.1 autofs-5.0.3-correct-ldap-lib.patch, NONE, 1.1 autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch, NONE, 1.1 autofs-5.0.3-expire-works-too-hard.patch, NONE, 1.1 autofs-5.0.3-ldap-page-control-configure-fix.patch, NONE, 1.1 autofs-5.0.3-nfs4-tcp-only.patch, NONE, 1.1 autofs-5.0.3-unlink-mount-return-fix.patch, NONE, 1.1 autofs-5.0.3-xfn-not-supported.patch, NONE, 1.1 autofs-5.0.2-basedn-with-spaces.patch, 1.1, 1.2 autofs-5.0.2-foreground-logging.patch, 1.1, 1.2 autofs-5.0.2-ldap-search-basedn-list.patch, 1.1, 1.2 autofs-5.0.2-random-selection-fix.patch, 1.1, 1.2 autofs-5.0.2-reread-config-on-hup.patch, 1.1, 1.2 autofs.spec, 1.235, 1.236
Ian Kent (iankent)
fedora-extras-commits at redhat.com
Thu Feb 14 07:28:40 UTC 2008
Author: iankent
Update of /cvs/pkgs/rpms/autofs/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv15385
Modified Files:
autofs-5.0.2-basedn-with-spaces.patch
autofs-5.0.2-foreground-logging.patch
autofs-5.0.2-ldap-search-basedn-list.patch
autofs-5.0.2-random-selection-fix.patch
autofs-5.0.2-reread-config-on-hup.patch autofs.spec
Added Files:
autofs-5.0.2-add-multiple-server-selection-option-fix.patch
autofs-5.0.2-basedn-with-spaces-fix-2.patch
autofs-5.0.2-basedn-with-spaces-fix.patch
autofs-5.0.2-external-cred-cache.patch
autofs-5.0.2-fix-off-by-one-lookup.patch
autofs-5.0.2-improve-server-unavail-fix.patch
autofs-5.0.2-improve-server-unavail.patch
autofs-5.0.2-instance-stale-mark-update.patch
autofs-5.0.2-ldap-page-control.patch
autofs-5.0.2-ldap-search-basedn-list-fix.patch
autofs-5.0.2-percent-hack-fix.patch
autofs-5.0.2-quell-mount-module-message.patch
autofs-5.0.2-quote-exports-fix.patch
autofs-5.0.2-remove-unsed-export-validation-code.patch
autofs-5.0.2-start-pipe-buff-size.patch
autofs-5.0.2-submount-shutdown-race.patch
autofs-5.0.3-basedn-with-spaces-fix-3.patch
autofs-5.0.3-correct-ldap-lib.patch
autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch
autofs-5.0.3-expire-works-too-hard.patch
autofs-5.0.3-ldap-page-control-configure-fix.patch
autofs-5.0.3-nfs4-tcp-only.patch
autofs-5.0.3-unlink-mount-return-fix.patch
autofs-5.0.3-xfn-not-supported.patch
Log Message:
* Thu Feb 14 2008 Ian Kent <ikent at redhat.com> - 5.0.2-26
- re-order and update patches to sync with upstream.
- located missing patch.
- replaced couple of patches previously altered due to incorrect ordering.
- add patches for upstream issues - synced with 5.0.3.
- fix incorrect read/write size of startup status token (Matthias Koenig).
- fix off-by-one error for lookup of map keys exactly 255 characters long.
- improve handling of server not available.
- fix LDAP_URI server selection.
- add authentication option for using an external credential cache.
- expand support for the "%" hack.
- fix to quoting for exports gathered by hosts map.
- use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified.
- second attempt fixing quoting for exports gathered by hosts map.
- quell annoying "cannot open mount module" message.
- fix for improve handling of server not available.
- use mount option "nodev" for "-hosts" map unless "dev" is explicily specified.
- add LDAP paged query handling to deal with query size restrictions (Edward Newman).
- add additional case for "mark map instances stale so they aren't "cleaned" during updates".
- fix race during sub-mount shutdown.
- fix add SEARCH_BASE configuration option.
- add patches for upstream issues - post 5.0.3.
- correct configure test for ldapr page control functions.
- catch "-xfn" map type and issue "no supported" message.
- correction for handling of LDAP base dns with spaces.
- avoid using UDP for probing NFSv4 mount requests.
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
- fix expire working harder than needed.
- fix unlink of mount tree incorrectly causing autofs mount fail.
autofs-5.0.2-add-multiple-server-selection-option-fix.patch:
--- NEW FILE autofs-5.0.2-add-multiple-server-selection-option-fix.patch ---
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
index 18733f3..303b7f2 100644
--- a/modules/cyrus-sasl.c
+++ b/modules/cyrus-sasl.c
@@ -75,6 +75,7 @@ static const char *krb5ccval = "MEMORY:_autofstkt";
static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER;
static unsigned int krb5cc_in_use = 0;
+static unsigned int init_callbacks = 1;
static int sasl_log_func(void *, int, const char *);
static int getpass_func(sasl_conn_t *, void *, int, sasl_secret_t **);
static int getuser_func(void *, int, const char **, unsigned *);
@@ -386,7 +387,7 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
debug(logopt,
"initializing kerberos ticket: client principal %s ",
- ctxt->client_princ ? "" : "autofsclient");
+ ctxt->client_princ ? ctxt->client_princ : "autofsclient");
ret = krb5_init_context(&ctxt->krb5ctxt);
if (ret) {
@@ -599,8 +600,8 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c
/* OK and CONTINUE are the only non-fatal return codes here. */
if ((result != SASL_OK) && (result != SASL_CONTINUE)) {
- error(logopt, "sasl_client start failed with error: %s",
- sasl_errdetail(conn));
+ warn(logopt, "sasl_client_start failed for %s", host);
+ debug(logopt, "sasl_client_start: %s", sasl_errdetail(conn));
ldap_memfree(host);
sasl_dispose(&conn);
return NULL;
@@ -721,23 +722,30 @@ autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
sasl_conn_t *conn;
/* Start up Cyrus SASL--only needs to be done once. */
- if (sasl_client_init(callbacks) != SASL_OK) {
+ if (init_callbacks && sasl_client_init(callbacks) != SASL_OK) {
error(logopt, "sasl_client_init failed");
return -1;
}
+ init_callbacks = 0;
sasl_auth_id = ctxt->user;
sasl_auth_secret = ctxt->secret;
/*
- * If sasl_mech was not filled in, it means that there was no
- * mechanism specified in the configuration file. Try to auto-
- * select one.
+ * If LDAP_AUTH_AUTODETECT is set, it means that there was no
+ * mechanism specified in the configuration file or auto
+ * selection has been requested, so try to auto-select an
+ * auth mechanism.
*/
- if (ctxt->sasl_mech)
+ if (!(ctxt->auth_required & LDAP_AUTH_AUTODETECT))
conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
- else
+ else {
+ if (ctxt->sasl_mech) {
+ free(ctxt->sasl_mech);
+ ctxt->sasl_mech = NULL;
+ }
conn = sasl_choose_mech(logopt, ldap, ctxt);
+ }
if (conn) {
sasl_dispose(&conn);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 7effbf1..93f0477 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -402,8 +402,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
ctxt->auth_required, ctxt->sasl_mech);
- if (ctxt->sasl_mech ||
- (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT))) {
+ if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
rv = autofs_sasl_bind(logopt, ldap, ctxt);
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
} else {
@@ -497,7 +496,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
* Determine which authentication mechanism to use if we require
* authentication.
*/
- if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
+ if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
ldap = auth_init(logopt, uri, ctxt);
if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
info(logopt,
@@ -510,6 +509,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
if (!do_bind(logopt, ldap, ctxt)) {
unbind_ldap_connection(logopt, ldap, ctxt);
+ autofs_sasl_done(ctxt);
error(logopt, MODPREFIX "cannot bind to server");
return NULL;
}
@@ -541,6 +541,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
while(p != ctxt->uri) {
this = list_entry(p, struct ldap_uri, list);
p = p->next;
+ debug(logopt, "trying server %s", this->uri);
ldap = connect_to_server(logopt, this->uri, ctxt);
if (ldap) {
info(logopt, "connected to uri %s", this->uri);
@@ -563,22 +564,23 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
{
+ struct ldap_uri *this;
LDAP *ldap;
if (ctxt->server || !ctxt->uri) {
ldap = do_connect(logopt, ctxt->server, ctxt);
return ldap;
- } else {
- struct ldap_uri *this;
- this = list_entry(ctxt->uri->next, struct ldap_uri, list);
- ldap = do_connect(logopt, this->uri, ctxt);
- if (ldap)
- return ldap;
- /* Failed to connect, put at end of list */
- list_del_init(&this->list);
- list_add_tail(&this->list, ctxt->uri);
}
+ this = list_entry(ctxt->uri->next, struct ldap_uri, list);
+ ldap = do_connect(logopt, this->uri, ctxt);
+ if (ldap)
+ return ldap;
+
+ /* Failed to connect, put at end of list */
+ list_del_init(&this->list);
+ list_add_tail(&this->list, ctxt->uri);
+
#ifdef WITH_SASL
autofs_sasl_done(ctxt);
#endif
@@ -844,6 +846,8 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
ctxt->tls_required = tls_required;
ctxt->auth_required = auth_required;
ctxt->sasl_mech = authtype;
+ if (!authtype && (auth_required & LDAP_AUTH_REQUIRED))
+ ctxt->auth_required |= LDAP_AUTH_AUTODETECT;
ctxt->user = user;
ctxt->secret = secret;
ctxt->client_princ = client_princ;
@@ -886,16 +890,6 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *
int ret;
LDAP *ldap;
- /*
- * First, check to see if a preferred authentication method was
- * specified by the user. parse_ldap_config will return error
- * if the permissions on the file were incorrect, or if the
- * specified authentication type is not valid.
- */
- ret = parse_ldap_config(logopt, ctxt);
- if (ret)
- return NULL;
-
ldap = init_ldap_connection(logopt, uri, ctxt);
if (!ldap)
return NULL;
@@ -909,10 +903,8 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *
* the credential cache and the client and service principals.
*/
ret = autofs_sasl_init(logopt, ldap, ctxt);
- if (ret) {
- ctxt->sasl_mech = NULL;
+ if (ret)
return NULL;
- }
return ldap;
}
@@ -1134,6 +1126,8 @@ static void free_context(struct lookup_context *ctxt)
free(ctxt->user);
if (ctxt->secret)
free(ctxt->secret);
+ if (ctxt->client_princ)
+ free(ctxt->client_princ);
if (ctxt->mapname)
free(ctxt->mapname);
if (ctxt->qdn)
@@ -1184,6 +1178,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
LDAP *ldap = NULL;
+ int ret;
*context = NULL;
@@ -1224,6 +1219,20 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
}
}
+#ifdef WITH_SASL
+ /*
+ * First, check to see if a preferred authentication method was
+ * specified by the user. parse_ldap_config will return error
+ * if the permissions on the file were incorrect, or if the
+ * specified authentication type is not valid.
+ */
+ ret = parse_ldap_config(LOGOPT_NONE, ctxt);
+ if (ret) {
+ free_context(ctxt);
+ return 1;
+ }
+#endif
+
if (ctxt->server || !ctxt->uri) {
ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
if (!ldap) {
autofs-5.0.2-basedn-with-spaces-fix-2.patch:
--- NEW FILE autofs-5.0.2-basedn-with-spaces-fix-2.patch ---
diff --git a/lib/master_tok.l b/lib/master_tok.l
index 5450753..36aa785 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -108,8 +108,8 @@ AT_DC ([dD][[cC])
AT_O ([oO])
AT_C ([cC])
DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
-DNNAMESTR ([[:alnum:]_.\- ]+)
-DNNAMETRM (,|{OPTWS}{NL}|{OPTWS}#.*|{OPTWS}\x00)
+DNNAMESTR1 ([[:alnum:]_.\- ]+)
+DNNAMESTR2 ([[:alnum:]_.\-]+)
INTMAP (-hosts|-null)
MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
@@ -282,7 +282,12 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
return EQUAL;
}
- {DNNAMESTR}/{DNNAMETRM} {
+ {DNNAMESTR1}/"," {
+ strcpy(master_lval.strtype, master_text);
+ return DNNAME;
+ }
+
+ {DNNAMESTR2} {
strcpy(master_lval.strtype, master_text);
return DNNAME;
}
autofs-5.0.2-basedn-with-spaces-fix.patch:
--- NEW FILE autofs-5.0.2-basedn-with-spaces-fix.patch ---
diff --git a/lib/master_tok.l b/lib/master_tok.l
index 48bc233..5450753 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -108,8 +108,8 @@ AT_DC ([dD][[cC])
AT_O ([oO])
AT_C ([cC])
DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
-DNNAMESTR ([[:alnum:]_.\-]+)
-DNNAMETRM (,|{WS}{NL}|{WS}#.*|\x00)
+DNNAMESTR ([[:alnum:]_.\- ]+)
+DNNAMETRM (,|{OPTWS}{NL}|{OPTWS}#.*|{OPTWS}\x00)
INTMAP (-hosts|-null)
MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
@@ -379,7 +379,13 @@ void master_set_scan_buffer(const char *buffer)
{
line = buffer;
line_pos = &line[0];
- line_lim = line + strlen(buffer);
+ /*
+ * Ensure buffer is 1 greater than string and is zeroed before
+ * the parse so we can fit the extra NULL which allows us to
+ * explicitly match an end of line within the buffer (ie. the
+ * need for 2 NULLS when parsing in memeory buffers).
+ */
+ line_lim = line + strlen(buffer) + 1;
}
#define min(a,b) (((a) < (b)) ? (a) : (b))
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 921b32b..c093415 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -479,7 +479,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
master->name = save_name;
} else {
- blen = path_len + 1 + ent_len + 1;
+ blen = path_len + 1 + ent_len + 2;
buffer = malloc(blen);
if (!buffer) {
error(logopt,
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 00215af..dfb3054 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1368,7 +1368,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
goto next;
}
- blen = strlen(*keyValue) + 1 + strlen(*values) + 1;
+ blen = strlen(*keyValue) + 1 + strlen(*values) + 2;
if (blen > PARSE_MAX_BUF) {
error(logopt, MODPREFIX "map entry too long");
ldap_value_free(values);
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index ff8bd49..bcdaeeb 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -90,7 +90,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
char *path, *ent;
char *buffer;
char buf[MAX_ERR_BUF];
- int cur_state;
+ int cur_state, len;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
@@ -138,11 +138,13 @@ int lookup_read_master(struct master *master, time_t age, void *context)
ent = ENTRY_VAL(this, 1);
- buffer = malloc(ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 1);
+ len = ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 2;
+ buffer = malloc(len);
if (!buffer) {
logerr(MODPREFIX "could not malloc parse buffer");
continue;
}
+ memset(buffer, 0, len);
strcat(buffer, path);
strcat(buffer, " ");
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 63fc8e3..7ba6940 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -178,7 +178,7 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
*(ypkey + ypkeylen) = '\0';
*(val + vallen) = '\0';
- len = ypkeylen + 1 + vallen + 1;
+ len = ypkeylen + 1 + vallen + 2;
buffer = alloca(len);
if (!buffer) {
autofs-5.0.2-external-cred-cache.patch:
--- NEW FILE autofs-5.0.2-external-cred-cache.patch ---
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
index 5b5c475..d6a754d 100644
--- a/include/lookup_ldap.h
+++ b/include/lookup_ldap.h
@@ -67,10 +67,10 @@ struct lookup_context {
char *user;
char *secret;
char *client_princ;
+ char *client_cc;
int kinit_done;
int kinit_successful;
#ifdef WITH_SASL
- krb5_principal krb5_client_princ;
krb5_context krb5ctxt;
krb5_ccache krb5_ccache;
sasl_conn_t *sasl_conn;
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
index 303b7f2..f24f46b 100644
--- a/modules/cyrus-sasl.c
+++ b/modules/cyrus-sasl.c
@@ -72,6 +72,7 @@
*/
static const char *krb5ccenv = "KRB5CCNAME";
static const char *krb5ccval = "MEMORY:_autofstkt";
+static const char *default_client = "autofsclient";
static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER;
static unsigned int krb5cc_in_use = 0;
@@ -376,7 +377,7 @@ int
sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
{
krb5_error_code ret;
- krb5_principal tgs_princ, krb5_client_princ = ctxt->krb5_client_princ;
+ krb5_principal tgs_princ, krb5_client_princ;
krb5_creds my_creds;
char *tgs_name;
int status;
@@ -386,8 +387,8 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
ctxt->kinit_done = 1;
debug(logopt,
- "initializing kerberos ticket: client principal %s ",
- ctxt->client_princ ? ctxt->client_princ : "autofsclient");
+ "initializing kerberos ticket: client principal %s",
+ ctxt->client_princ ? ctxt->client_princ : default_client);
ret = krb5_init_context(&ctxt->krb5ctxt);
if (ret) {
@@ -424,13 +425,12 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
"calling krb5_sname_to_principal using defaults");
ret = krb5_sname_to_principal(ctxt->krb5ctxt, NULL,
- "autofsclient", KRB5_NT_SRV_HST,
+ default_client, KRB5_NT_SRV_HST,
&krb5_client_princ);
if (ret) {
error(logopt,
"krb5_sname_to_principal failed for "
- "%s with error %d",
- ctxt->client_princ ? "" : "autofsclient", ret);
+ "%s with error %d", default_client, ret);
goto out_cleanup_cc;
}
@@ -441,11 +441,11 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
debug(logopt,
"krb5_unparse_name failed with error %d",
ret);
- goto out_cleanup_cc;
+ goto out_cleanup_client_princ;
}
debug(logopt,
- "principal used for authentication: \"%s\"", tmp_name);
+ "principal used for authentication: %s", tmp_name);
krb5_free_unparsed_name(ctxt->krb5ctxt, tmp_name);
}
@@ -461,14 +461,14 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
if (ret) {
error(logopt,
"krb5_build_principal failed with error %d", ret);
- goto out_cleanup_cc;
+ goto out_cleanup_client_princ;
}
ret = krb5_unparse_name(ctxt->krb5ctxt, tgs_princ, &tgs_name);
if (ret) {
error(logopt, "krb5_unparse_name failed with error %d",
ret);
- goto out_cleanup_cc;
+ goto out_cleanup_client_princ;
}
debug(logopt, "Using tgs name %s", tgs_name);
@@ -486,7 +486,6 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
goto out_cleanup_unparse;
}
-
status = pthread_mutex_lock(&krb5cc_mutex);
if (status)
fatal(status);
@@ -503,7 +502,7 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
if (ret) {
error(logopt,
"krb5_cc_initialize failed with error %d", ret);
- goto out_cleanup_unparse;
+ goto out_cleanup_creds;
}
/* and store credentials for that principal */
@@ -511,26 +510,34 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
if (ret) {
error(logopt,
"krb5_cc_store_cred failed with error %d", ret);
- goto out_cleanup_unparse;
+ goto out_cleanup_creds;
}
/* finally, set the environment variable to point to our
* credentials cache */
if (setenv(krb5ccenv, krb5ccval, 1) != 0) {
error(logopt, "setenv failed with %d", errno);
- goto out_cleanup_unparse;
+ goto out_cleanup_creds;
}
ctxt->kinit_successful = 1;
debug(logopt, "Kerberos authentication was successful!");
krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
+ krb5_free_cred_contents(ctxt->krb5ctxt, &my_creds);
+ krb5_free_principal(ctxt->krb5ctxt, tgs_princ);
+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
return 0;
-out_cleanup_unparse:
+out_cleanup_creds:
krb5cc_in_use--;
+ krb5_free_cred_contents(ctxt->krb5ctxt, &my_creds);
+out_cleanup_unparse:
+ krb5_free_principal(ctxt->krb5ctxt, tgs_princ);
krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
+out_cleanup_client_princ:
+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
out_cleanup_cc:
status = pthread_mutex_lock(&krb5cc_mutex);
if (status)
@@ -554,6 +561,152 @@ out_cleanup_cc:
}
/*
+ * Check a client given external credential cache.
+ *
+ * Returns 0 upon success. ctxt->kinit_done and ctxt->kinit_successful
+ * are set for cleanup purposes. The krb5 context and ccache entries in
+ * the lookup_context are also filled in.
+ *
+ * Upon failure, -1 is returned.
+ */
+int
+sasl_do_kinit_ext_cc(unsigned logopt, struct lookup_context *ctxt)
+{
+ krb5_principal def_princ;
+ krb5_principal krb5_client_princ;
+ krb5_error_code ret;
+ char *cc_princ, *client_princ;
+
+ if (ctxt->kinit_done)
+ return 0;
+ ctxt->kinit_done = 1;
+
+ debug(logopt,
+ "using external credential cache for auth: client principal %s",
+ ctxt->client_princ ? ctxt->client_princ : default_client);
+
+ ret = krb5_init_context(&ctxt->krb5ctxt);
+ if (ret) {
+ error(logopt, "krb5_init_context failed with %d", ret);
+ return -1;
+ }
+
+ ret = krb5_cc_resolve(ctxt->krb5ctxt, ctxt->client_cc, &ctxt->krb5_ccache);
+ if (ret) {
+ error(logopt, "krb5_cc_resolve failed with error %d",
+ ret);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+
+ ret = krb5_cc_get_principal(ctxt->krb5ctxt, ctxt->krb5_ccache, &def_princ);
+ if (ret) {
+ error(logopt, "krb5_cc_get_principal failed with error %d", ret);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+
+ ret = krb5_unparse_name(ctxt->krb5ctxt, def_princ, &cc_princ);
+ if (ret) {
+ error(logopt, "krb5_unparse_name failed with error %d", ret);
+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+
+ debug(logopt, "external credential cache default principal %s", cc_princ);
+
+ /*
+ * If the principal isn't set in the config construct the default
+ * so we can check against the default principal of the external
+ * cred cache.
+ */
+ if (ctxt->client_princ)
+ client_princ = ctxt->client_princ;
+ else {
+ debug(logopt,
+ "calling krb5_sname_to_principal using defaults");
+
+ ret = krb5_sname_to_principal(ctxt->krb5ctxt, NULL,
+ default_client, KRB5_NT_SRV_HST,
+ &krb5_client_princ);
+ if (ret) {
+ error(logopt,
+ "krb5_sname_to_principal failed for "
+ "%s with error %d", default_client, ret);
+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+
+
+ ret = krb5_unparse_name(ctxt->krb5ctxt,
+ krb5_client_princ, &client_princ);
+ if (ret) {
+ debug(logopt,
+ "krb5_unparse_name failed with error %d",
+ ret);
+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+
+ debug(logopt,
+ "principal used for authentication: %s", client_princ);
+
+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
+ }
+
+ /*
+ * Check if the principal to be used matches the default principal in
+ * the external cred cache.
+ */
+ if (strcmp(cc_princ, client_princ)) {
+ error(logopt,
+ "configured client principal %s ",
+ ctxt->client_princ);
+ error(logopt,
+ "external credential cache default principal %s",
+ cc_princ);
+ error(logopt,
+ "cannot use credential cache, external "
+ "default principal does not match configured "
+ "principal");
+ if (!ctxt->client_princ)
+ krb5_free_unparsed_name(ctxt->krb5ctxt, client_princ);
+ krb5_free_unparsed_name(ctxt->krb5ctxt, cc_princ);
+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+
+ if (!ctxt->client_princ)
+ krb5_free_unparsed_name(ctxt->krb5ctxt, client_princ);
+ krb5_free_unparsed_name(ctxt->krb5ctxt, cc_princ);
+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
+
+ /* Set the environment variable to point to the external cred cache */
+ if (setenv(krb5ccenv, ctxt->client_cc, 1) != 0) {
+ error(logopt, "setenv failed with %d", errno);
+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
+ krb5_free_context(ctxt->krb5ctxt);
+ return -1;
+ }
+ ctxt->kinit_successful = 1;
+
+ debug(logopt, "Kerberos authentication was successful!");
+
+ return 0;
+}
+
+/*
* Attempt to bind to the ldap server using a given authentication
* mechanism. ldap should be a properly initialzed ldap pointer.
*
@@ -570,7 +723,11 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c
int result;
if (!strncmp(mech, "GSSAPI", 6)) {
- if (sasl_do_kinit(logopt, ctxt) != 0)
+ if (ctxt->client_cc)
+ result = sasl_do_kinit_ext_cc(logopt, ctxt);
+ else
+ result = sasl_do_kinit(logopt, ctxt);
+ if (result != 0)
return NULL;
}
@@ -774,7 +931,7 @@ autofs_sasl_done(struct lookup_context *ctxt)
if (status)
fatal(status);
- if (--krb5cc_in_use)
+ if (--krb5cc_in_use || ctxt->client_cc)
ret = krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
else
ret = krb5_cc_destroy(ctxt->krb5ctxt, ctxt->krb5_ccache);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 93f0477..13fbff7 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -651,7 +651,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
xmlNodePtr root = NULL;
char *authrequired, *auth_conf, *authtype;
char *user = NULL, *secret = NULL;
- char *client_princ = NULL;
+ char *client_princ = NULL, *client_cc = NULL;
char *usetls, *tlsrequired;
authtype = user = secret = NULL;
@@ -840,6 +840,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
* client. The default is "autofsclient/hostname at REALM".
*/
(void)get_property(logopt, root, "clientprinc", &client_princ);
+ (void)get_property(logopt, root, "credentialcache", &client_cc);
ctxt->auth_conf = auth_conf;
ctxt->use_tls = use_tls;
@@ -851,6 +852,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
ctxt->user = user;
ctxt->secret = secret;
ctxt->client_princ = client_princ;
+ ctxt->client_cc = client_cc;
debug(logopt, MODPREFIX
"ldap authentication configured with the following options:");
@@ -863,9 +865,10 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
debug(logopt, MODPREFIX
"user: %s, "
"secret: %s, "
- "client principal: %s",
+ "client principal: %s "
+ "credential cache: %s",
user, secret ? "specified" : "unspecified",
- client_princ);
+ client_princ, client_cc);
out:
xmlFreeDoc(doc);
@@ -1128,6 +1131,8 @@ static void free_context(struct lookup_context *ctxt)
free(ctxt->secret);
if (ctxt->client_princ)
free(ctxt->client_princ);
+ if (ctxt->client_cc)
+ free(ctxt->client_cc);
if (ctxt->mapname)
free(ctxt->mapname);
if (ctxt->qdn)
diff --git a/samples/autofs_ldap_auth.conf b/samples/autofs_ldap_auth.conf
index e10d1ea..a1f60c0 100644
--- a/samples/autofs_ldap_auth.conf
+++ b/samples/autofs_ldap_auth.conf
@@ -56,6 +56,11 @@ clientprinc - When using GSSAPI authentication, this attribute is
consulted to determine the principal name to use when
authenticating to the directory server. By default, this will
be set to "autofsclient/<fqdn>@<REALM>.
+
+credentialcache - When using GSSAPI authentication, this attribute
+ can be used to specify an externally configured credential
+ cache that is used during authentication. By default, autofs
+ will setup a memory based credential cache.
-->
<autofs_ldap_sasl_conf
autofs-5.0.2-fix-off-by-one-lookup.patch:
--- NEW FILE autofs-5.0.2-fix-off-by-one-lookup.patch ---
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 23ea07d..550bf5c 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1047,7 +1047,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
debug(ap->logopt, MODPREFIX "looking up %s", name);
- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 93a1b40..b8484a2 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2053,7 +2053,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
debug(ap->logopt, MODPREFIX "looking up %s", name);
- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index bb1ca42..fee8b16 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -476,7 +476,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
debug(ap->logopt, MODPREFIX "looking up %s", name);
- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index e8ca8e8..5f4f95f 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -567,7 +567,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
debug(ap->logopt, MODPREFIX "looking up %s", name);
- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
autofs-5.0.2-improve-server-unavail-fix.patch:
--- NEW FILE autofs-5.0.2-improve-server-unavail-fix.patch ---
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index a77068a..ab2dd0f 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -474,8 +474,12 @@ int lookup_read_master(struct master *master, time_t age, void *context)
MODPREFIX
"failed to read included master map %s",
master->name);
- fclose(f);
- return NSS_STATUS_UNAVAIL;
+ if (!master->recurse) {
+ master->depth--;
+ master->recurse = 0;
+ fclose(f);
+ return NSS_STATUS_UNAVAIL;
+ }
}
master->depth--;
master->recurse = 0;
autofs-5.0.2-improve-server-unavail.patch:
--- NEW FILE autofs-5.0.2-improve-server-unavail.patch ---
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 0be10d3..eb72411 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -298,8 +298,6 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
status = lookup->lookup_read_map(ap, age, lookup->context);
- map->stale = 0;
-
/*
* For maps that don't support enumeration return success
* and do whatever we must to have autofs function with an
@@ -533,6 +531,10 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time
if (result == NSS_STATUS_UNKNOWN)
continue;
+ /* Don't try to update the map cache if it's unavailable */
+ if (result == NSS_STATUS_UNAVAIL)
+ map->stale = 0;
+
if (result == NSS_STATUS_SUCCESS) {
at_least_one = 1;
result = NSS_STATUS_TRYAGAIN;
@@ -553,7 +555,7 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time
}
pthread_cleanup_pop(1);
- if (!result || at_least_one)
+ if (!result || at_least_one)
return 1;
return 0;
diff --git a/daemon/state.c b/daemon/state.c
index cf07aac..5bccfef 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -432,6 +432,7 @@ static void *do_readmap(void *arg)
me = cache_enumerate(mc, me);
}
pthread_cleanup_pop(1);
+ map->stale = 0;
map = map->next;
}
pthread_cleanup_pop(1);
diff --git a/include/automount.h b/include/automount.h
index fa5cd97..133fd32 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -121,6 +121,7 @@ struct autofs_point;
#define CHE_MISSING 0x0008
#define CHE_COMPLETED 0x0010
#define CHE_DUPLICATE 0x0020
+#define CHE_UNAVAIL 0x0040
#define HASHSIZE 77
#define NEGATIVE_TIMEOUT 10
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 550bf5c..a77068a 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -469,11 +469,14 @@ int lookup_read_master(struct master *master, time_t age, void *context)
master->recurse = 1;;
master->depth++;
status = lookup_nss_read_master(master, age);
- if (!status)
+ if (!status) {
warn(logopt,
MODPREFIX
"failed to read included master map %s",
master->name);
+ fclose(f);
+ return NSS_STATUS_UNAVAIL;
+ }
master->depth--;
master->recurse = 0;
@@ -484,6 +487,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
if (!buffer) {
error(logopt,
MODPREFIX "could not malloc parse buffer");
+ fclose(f);
return NSS_STATUS_UNAVAIL;
}
memset(buffer, 0, blen);
@@ -721,9 +725,12 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
/* Gim'ee some o' that 16k stack baby !! */
status = lookup_nss_read_map(ap, inc_source, age);
- if (!status)
+ if (!status) {
warn(ap->logopt,
"failed to read included map %s", key);
+ fclose(f);
+ return NSS_STATUS_UNAVAIL;
+ }
} else {
char *s_key;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index b8484a2..7effbf1 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1755,7 +1755,7 @@ static int lookup_one(struct autofs_point *ap,
/* Initialize the LDAP context. */
ldap = do_reconnect(ap->logopt, ctxt);
if (!ldap)
- return CHE_FAIL;
+ return CHE_UNAVAIL;
debug(ap->logopt,
MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn);
@@ -1999,6 +1999,21 @@ static int check_map_indirect(struct autofs_point *ap,
if (ret == CHE_FAIL) {
pthread_setcancelstate(cur_state, NULL);
return NSS_STATUS_NOTFOUND;
+ } else if (ret == CHE_UNAVAIL) {
+ /*
+ * If the server is down and the entry exists in the cache
+ * and belongs to this map return success and use the entry.
+ */
+ struct mapent *exists = cache_lookup(mc, key);
+ if (exists && exists->source == source) {
+ pthread_setcancelstate(cur_state, NULL);
+ return NSS_STATUS_SUCCESS;
+ }
+
+ warn(ap->logopt,
+ MODPREFIX "lookup for %s failed: connection failed", key);
+
+ return NSS_STATUS_UNAVAIL;
}
pthread_setcancelstate(cur_state, NULL);
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index fee8b16..628ffcf 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -385,9 +385,18 @@ static int check_map_indirect(struct autofs_point *ap,
return NSS_STATUS_NOTFOUND;
if (ret < 0) {
+ /*
+ * If the server is down and the entry exists in the cache
+ * and belongs to this map return success and use the entry.
+ */
+ exists = cache_lookup(mc, key);
+ if (exists && exists->source == source)
+ return NSS_STATUS_SUCCESS;
+
warn(ap->logopt,
MODPREFIX "lookup for %s failed: %s",
key, nis_sperrno(-ret));
+
return NSS_STATUS_UNAVAIL;
}
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 5f4f95f..f5097dc 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -239,6 +239,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
MODPREFIX "read of master map %s failed: %s",
mapname, yperr_string(err));
+ if (err == YPERR_PMAP || err == YPERR_YPSERV)
+ return NSS_STATUS_UNAVAIL;
+
return NSS_STATUS_NOTFOUND;
}
@@ -336,6 +339,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
MODPREFIX "read of map %s failed: %s",
ap->path, yperr_string(err));
+ if (err == YPERR_PMAP || err == YPERR_YPSERV)
+ return NSS_STATUS_UNAVAIL;
+
return NSS_STATUS_NOTFOUND;
}
@@ -481,9 +487,18 @@ static int check_map_indirect(struct autofs_point *ap,
return NSS_STATUS_NOTFOUND;
if (ret < 0) {
+ /*
+ * If the server is down and the entry exists in the cache
+ * and belongs to this map return success and use the entry.
+ */
+ exists = cache_lookup(mc, key);
+ if (exists && exists->source == source)
+ return NSS_STATUS_SUCCESS;
+
warn(ap->logopt,
MODPREFIX "lookup for %s failed: %s",
key, yperr_string(-ret));
+
return NSS_STATUS_UNAVAIL;
}
autofs-5.0.2-instance-stale-mark-update.patch:
--- NEW FILE autofs-5.0.2-instance-stale-mark-update.patch ---
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index ab2dd0f..6d134cb 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -617,7 +617,13 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in
argv[1] = NULL;
source = master_find_source_instance(current, type, fmt, argc, argv);
- if (!source) {
+ if (source)
+ /*
+ * Make sure included map age is in sync with its owner
+ * or we could incorrectly wipe out its entries.
+ */
+ source->age = age;
+ else {
source = master_add_source_instance(current, type, fmt, age, argc, argv);
if (!source) {
free(buf);
autofs-5.0.2-ldap-page-control.patch:
--- NEW FILE autofs-5.0.2-ldap-page-control.patch ---
diff --git a/configure b/configure
index 0360086..4515fb8 100755
--- a/configure
+++ b/configure
@@ -4580,6 +4580,102 @@ fi
LDFLAGS="${AF_tmp_ldflags}"
+
+
+for ac_func in ldap_create_page_control ldap_parse_page_control
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
#
# SASL support
# configure magic taken from:
diff --git a/configure.in b/configure.in
index a83b3f1..8d5e6c9 100644
--- a/configure.in
+++ b/configure.in
@@ -210,6 +210,8 @@ AC_SUBST(HAVE_LDAP)
AC_SUBST(LIBLDAP)
LDFLAGS="${AF_tmp_ldflags}"
+AC_CHECK_FUNCS(ldap_create_page_control ldap_parse_page_control)
+
#
# SASL support
# configure magic taken from:
diff --git a/include/config.h.in b/include/config.h.in
index 9669872..d8f1747 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -21,6 +21,12 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the `ldap_create_page_control' function. */
+#undef HAVE_LDAP_CREATE_PAGE_CONTROL
+
+/* Define to 1 if you have the `ldap_parse_page_control' function. */
+#undef HAVE_LDAP_PARSE_PAGE_CONTROL
+
/* Define if you have the Linux /proc filesystem. */
#undef HAVE_LINUX_PROCFS
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 65f1fda..29e26db 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -49,8 +49,79 @@ static struct ldap_schema common_schema[] = {
};
static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
+struct ldap_search_params {
+ struct autofs_point *ap;
+ LDAP *ldap;
+ char *query, **attrs;
+ struct berval *cookie;
+ int morePages;
+ unsigned int totalCount;
+ LDAPMessage *result;
+ time_t age;
+};
+
static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *);
+#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
+int ldap_create_page_control(LDAP *ldap, unsigned int pagesize,
+ struct berval *cookie, char isCritical,
+ LDAPControl **output)
+{
+ BerElement *ber;
+ int rc;
+
+ if (!ldap || !output)
+ return LDAP_PARAM_ERROR;
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (!ber)
+ return LDAP_NO_MEMORY;
+
+ if (ber_printf(ber, "{io}", pagesize,
+ (cookie && cookie->bv_val) ? cookie->bv_val : "",
+ (cookie && cookie->bv_val) ? cookie->bv_len : 0)
+ == LBER_ERROR) {
+ ber_free(ber, 1);
+ return LDAP_ENCODING_ERROR;
+ }
+
+ rc = ldap_create_control(LDAP_CONTROL_PAGEDRESULTS, ber, isCritical, output);
+
+ return rc;
+}
+#endif /* HAVE_LDAP_CREATE_PAGE_CONTROL */
+
+#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL
+int ldap_parse_page_control(LDAP *ldap, LDAPControl **controls,
+ unsigned int *totalcount, struct berval **cookie)
+{
+ int i, rc;
+ BerElement *theBer;
+ LDAPControl *listCtrlp;
+
+ for (i = 0; controls[i] != NULL; i++) {
+ if (strcmp(controls[i]->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS) == 0) {
+ listCtrlp = controls[i];
+
+ theBer = ber_init(&listCtrlp->ldctl_value);
+ if (!theBer)
+ return LDAP_NO_MEMORY;
+
+ rc = ber_scanf(theBer, "{iO}", totalcount, cookie);
+ if (rc == LBER_ERROR) {
+ ber_free(theBer, 1);
+ return LDAP_DECODING_ERROR;
+ }
+
+ ber_free(theBer, 1);
+ return LDAP_SUCCESS;
+ }
+ }
+
+ return LDAP_CONTROL_NOT_FOUND;
+}
+#endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */
+
int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
{
int rv;
@@ -1545,80 +1616,118 @@ static int encode_percent_hack(const char *name, char **key, unsigned int use_cl
return strlen(new);
}
-static int read_one_map(struct autofs_point *ap,
- struct lookup_context *ctxt,
- time_t age, int *result_ldap)
+static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *ctxt)
{
- struct map_source *source;
- struct mapent_cache *mc;
- int rv, i, l, count;
- char buf[MAX_ERR_BUF];
- char *query;
- LDAPMessage *result, *e;
- char *class, *info, *entry;
- struct berval **bvKey;
- struct berval **bvValues;
- char *attrs[3];
- int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap;
-
- source = ap->entry->current;
- ap->entry->current = NULL;
- master_source_current_signal(ap->entry);
-
- mc = source->mc;
+ struct autofs_point *ap = sp->ap;
+ LDAPControl *pageControl=NULL, *controls[2] = { NULL, NULL };
+ LDAPControl **returnedControls = NULL;
+ static unsigned long pageSize = 1000;
+ static char pagingCriticality = 'T';
+ int rv, scope = LDAP_SCOPE_SUBTREE;
+
+ if (sp->morePages == TRUE)
+ goto do_paged;
+
+ rv = ldap_search_s(sp->ldap, ctxt->qdn, scope, sp->query, sp->attrs, 0, &sp->result);
+ if ((rv != LDAP_SUCCESS) || !sp->result) {
+ /*
+ * Check for Size Limit exceeded and force run through loop
+ * and requery using page control.
+ */
+ if (rv == LDAP_SIZELIMIT_EXCEEDED)
+ sp->morePages = TRUE;
+ else {
+ debug(ap->logopt,
+ MODPREFIX "query failed for %s: %s",
+ sp->query, ldap_err2string(rv));
+ return rv;
+ }
+ }
+ return rv;
- class = ctxt->schema->entry_class;
- entry = ctxt->schema->entry_attr;
- info = ctxt->schema->value_attr;
+do_paged:
+ /* we need to use page controls so requery LDAP */
+ debug(ap->logopt, MODPREFIX "geting page of results");
- attrs[0] = entry;
- attrs[1] = info;
- attrs[2] = NULL;
+ rv = ldap_create_page_control(sp->ldap, pageSize, sp->cookie,
+ pagingCriticality, &pageControl);
+ if (rv != LDAP_SUCCESS) {
+ warn(ap->logopt, MODPREFIX "failed to create page control");
+ return rv;
+ }
- /* Build a query string. */
- l = strlen("(objectclass=)") + strlen(class) + 1;
+ /* Insert the control into a list to be passed to the search. */
+ controls[0] = pageControl;
- query = alloca(l);
- if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return NSS_STATUS_UNAVAIL;
+ /* Search for entries in the directory using the parmeters. */
+ rv = ldap_search_ext_s(sp->ldap,
+ ctxt->qdn, scope, sp->query, sp->attrs,
+ 0, controls, NULL, NULL, 0, &sp->result);
+ if ((rv != LDAP_SUCCESS) && (rv != LDAP_PARTIAL_RESULTS)) {
+ debug(ap->logopt,
+ MODPREFIX "query failed for %s: %s",
+ sp->query, ldap_err2string(rv));
+ ldap_control_free(pageControl);
+ return rv;
}
- if (sprintf(query, "(objectclass=%s)", class) >= l) {
- error(ap->logopt, MODPREFIX "error forming query string");
- return NSS_STATUS_UNAVAIL;
+ /* Parse the results to retrieve the contols being returned. */
+ rv = ldap_parse_result(sp->ldap, sp->result,
+ NULL, NULL, NULL, NULL,
+ &returnedControls, FALSE);
+ if (sp->cookie != NULL) {
+ ber_bvfree(sp->cookie);
+ sp->cookie = NULL;
}
- query[l] = '\0';
- /* Initialize the LDAP context. */
- ldap = do_reconnect(ap->logopt, ctxt);
- if (!ldap)
- return NSS_STATUS_UNAVAIL;
+ /*
+ * Parse the page control returned to get the cookie and
+ * determine whether there are more pages.
+ */
+ rv = ldap_parse_page_control(sp->ldap,
+ returnedControls, &sp->totalCount,
+ &sp->cookie);
+ if (sp->cookie && sp->cookie->bv_val && strlen(sp->cookie->bv_val))
+ sp->morePages = TRUE;
+ else
+ sp->morePages = FALSE;
- /* Look around. */
- debug(ap->logopt,
- MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn);
+ /* Cleanup the controls used. */
+ if (returnedControls)
+ ldap_controls_free(returnedControls);
- rv = ldap_search_s(ldap, ctxt->qdn, scope, query, attrs, 0, &result);
+ ldap_control_free(pageControl);
- if ((rv != LDAP_SUCCESS) || !result) {
- debug(ap->logopt,
- MODPREFIX "query failed for %s: %s",
- query, ldap_err2string(rv));
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
- *result_ldap = rv;
- return NSS_STATUS_NOTFOUND;
- }
+ return rv;
+}
- e = ldap_first_entry(ldap, result);
+static int do_get_entries(struct ldap_search_params *sp, struct map_source *source, struct lookup_context *ctxt)
+{
+ struct autofs_point *ap = sp->ap;
+ struct mapent_cache *mc = source->mc;
+ char buf[MAX_ERR_BUF];
+ struct berval **bvKey;
+ struct berval **bvValues;
+ LDAPMessage *e;
+ char *class, *info, *entry;
+ int rv, ret;
+ int i, count;
+
+ class = ctxt->schema->entry_class;
+ entry = ctxt->schema->entry_attr;
+ info = ctxt->schema->value_attr;
+
+ e = ldap_first_entry(sp->ldap, sp->result);
if (!e) {
debug(ap->logopt,
- MODPREFIX "query succeeded, no matches for %s", query);
- ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
- return NSS_STATUS_NOTFOUND;
+ MODPREFIX "query succeeded, no matches for %s",
+ sp->query);
+ ret = ldap_parse_result(sp->ldap, sp->result,
+ &rv, NULL, NULL, NULL, NULL, 0);
+ if (ret == LDAP_SUCCESS)
+ return rv;
+ else
+ return LDAP_OPERATIONS_ERROR;
} else
debug(ap->logopt, MODPREFIX "examining entries");
@@ -1629,10 +1738,21 @@ static int read_one_map(struct autofs_point *ap,
ber_len_t k_len;
char *s_key;
- bvKey = ldap_get_values_len(ldap, e, entry);
-
+ bvKey = ldap_get_values_len(sp->ldap, e, entry);
if (!bvKey || !*bvKey) {
- e = ldap_next_entry(ldap, e);
+ e = ldap_next_entry(sp->ldap, e);
+ if (!e) {
+ debug(ap->logopt, MODPREFIX
+ "failed to get next entry for query %s",
+ sp->query);
+ ret = ldap_parse_result(sp->ldap,
+ sp->result, &rv,
+ NULL, NULL, NULL, NULL, 0);
+ if (ret == LDAP_SUCCESS)
+ return rv;
+ else
+ return LDAP_OPERATIONS_ERROR;
+ }
continue;
}
@@ -1697,8 +1817,7 @@ static int read_one_map(struct autofs_point *ap,
if (!k_val) {
error(ap->logopt,
- MODPREFIX
- "invalid entry %.*s - ignoring",
+ MODPREFIX "invalid entry %.*s - ignoring",
bvKey[0]->bv_len, bvKey[0]->bv_val);
goto next;
}
@@ -1721,10 +1840,10 @@ static int read_one_map(struct autofs_point *ap,
goto next;
}
- bvValues = ldap_get_values_len(ldap, e, info);
+ bvValues = ldap_get_values_len(sp->ldap, e, info);
if (!bvValues || !*bvValues) {
debug(ap->logopt,
- MODPREFIX "no %s defined for %s", info, query);
+ MODPREFIX "no %s defined for %s", info, sp->query);
goto next;
}
@@ -1737,7 +1856,6 @@ static int read_one_map(struct autofs_point *ap,
* options or the actual order of entries causes problems
* it won't be supported. Perhaps someone can instruct us
* how to force an ordering.
- *
*/
count = ldap_count_values_len(bvValues);
for (i = 0; i < count; i++) {
@@ -1807,7 +1925,7 @@ static int read_one_map(struct autofs_point *ap,
}
cache_writelock(mc);
- cache_update(mc, source, s_key, mapent, age);
+ cache_update(mc, source, s_key, mapent, sp->age);
cache_unlock(mc);
free(s_key);
@@ -1818,14 +1936,112 @@ next:
}
ldap_value_free_len(bvKey);
- e = ldap_next_entry(ldap, e);
+ e = ldap_next_entry(sp->ldap, e);
+ if (!e) {
+ debug(ap->logopt, MODPREFIX
+ "failed to get next entry for query %s",
+ sp->query);
+ ret = ldap_parse_result(sp->ldap,
+ sp->result, &rv,
+ NULL, NULL, NULL, NULL, 0);
+ if (ret == LDAP_SUCCESS)
+ return rv;
+ else
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+
+static int read_one_map(struct autofs_point *ap,
+ struct lookup_context *ctxt,
+ time_t age, int *result_ldap)
+{
+ struct map_source *source;
+ struct ldap_search_params sp;
+ char buf[MAX_ERR_BUF];
+ char *class, *info, *entry;
+ char *attrs[3];
+ int rv, l;
+
+ source = ap->entry->current;
+ ap->entry->current = NULL;
+ master_source_current_signal(ap->entry);
+
+ sp.ap = ap;
+ sp.age = age;
+
+ class = ctxt->schema->entry_class;
+ entry = ctxt->schema->entry_attr;
+ info = ctxt->schema->value_attr;
+
+ attrs[0] = entry;
+ attrs[1] = info;
+ attrs[2] = NULL;
+ sp.attrs = attrs;
+
+ /* Build a query string. */
+ l = strlen("(objectclass=)") + strlen(class) + 1;
+
+ sp.query = alloca(l);
+ if (sp.query == NULL) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ if (sprintf(sp.query, "(objectclass=%s)", class) >= l) {
+ error(ap->logopt, MODPREFIX "error forming query string");
+ return NSS_STATUS_UNAVAIL;
}
+ sp.query[l] = '\0';
+
+ /* Initialize the LDAP context. */
+ sp.ldap = do_reconnect(ap->logopt, ctxt);
+ if (!sp.ldap)
+ return NSS_STATUS_UNAVAIL;
+
+ /* Look around. */
+ debug(ap->logopt,
+ MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, ctxt->qdn);
+
+ sp.cookie = NULL;
+ sp.morePages = FALSE;
+ sp.totalCount = 0;
+ sp.result = NULL;
+
+ do {
+ rv = do_paged_query(&sp, ctxt);
+ if (rv == LDAP_SIZELIMIT_EXCEEDED)
+ {
+ debug(ap->logopt, MODPREFIX "result size exceed");
+ if (sp.result)
+ ldap_msgfree(sp.result);
+
+ continue;
+ }
+
+ if (rv != LDAP_SUCCESS || !sp.result) {
+ unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ *result_ldap = rv;
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ rv = do_get_entries(&sp, source, ctxt);
+ if (rv != LDAP_SUCCESS) {
+ ldap_msgfree(sp.result);
+ unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ *result_ldap = rv;
+ return NSS_STATUS_NOTFOUND;
+ }
+ ldap_msgfree(sp.result);
+ } while (sp.morePages == TRUE);
debug(ap->logopt, MODPREFIX "done updating map");
- /* Clean up. */
- ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
source->age = age;
autofs-5.0.2-ldap-search-basedn-list-fix.patch:
--- NEW FILE autofs-5.0.2-ldap-search-basedn-list-fix.patch ---
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 29e26db..0723fd8 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -261,7 +261,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
{
char buf[PARSE_MAX_BUF];
char *query, *dn, *qdn;
- LDAPMessage *result = NULL, *e;
+ LDAPMessage *result, *e;
struct ldap_searchdn *sdns = NULL;
char *attrs[2];
struct berval **value;
@@ -319,52 +319,71 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
}
}
- if (!ctxt->sdns)
+ dn = NULL;
+ if (!ctxt->sdns) {
rv = ldap_search_s(ldap, ctxt->base,
scope, query, attrs, 0, &result);
- else {
+ if ((rv != LDAP_SUCCESS) || !result) {
+ error(logopt,
+ MODPREFIX "query failed for %s: %s",
+ query, ldap_err2string(rv));
+ return 0;
+ }
+
+ e = ldap_first_entry(ldap, result);
+ if (e && (value = ldap_get_values_len(ldap, e, key))) {
+ ldap_value_free_len(value);
+ dn = ldap_get_dn(ldap, e);
+ debug(logopt, MODPREFIX "found query dn %s", dn);
+ } else {
+ debug(logopt,
+ MODPREFIX "query succeeded, no matches for %s",
+ query);
+ ldap_msgfree(result);
+ return 0;
+ }
+ } else {
struct ldap_searchdn *this = ctxt->sdns;
debug(logopt, MODPREFIX "check search base list");
+ result = NULL;
while (this) {
rv = ldap_search_s(ldap, this->basedn,
scope, query, attrs, 0, &result);
-
if ((rv == LDAP_SUCCESS) && result) {
debug(logopt, MODPREFIX
"found search base under %s",
this->basedn);
- break;
+
+ e = ldap_first_entry(ldap, result);
+ if (e && (value = ldap_get_values_len(ldap, e, key))) {
+ ldap_value_free_len(value);
+ dn = ldap_get_dn(ldap, e);
+ debug(logopt, MODPREFIX "found query dn %s", dn);
+ break;
+ } else {
+ debug(logopt,
+ MODPREFIX "query succeeded, no matches for %s",
+ query);
+ ldap_msgfree(result);
+ result = NULL;
+ }
+ } else {
+ error(logopt,
+ MODPREFIX "query failed for search dn %s: %s",
+ this->basedn, ldap_err2string(rv));
}
this = this->next;
-
- if (result) {
- ldap_msgfree(result);
- result = NULL;
- }
}
- }
-
- if ((rv != LDAP_SUCCESS) || !result) {
- error(logopt,
- MODPREFIX "query failed for %s: %s",
- query, ldap_err2string(rv));
- return 0;
- }
- e = ldap_first_entry(ldap, result);
- if (e && (value = ldap_get_values_len(ldap, e, key))) {
- ldap_value_free_len(value);
- dn = ldap_get_dn(ldap, e);
- debug(logopt, MODPREFIX "found query dn %s", dn);
- } else {
- debug(logopt,
- MODPREFIX "query succeeded, no matches for %s",
- query);
- ldap_msgfree(result);
- return 0;
+ if (!result) {
+ ldap_msgfree(result);
+ error(logopt,
+ MODPREFIX "failed to find query dn under search base dns");
+ return 0;
+ }
}
qdn = strdup(dn);
@@ -1290,8 +1309,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
validate_uris(uris);
if (!list_empty(uris))
ctxt->uri = uris;
- else
+ else {
+ error(LOGOPT_ANY,
+ "no valid uris found in config list"
+ ", using default system config");
free(uris);
+ }
}
}
autofs-5.0.2-percent-hack-fix.patch:
--- NEW FILE autofs-5.0.2-percent-hack-fix.patch ---
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 13fbff7..65f1fda 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1411,6 +1411,140 @@ next:
return NSS_STATUS_SUCCESS;
}
+/*
+ * Deal with encode and decode of % hack.
+ * Return
+ * 0 => % hack not present.
+ * -1 => syntax error or alloc fail.
+ * 1 transofrmed value returned.
+ */
+static int decode_percent_hack(const char *name, char **key)
+{
+ const char *tmp;
+ char *ptr, *new;
+
+ if (!key)
+ return -1;
+
+ *key = NULL;
+
+ tmp = name;
+ while (*tmp && *tmp != '%' && *tmp != '[' && *tmp != ']')
+ tmp++;
+ if (!*tmp)
+ return 0;
+
+ tmp = name;
+ while (*tmp) {
+ if (*tmp == '%') {
+ tmp++;
+ if (!*tmp)
+ return -1;
+ if (*tmp != '[')
+ continue;
+ tmp++;
+ while (*tmp && *tmp != ']') {
+ if (*tmp == '%')
+ tmp++;
+ tmp++;
+ }
+ if (!tmp)
+ return -1;
+ }
+ tmp++;
+ }
+
+ new = malloc(strlen(name) + 1);
+ if (!new)
+ return -1;
+
+ ptr = new;
+ tmp = name;
+ while (*tmp) {
+ if (*tmp == '%' || *tmp == '[' || *tmp == ']') {
+ tmp++;
+ if (*tmp && *tmp != '%')
+ continue;
+ }
+ *ptr++ = *tmp++;
+ }
+ *ptr = '\0';
+
+ *key = new;
+
+ return strlen(new);
+}
+
+static int encode_percent_hack(const char *name, char **key, unsigned int use_class)
+{
+ const char *tmp;
+ unsigned int len = 0;
+ char *ptr, *new;
+
+ if (!key)
+ return -1;
+
+ *key = NULL;
+
+ tmp = name;
+ while (*tmp) {
+ if (*tmp == '%')
+ len++;
+ else if (isupper(*tmp)) {
+ tmp++;
+ len++;
+ if (!use_class)
+ len++;
+ else {
+ if (*tmp && isupper(*tmp))
+ len += 2;
+ else
+ return 0;
+ while (*tmp && isupper(*tmp)) {
+ len++;
+ tmp++;
+ }
+ }
+ continue;
+ }
+ len++;
+ tmp++;
+ }
+ if (len == strlen(name))
+ return 0;
+
+ new = malloc(len + 1);
+ if (!new)
+ return -1;
+
+ ptr = new;
+ tmp = name;
+ while (*tmp) {
+ if (*tmp == '%')
+ *ptr++ = '%';
+ else if (isupper(*tmp)) {
+ char next = *tmp++;
+ *ptr++ = '%';
+ if (*tmp && (!isupper(*tmp) || !use_class))
+ *ptr++ = next;
+ else {
+ *ptr++ = '[';
+ *ptr++ = next;
+ while (*tmp && isupper(*tmp))
+ *ptr++ = *tmp++;
+ *ptr++ = ']';
+ }
+ continue;
+ }
+ *ptr++ = *tmp++;
+ }
+ *ptr = '\0';
+
+ *key = new;
+
+ return strlen(new);
+}
+
static int read_one_map(struct autofs_point *ap,
struct lookup_context *ctxt,
time_t age, int *result_ldap)
@@ -1518,7 +1652,7 @@ static int read_one_map(struct autofs_point *ap,
* people using older schemas that allow '*' as a key
* value. Another case where there can be multiple key
* values is when people have used the "%" hack to specify
- * case matching ctriteria in a caase insensitive attribute.
+ * case matching ctriteria in a case insensitive attribute.
*/
count = ldap_count_values_len(bvKey);
if (count > 1) {
@@ -1647,9 +1781,30 @@ static int read_one_map(struct autofs_point *ap,
*k_val = '*';
}
- s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
- if (!s_key)
- goto next;
+ if (strcasecmp(class, "nisObject")) {
+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
+ if (!s_key)
+ goto next;
+ } else {
+ char *dec_key;
+ int dec_len = decode_percent_hack(k_val, &dec_key);
+
+ if (dec_len < 0) {
+ crit(ap->logopt,
+ "could not use percent hack to decode key %s",
+ k_val);
+ goto next;
+ }
+
+ if (dec_len == 0)
+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
+ else {
+ s_key = sanitize_path(dec_key, dec_len, ap->type, ap->logopt);
+ free(dec_key);
+ }
+ if (!s_key)
+ goto next;
+ }
cache_writelock(mc);
cache_update(mc, source, s_key, mapent, age);
@@ -1712,6 +1867,8 @@ static int lookup_one(struct autofs_point *ap,
char *query;
LDAPMessage *result, *e;
char *class, *info, *entry;
+ char *enc_key1, *enc_key2;
+ int enc_len1 = 0, enc_len2 = 0;
struct berval **bvKey;
struct berval **bvValues;
char *attrs[3];
@@ -1742,14 +1899,38 @@ static int lookup_one(struct autofs_point *ap,
if (*qKey == '*' && qKey_len == 1)
*qKey = '/';
+ else if (!strcasecmp(class, "nisObject")) {
+ enc_len1 = encode_percent_hack(qKey, &enc_key1, 0);
+ if (enc_len1 < 0) {
+ crit(ap->logopt,
+ "could not use percent hack encode key %s",
+ qKey);
+ return CHE_FAIL;
+ }
+ if (enc_len1 != 0) {
+ enc_len2 = encode_percent_hack(qKey, &enc_key2, 1);
+ if (enc_len2 < 0) {
+ crit(ap->logopt,
+ "could not use percent hack encode key %s",
+ qKey);
+ return CHE_FAIL;
+ }
+ }
+ }
/* Build a query string. */
l = strlen(class) + 3*strlen(entry) + strlen(qKey) + 35;
+ if (enc_len1)
+ l += 2*strlen(entry) + enc_len1 + enc_len2 + 6;
query = alloca(l);
if (query == NULL) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
crit(ap->logopt, MODPREFIX "malloc: %s", estr);
+ if (enc_len1) {
+ free(enc_key1);
+ free(enc_key2);
+ }
return CHE_FAIL;
}
@@ -1757,8 +1938,27 @@ static int lookup_one(struct autofs_point *ap,
* Look for an entry in class under ctxt-base
* whose entry is equal to qKey.
*/
- ql = sprintf(query,
- "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))", class, entry, qKey, entry, entry);
+ if (!enc_len1) {
+ ql = sprintf(query,
+ "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))",
+ class, entry, qKey, entry, entry);
+ } else {
+ if (enc_len2) {
+ ql = sprintf(query,
+ "(&(objectclass=%s)"
+ "(|(%s=%s)(%s=%s)(%s=%s)(%s=/)(%s=\\2A)))",
+ class, entry, qKey,
+ entry, enc_key1, entry, enc_key2, entry, entry);
+ free(enc_key1);
+ free(enc_key2);
+ } else {
+ ql = sprintf(query,
+ "(&(objectclass=%s)"
+ "(|(%s=%s)(%s=%s)(%s=/)(%s=\\2A)))",
+ class, entry, qKey, entry, enc_key1, entry, entry);
+ free(enc_key1);
+ }
+ }
if (ql >= l) {
error(ap->logopt,
MODPREFIX "error forming query string");
@@ -1934,9 +2134,30 @@ static int lookup_one(struct autofs_point *ap,
goto next;
}
- s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
- if (!s_key)
- goto next;
+ if (strcasecmp(class, "nisObject")) {
+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
+ if (!s_key)
+ goto next;
+ } else {
+ char *dec_key;
+ int dec_len = decode_percent_hack(k_val, &dec_key);
+
+ if (dec_len < 0) {
+ crit(ap->logopt,
+ "could not use percent hack to decode key %s",
+ k_val);
+ goto next;
+ }
+
+ if (dec_len == 0)
+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
+ else {
+ s_key = sanitize_path(dec_key, dec_len, ap->type, ap->logopt);
+ free(dec_key);
+ }
+ if (!s_key)
+ goto next;
+ }
cache_writelock(mc);
ret = cache_update(mc, source, s_key, mapent, age);
autofs-5.0.2-quell-mount-module-message.patch:
--- NEW FILE autofs-5.0.2-quell-mount-module-message.patch ---
diff --git a/daemon/mount.c b/daemon/mount.c
index 59f8f44..494ede1 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -38,14 +38,21 @@ int do_mount(struct autofs_point *ap, const char *root, const char *name, int na
char **ngp;
int rv;
- mod = open_mount(modstr = fstype, ERR_PREFIX);
+ /* Initially look for a mount module but don't issue an error on fail */
+ mod = open_mount(modstr = fstype, NULL);
if (!mod) {
for (ngp = not_generic; *ngp; ngp++) {
if (!strcmp(fstype, *ngp))
break;
}
+ /*
+ * If there's not a known mount module use the generic module,
+ * otherwise redo the fs mount module with error reporting
+ */
if (!*ngp)
mod = open_mount(modstr = "generic", ERR_PREFIX);
+ else
+ mod = open_mount(modstr = fstype, ERR_PREFIX);
if (!mod) {
error(ap->logopt,
"cannot find mount method for filesystem %s",
autofs-5.0.2-quote-exports-fix.patch:
--- NEW FILE autofs-5.0.2-quote-exports-fix.patch ---
diff -up autofs-5.0.1/modules/parse_sun.c.quote-exports-fix autofs-5.0.1/modules/parse_sun.c
--- autofs-5.0.1/modules/parse_sun.c.quote-exports-fix 2007-12-15 13:23:45.000000000 +0900
+++ autofs-5.0.1/modules/parse_sun.c 2007-12-15 13:24:20.000000000 +0900
@@ -873,7 +873,7 @@ static int parse_mapent(const char *ent,
}
if (!validate_location(loc)) {
- warn(logopt, MODPREFIX "invalid location");
+ warn(logopt, MODPREFIX "invalid location %s", loc);
free(myoptions);
free(loc);
return 0;
@@ -1338,6 +1338,23 @@ int parse_mount(struct autofs_point *ap,
int loclen;
int l;
+ /*
+ * If this is an offset belonging to a multi-mount entry
+ * it's already been parsed (above) and any option string
+ * has already been stripped so just use the remainder.
+ */
+ if (*name == '/' &&
+ (me = cache_lookup_distinct(mc, name)) && me->multi) {
+ loc = strdup(p);
+ if (!loc) {
+ free(options);
+ warn(ap->logopt, MODPREFIX "out of memory");
+ return 1;
+ }
+ loclen = strlen(p);
+ goto mount_it;
+ }
+
l = chunklen(p, check_colon(p));
loc = dequote(p, l, ap->logopt);
if (!loc) {
@@ -1355,9 +1372,9 @@ int parse_mount(struct autofs_point *ap,
}
if (!validate_location(loc)) {
+ warn(ap->logopt, MODPREFIX "invalid location %s", loc);
free(loc);
free(options);
- warn(ap->logopt, MODPREFIX "invalid location");
return 1;
}
@@ -1381,10 +1398,11 @@ int parse_mount(struct autofs_point *ap,
}
if (!validate_location(ent)) {
+ warn(ap->logopt,
+ MODPREFIX "invalid location %s", loc);
free(ent);
free(loc);
free(options);
- warn(ap->logopt, MODPREFIX "invalid location");
return 1;
}
@@ -1418,7 +1436,7 @@ int parse_mount(struct autofs_point *ap,
MODPREFIX "entry %s is empty!", name);
return 1;
}
-
+mount_it:
debug(ap->logopt,
MODPREFIX "core of entry: options=%s, loc=%.*s",
options, loclen, loc);
autofs-5.0.2-remove-unsed-export-validation-code.patch:
--- NEW FILE autofs-5.0.2-remove-unsed-export-validation-code.patch ---
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 831d456..d79a94f 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -52,10 +52,7 @@
/* Get numeric value of the n bits starting at position p */
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n))
-static char *domain = NULL;
-
inline void dump_core(void);
-static pthread_mutex_t networks_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Create a UDP RPC client
@@ -764,573 +761,6 @@ void rpc_exports_free(exports list)
return;
}
-static int masked_match(const char *addr, const char *mask)
-{
- char buf[MAX_IFC_BUF], *ptr;
- struct sockaddr_in saddr;
- struct sockaddr_in6 saddr6;
- struct ifconf ifc;
- struct ifreq *ifr;
- int sock, cl_flags, ret, i, is_ipv4, is_ipv6;
- unsigned int msize;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(LOGOPT_ANY, "socket creation failed: %s", estr);
- return 0;
- }
-
- if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) {
- cl_flags |= FD_CLOEXEC;
- fcntl(sock, F_SETFD, cl_flags);
- }
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_req = (struct ifreq *) buf;
- ret = ioctl(sock, SIOCGIFCONF, &ifc);
- if (ret == -1) {
- close(sock);
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(LOGOPT_ANY, "ioctl: %s", estr);
- return 0;
- }
-
- is_ipv4 = is_ipv6 = 0;
- is_ipv4 = inet_pton(AF_INET, addr, &saddr.sin_addr);
- if (!is_ipv4)
- is_ipv6 = inet_pton(AF_INET6, addr, &saddr6.sin6_addr);
-
- if (strchr(mask, '.')) {
- struct sockaddr_in maddr;
- uint32_t ma;
- int i = 0;
-
- ret = inet_aton(mask, &maddr.sin_addr);
- if (!ret) {
- close(sock);
- return 0;
- }
-
- ma = ntohl((uint32_t) maddr.sin_addr.s_addr);
- while (!(ma & 1)) {
- i++;
- ma = ma >> 1;
- }
-
- msize = i;
- } else
- msize = atoi(mask);
-
- i = 0;
- ptr = (char *) &ifc.ifc_buf[0];
-
- while (ptr < buf + ifc.ifc_len) {
- ifr = (struct ifreq *) ptr;
-
- switch (ifr->ifr_addr.sa_family) {
- case AF_INET:
- {
- struct sockaddr_in *if_addr;
- uint32_t m, ia, ha;
-
- if (!is_ipv4 || msize > 32)
- break;
-
- m = -1;
- m = m << (32 - msize);
- ha = ntohl((uint32_t) saddr.sin_addr.s_addr);
-
- if_addr = (struct sockaddr_in *) &ifr->ifr_addr;
- ia = ntohl((uint32_t) if_addr->sin_addr.s_addr);
-
- if ((ia & m) == (ha & m)) {
- close(sock);
- return 1;
- }
- break;
- }
-
- /* glibc rpc only understands IPv4 atm */
- case AF_INET6:
- break;
-
- default:
- break;
- }
-
- i++;
- ptr = (char *) &ifc.ifc_req[i];
- }
-
- close(sock);
- return 0;
-}
-
-/*
- * This function has been adapted from the match_patern function
- * found in OpenSSH and is used in accordance with the copyright
- * notice found their.
- *
- * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland.
- */
-/*
- * Returns true if the given string matches the pattern (which
- * may contain ? and * as wildcards), and zero if it does not
- * match.
- */
-static int pattern_match(const char *s, const char *pattern)
-{
- for (;;) {
- /* If at end of pattern, accept if also at end of string. */
- if (!*pattern)
- return !*s;
-
- if (*pattern == '*') {
- /* Skip the asterisk. */
- pattern++;
-
- /* If at end of pattern, accept immediately. */
- if (!*pattern)
- return 1;
-
- /* If next character in pattern is known, optimize. */
- if (*pattern != '?' && *pattern != '*') {
- /*
- * Look instances of the next character in
- * pattern, and try to match starting from
- * those.
- */
- for (; *s; s++)
- if (*s == *pattern &&
- pattern_match(s + 1, pattern + 1))
- return 1;
-
- /* Failed. */
- return 0;
- }
- /*
- * Move ahead one character at a time and try to
- * match at each position.
- */
- for (; *s; s++)
- if (pattern_match(s, pattern))
- return 1;
- /* Failed. */
- return 0;
- }
- /*
- * There must be at least one more character in the string.
- * If we are at the end, fail.
- */
- if (!*s)
- return 0;
-
- /* Check if the next character of the string is acceptable. */
- if (*pattern != '?' && *pattern != *s)
- return 0;
-
- /* Move to the next character, both in string and in pattern. */
- s++;
- pattern++;
- }
- /* NOTREACHED */
-}
-
-static int name_match(const char *name, const char *pattern)
-{
- int ret;
-
- if (strchr(pattern, '*') || strchr(pattern, '?'))
- ret = pattern_match(name, pattern);
- else {
- ret = !memcmp(name, pattern, strlen(pattern));
- /* Name could still be a netgroup (Solaris) */
- if (!ret)
- ret = innetgr(pattern, name, NULL, domain);
- }
-
- return ret;
-}
-
-static int fqdn_match(const char *pattern)
-{
- char buf[MAX_IFC_BUF], *ptr;
- struct ifconf ifc;
- struct ifreq *ifr;
- int sock, cl_flags, ret, i;
- char fqdn[NI_MAXHOST + 1];
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(LOGOPT_ANY, "socket creation failed: %s", estr);
- return 0;
- }
-
- if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) {
- cl_flags |= FD_CLOEXEC;
- fcntl(sock, F_SETFD, cl_flags);
- }
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_req = (struct ifreq *) buf;
- ret = ioctl(sock, SIOCGIFCONF, &ifc);
- if (ret == -1) {
- close(sock);
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(LOGOPT_ANY, "ioctl: %s", estr);
- return 0;
- }
-
- i = 0;
- ptr = (char *) &ifc.ifc_buf[0];
-
- while (ptr < buf + ifc.ifc_len) {
- ifr = (struct ifreq *) ptr;
-
- switch (ifr->ifr_addr.sa_family) {
- case AF_INET:
- {
- socklen_t slen = sizeof(struct sockaddr);
-
- ret = getnameinfo(&ifr->ifr_addr, slen, fqdn,
- NI_MAXHOST, NULL, 0, NI_NAMEREQD);
- if (!ret) {
- ret = name_match(fqdn, pattern);
- if (ret) {
- close(sock);
- return 1;
- }
- }
- break;
- }
-
- /* glibc rpc only understands IPv4 atm */
- case AF_INET6:
- break;
-
- default:
- break;
- }
-
- i++;
- ptr = (char *) &ifc.ifc_req[i];
- }
-
- close(sock);
- return 0;
-}
-
-static int string_match(const char *myname, const char *pattern)
-{
- struct addrinfo hints, *ni;
- int ret;
-
- /* Try simple name match first */
- ret = name_match(myname, pattern);
- if (ret)
- goto done;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_CANONNAME;
- hints.ai_family = 0;
- hints.ai_socktype = 0;
-
- /* See if our canonical name matches */
- if (getaddrinfo(myname, NULL, &hints, &ni) == 0) {
- ret = name_match(ni->ai_canonname, pattern);
- freeaddrinfo(ni);
- } else
- warn(LOGOPT_ANY, "name lookup failed: %s", gai_strerror(ret));
- if (ret)
- goto done;
-
- /* Lastly see if the name of an interfaces matches */
- ret = fqdn_match(pattern);
-done:
- return ret;
-}
-
-static unsigned int inet_get_net_len(uint32_t net)
-{
- int i;
-
- for (i = 0; i < 32; i += 8) {
- if (getbits(net, i + 7, 8))
- break;
- }
-
- return (unsigned int) 32 - i;
-}
-
-static char *inet_fill_net(const char *net_num, char *net)
-{
- char *np;
- unsigned int dots = 3;
-
- if (strlen(net_num) > INET_ADDRSTRLEN)
- return NULL;
-
- if (!isdigit(*net_num))
- return NULL;
-
- *net = '\0';
- strcpy(net, net_num);
-
- np = net;
- while (*np++) {
- if (*np == '.') {
- np++;
- dots--;
- if (!*np && dots)
- strcat(net, "0");
- continue;
- }
-
- if ((*np && !isdigit(*np)) || dots < 0) {
- *net = '\0';
- return NULL;
- }
- }
-
- while (dots--)
- strcat(net, ".0");
-
- return net;
-}
-
-static int match_network(const char *network)
-{
- struct netent *pnent, nent;
- const char *pcnet;
- char *net, cnet[MAX_NETWORK_LEN], mask[4], *pmask;
- unsigned int size;
- size_t l_network = strlen(network) + 1;
- int status;
-
- if (l_network > MAX_NETWORK_LEN) {
- error(LOGOPT_ANY,
- "match string \"%s\" too long", network);
- return 0;
- }
-
- net = alloca(l_network);
- if (!net)
- return 0;
- memset(net, 0, l_network);
- strcpy(net, network);
-
- if ((pmask = strchr(net, '/')))
- *pmask++ = '\0';
-
- status = pthread_mutex_lock(&networks_mutex);
- if (status)
- fatal(status);
-
- pnent = getnetbyname(net);
- if (pnent)
- memcpy(&nent, pnent, sizeof(struct netent));
-
- status = pthread_mutex_unlock(&networks_mutex);
- if (status)
- fatal(status);
-
- if (pnent) {
- uint32_t n_net;
-
- switch (nent.n_addrtype) {
- case AF_INET:
- n_net = ntohl(nent.n_net);
- pcnet = inet_ntop(AF_INET, &n_net, cnet, INET_ADDRSTRLEN);
- if (!pcnet)
- return 0;
-
- if (!pmask) {
- size = inet_get_net_len(nent.n_net);
- if (!size)
- return 0;
- }
- break;
-
- case AF_INET6:
- return 0;
-
- default:
- return 0;
- }
- } else {
- int ret;
-
- if (strchr(net, ':')) {
- return 0;
- } else {
- struct in_addr addr;
-
- pcnet = inet_fill_net(net, cnet);
- if (!pcnet)
- return 0;
-
- ret = inet_pton(AF_INET, pcnet, &addr);
- if (ret <= 0)
- return 0;
-
- if (!pmask) {
- uint32_t nl_addr = htonl(addr.s_addr);
- size = inet_get_net_len(nl_addr);
- if (!size)
- return 0;
- }
- }
- }
-
- if (!pmask) {
- if (sprintf(mask, "%u", size) <= 0)
- return 0;
- pmask = mask;
- }
-
- debug(LOGOPT_ANY, "pcnet %s pmask %s", pcnet, pmask);
-
- return masked_match(pcnet, pmask);
-}
-
-/*
- * Two export formats need to be understood to cater for different
- * NFS server exports.
- *
- * (host|wildcard|network[/mask]|@netgroup)
- *
- * A host name which can be cannonical.
- * A wildcard host name containing "*" and "?" with the usual meaning.
- * A network in numbers and dots form with optional mask given as
- * either a length or as numbers and dots.
- * A netgroup identified by the prefix "@".
- *
- * [-](host|domain suffix|netgroup|@network[/mask])
- *
- * A host name which can be cannonical.
- * A domain suffix identified by a leading "." which will match all
- * hosts in the given domain.
- * A netgroup.
- * A network identified by the prefix "@" given in numbers and dots
- * form or as a network name with optional mask given as either a
- * length or as numbers and dots.
- * A "-" prefix can be appended to indicate access is denied.
- */
-static int host_match(char *pattern)
-{
- unsigned int negate = (*pattern == '-');
- const char *m_pattern = (negate ? pattern + 1 : pattern);
- char myname[MAXHOSTNAMELEN + 1] = "\0";
- int ret = 0;
-
- if (gethostname(myname, MAXHOSTNAMELEN))
- return 0;
-
- if (yp_get_default_domain(&domain))
- domain = NULL;
-
- if (*m_pattern == '@') {
- /*
- * The pattern begins with an "@" so it's a network
- * spec or it's a netgroup.
- */
- ret = match_network(m_pattern + 1);
- if (!ret)
- ret = innetgr(m_pattern + 1, myname, NULL, domain);
- } else if (*m_pattern == '.') {
- size_t m_len = strlen(m_pattern);
- char *has_dot = strchr(myname, '.');
- /*
- * The pattern starts with a "." so it's a domain spec
- * of some sort.
- *
- * If the host name contains a dot then it must be either
- * a cannonical name or a simple NIS name.domain. So
- * perform a string match. Otherwise, append the domain
- * pattern to our simple name and try a wildcard pattern
- * match against the interfaces.
- */
- if (has_dot) {
- if (strlen(has_dot) == m_len)
- ret = !memcmp(has_dot, m_pattern, m_len);
- } else {
- char *w_pattern = alloca(m_len + 2);
- if (w_pattern) {
- strcpy(w_pattern, "*");
- strcat(w_pattern, m_pattern);
- ret = fqdn_match(w_pattern);
- }
- }
- } else if (!strcmp(m_pattern, "gss/krb5")) {
- /* Leave this to the GSS layer */
- return 1;
- } else {
- /*
- * Otherwise it's a network name or host name
- */
- ret = match_network(m_pattern);
- if (!ret)
- /* if not then try to match host name */
- ret = string_match(myname, m_pattern);
- }
-
- if (negate && ret)
- ret = -1;
-
- return ret;
-}
-
-static int rpc_export_allowed(groups grouplist)
-{
- groups grp = grouplist;
-
- /* NULL group list => everyone */
- if (!grp)
- return 1;
-
- while (grp) {
- int allowed = host_match(grp->gr_name);
- /* Explicitly denied access */
- if (allowed == -1)
- return 0;
- else if (allowed)
- return 1;
- grp = grp->gr_next;
- }
- return 0;
-}
-
-exports rpc_exports_prune(exports list)
-{
- exports head = list;
- exports exp;
- exports last;
- int res;
-
- exp = list;
- last = NULL;
- while (exp) {
- res = rpc_export_allowed(exp->ex_groups);
- if (!res) {
- if (last == NULL) {
- head = exp->ex_next;
- rpc_export_free(exp);
- exp = head;
- } else {
- last->ex_next = exp->ex_next;
- rpc_export_free(exp);
- exp = last->ex_next;
- }
- continue;
- }
- last = exp;
- exp = exp->ex_next;
- }
- return head;
-}
-
exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option)
{
struct conn_info info;
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 1f8fa15..d711611 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -45,7 +45,6 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
-exports rpc_exports_prune(exports list);
void rpc_exports_free(exports list);
int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
@@ -207,9 +206,6 @@ done:
exp = rpc_get_exports(name, 10, 0, RPC_CLOSE_NOLINGER);
- /* Check exports for obvious ones we don't have access to */
- /*exp = rpc_exports_prune(exp);*/
-
mapent = NULL;
while (exp) {
if (mapent) {
autofs-5.0.2-start-pipe-buff-size.patch:
--- NEW FILE autofs-5.0.2-start-pipe-buff-size.patch ---
diff --git a/daemon/automount.c b/daemon/automount.c
index 7becad5..f31ec11 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1125,7 +1125,7 @@ static void become_daemon(unsigned foreground)
if (pid > 0) {
int r;
close(start_pipefd[1]);
- r = read(start_pipefd[0], pst_stat, sizeof(pst_stat));
+ r = read(start_pipefd[0], pst_stat, sizeof(*pst_stat));
if (r < 0)
exit(1);
exit(*pst_stat);
@@ -2061,12 +2061,12 @@ int main(int argc, char *argv[])
if (!master_read_master(master_list, age, 0)) {
master_kill(master_list);
*pst_stat = 3;
- res = write(start_pipefd[1], pst_stat, sizeof(pst_stat));
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
exit(3);
}
- res = write(start_pipefd[1], pst_stat, sizeof(pst_stat));
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
state_mach_thid = pthread_self();
autofs-5.0.2-submount-shutdown-race.patch:
--- NEW FILE autofs-5.0.2-submount-shutdown-race.patch ---
diff --git a/daemon/automount.c b/daemon/automount.c
index f31ec11..afbcb56 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1564,9 +1564,24 @@ void *handle_mounts(void *arg)
}
/* OK to exit */
- if (ap->state == ST_SHUTDOWN || result) {
- state_mutex_unlock(ap);
- break;
+ if (ap->state == ST_SHUTDOWN) {
+ if (result) {
+ state_mutex_unlock(ap);
+ break;
+ }
+#ifdef ENABLE_IGNORE_BUSY_MOUNTS
+ /*
+ * There weren't any active mounts but if the
+ * filesystem is busy there may be a mount
+ * request in progress so return to the ready
+ * state unless a shutdown has been explicitly
+ * requested.
+ */
+ if (ap->shutdown) {
+ state_mutex_unlock(ap);
+ break;
+ }
+#endif
}
/* Failed shutdown returns to ready */
diff --git a/daemon/direct.c b/daemon/direct.c
index 619efce..529f143 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1494,7 +1494,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
(unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
/* Ignore packet if we're trying to shut down */
- if (ap->state == ST_SHUTDOWN_PENDING ||
+ if (ap->shutdown ||
ap->state == ST_SHUTDOWN_FORCE ||
ap->state == ST_SHUTDOWN) {
send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index f6b93d0..fd94e59 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -863,7 +863,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
(unsigned long) pkt->wait_queue_token, pkt->name, pkt->pid);
/* Ignore packet if we're trying to shut down */
- if (ap->state == ST_SHUTDOWN_PENDING ||
+ if (ap->shutdown ||
ap->state == ST_SHUTDOWN_FORCE ||
ap->state == ST_SHUTDOWN) {
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index eb72411..eac6053 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -928,10 +928,17 @@ void lookup_close_lookup(struct autofs_point *ap)
if (!map)
return;
+ /*
+ * Make sure we don't kill the context if a mount
+ * request has come in while were shutting down.
+ */
+ master_source_writelock(ap->entry);
while (map) {
lookup_close_lookup_instances(map);
map = map->next;
}
+ master_source_unlock(ap->entry);
+
return;
}
diff --git a/daemon/state.c b/daemon/state.c
index 5bccfef..5804707 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -113,6 +113,8 @@ void expire_cleanup(void *arg)
/* Check to see if expire process finished */
if (thid == ap->exp_thread) {
+ int rv, idle;
+
ap->exp_thread = 0;
switch (ap->state) {
@@ -133,8 +135,6 @@ void expire_cleanup(void *arg)
* allowing it to shutdown.
*/
if (ap->submount && !success) {
- int rv, idle;
-
rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &idle);
if (!rv && idle && ap->submount > 1) {
next = ST_SHUTDOWN_PENDING;
@@ -155,6 +155,19 @@ void expire_cleanup(void *arg)
break;
case ST_SHUTDOWN_PENDING:
+ /*
+ * If we reveive a mount request while trying to
+ * shutdown return to ready state unless we have
+ * been signaled to shutdown.
+ */
+ rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &idle);
+ if (!idle && !ap->shutdown) {
+ next = ST_READY;
+ if (!ap->submount)
+ alarm_add(ap, ap->exp_runfreq);
+ break;
+ }
+
next = ST_SHUTDOWN;
#ifdef ENABLE_IGNORE_BUSY_MOUNTS
break;
@@ -200,6 +213,7 @@ static unsigned int st_ready(struct autofs_point *ap)
debug(ap->logopt,
"st_ready(): state = %d path %s", ap->state, ap->path);
+ ap->shutdown = 0;
ap->state = ST_READY;
if (ap->submount)
diff --git a/include/automount.h b/include/automount.h
index 133fd32..cd8ce7b 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -461,6 +461,7 @@ struct autofs_point {
unsigned int mounts_signaled; /* Submount signals task complete */
struct list_head mounts; /* List of autofs mounts at current level */
unsigned int submount; /* Is this a submount */
+ unsigned int shutdown; /* Shutdown notification */
unsigned int submnt_count; /* Number of submounts */
struct list_head submounts; /* List of child submounts */
};
diff --git a/lib/master.c b/lib/master.c
index c001d20..ed82131 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -94,6 +94,7 @@ int master_add_autofs_point(struct master_mapent *entry,
ap->submount = submount;
INIT_LIST_HEAD(&ap->mounts);
INIT_LIST_HEAD(&ap->submounts);
+ ap->shutdown = 0;
status = pthread_mutex_init(&ap->state_mutex, NULL);
if (status) {
@@ -968,6 +969,7 @@ void master_notify_state_change(struct master *master, int sig)
if (ap->state != ST_SHUTDOWN_PENDING &&
ap->state != ST_SHUTDOWN_FORCE) {
next = ST_SHUTDOWN_PENDING;
+ ap->shutdown = 1;
nextstate(state_pipe, next);
}
break;
@@ -1180,9 +1182,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
continue;
}
- master_source_writelock(this);
lookup_close_lookup(ap);
- master_source_unlock(this);
cache_readlock(nc);
ne = cache_lookup_distinct(nc, this->path);
autofs-5.0.3-basedn-with-spaces-fix-3.patch:
--- NEW FILE autofs-5.0.3-basedn-with-spaces-fix-3.patch ---
diff --git a/lib/master_tok.l b/lib/master_tok.l
index 2a6fdf9..7f1de90 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -289,7 +289,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
return EQUAL;
}
- {DNNAMESTR1}/"," {
+ {DNNAMESTR1}/","{DNATTRSTR}"=" {
strcpy(master_lval.strtype, master_text);
return DNNAME;
}
autofs-5.0.3-correct-ldap-lib.patch:
--- NEW FILE autofs-5.0.3-correct-ldap-lib.patch ---
diff --git a/aclocal.m4 b/aclocal.m4
index f24e076..a1105ae 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -232,7 +232,7 @@ AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL],
# save current ldflags
af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap_r"
+LDFLAGS="$LDFLAGS -lldap"
AC_TRY_LINK(
[ #include <ldap.h> ],
@@ -265,7 +265,7 @@ AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL],
# save current ldflags
af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap_r"
+LDFLAGS="$LDFLAGS -lldap"
AC_TRY_LINK(
[ #include <ldap.h> ],
diff --git a/configure b/configure
index e872392..0d3268c 100755
--- a/configure
+++ b/configure
@@ -4563,7 +4563,7 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5
echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6; }
if test $ac_cv_lib_ldap_ldap_initialize = yes; then
- HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv"
+ HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv"
fi
if test "$HAVE_LDAP" = "1"; then
@@ -4578,7 +4578,7 @@ echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; }
# save current ldflags
af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap_r"
+LDFLAGS="$LDFLAGS -lldap"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -4648,7 +4648,7 @@ echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; }
# save current ldflags
af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap_r"
+LDFLAGS="$LDFLAGS -lldap"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
diff --git a/configure.in b/configure.in
index a9c86dd..27b9bec 100644
--- a/configure.in
+++ b/configure.in
@@ -197,7 +197,7 @@ AC_ARG_WITH(openldap,
if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then
HAVE_LDAP=0
LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1"
- AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv", ,
+ AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv", ,
-llber -lresolv $LIBS)
if test "$HAVE_LDAP" = "1"; then
AC_DEFINE(WITH_LDAP,1,
autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch:
--- NEW FILE autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch ---
diff --git a/lib/master.c b/lib/master.c
index ed82131..4a34dd4 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -799,21 +799,13 @@ int master_read_master(struct master *master, time_t age, int readall)
master_init_scan();
- if (!lookup_nss_read_master(master, age)) {
- error(logopt,
- "can't read master map %s", master->name);
- return 0;
- }
-
+ lookup_nss_read_master(master, age);
master_mount_mounts(master, age, readall);
master_mutex_lock();
- if (list_empty(&master->mounts)) {
- master_mutex_unlock();
+ if (list_empty(&master->mounts))
warn(logopt, "no mounts in table");
- return 1;
- }
master_mutex_unlock();
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index b01eea6..466690a 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -475,6 +475,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
"failed to read included master map %s",
master->name);
if (!master->recurse) {
+ master->name = save_name;
master->depth--;
master->recurse = 0;
fclose(f);
autofs-5.0.3-expire-works-too-hard.patch:
--- NEW FILE autofs-5.0.3-expire-works-too-hard.patch ---
diff --git a/daemon/direct.c b/daemon/direct.c
index 529f143..760fbd4 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -824,11 +824,16 @@ static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsig
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel try the same mount again, limited by
+ * retries (ie. number of mounts directly under
+ * mount point, should always be one for direct
+ * mounts).
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index fd94e59..39b42da 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -344,11 +344,13 @@ static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *pat
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel will try the next mount.
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
autofs-5.0.3-ldap-page-control-configure-fix.patch:
--- NEW FILE autofs-5.0.3-ldap-page-control-configure-fix.patch ---
diff --git a/aclocal.m4 b/aclocal.m4
index 118ef0d..f24e076 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -222,3 +222,69 @@ AC_TRY_LINK(
LDFLAGS="$af_check_hesiod_save_ldflags"
])
+dnl --------------------------------------------------------------------------
+dnl AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL
+dnl
+dnl Check for function ldap_create_page_control
+dnl --------------------------------------------------------------------------
+AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL],
+[AC_MSG_CHECKING(for ldap_create_page_control in -lldap)
+
+# save current ldflags
+af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS -lldap_r"
+
+AC_TRY_LINK(
+ [ #include <ldap.h> ],
+ [ LDAP *ld;
+ ber_int_t ps;
+ struct berval *c;
+ int ic, ret;
+ LDAPControl **clp;
+ ret = ldap_create_page_control(ld,ps,c,ic,clp); ],
+ [ af_have_ldap_create_page_control=yes
+ AC_MSG_RESULT(yes) ],
+ [ AC_MSG_RESULT(no) ])
+
+if test "$af_have_ldap_create_page_control" = "yes"; then
+ AC_DEFINE(HAVE_LDAP_CREATE_PAGE_CONTROL, 1,
+ [Define to 1 if you have the `ldap_create_page_control' function.])
+fi
+
+# restore ldflags
+LDFLAGS="$af_check_ldap_create_page_control_save_ldflags"
+])
+
+dnl --------------------------------------------------------------------------
+dnl AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL
+dnl
+dnl Check for function ldap_parse_page_control
+dnl --------------------------------------------------------------------------
+AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL],
+[AC_MSG_CHECKING(for ldap_parse_page_control in -lldap)
+
+# save current ldflags
+af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS -lldap_r"
+
+AC_TRY_LINK(
+ [ #include <ldap.h> ],
+ [ LDAP *ld;
+ ber_int_t ct;
+ struct berval *c;
+ int ret;
+ LDAPControl **clp;
+ ret = ldap_parse_page_control(ld,clp,ct,c); ],
+ [ af_have_ldap_parse_page_control=yes
+ AC_MSG_RESULT(yes) ],
+ [ AC_MSG_RESULT(no) ])
+
+if test "$af_have_ldap_create_page_control" = "yes"; then
+ AC_DEFINE(HAVE_LDAP_PARSE_PAGE_CONTROL, 1,
+ [Define to 1 if you have the `ldap_parse_page_control' function.])
+fi
+
+# restore ldflags
+LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags"
+])
+
diff --git a/configure b/configure
index d212b05..e872392 100755
--- a/configure
+++ b/configure
@@ -3631,7 +3631,7 @@ if test "${with_hesiod+set}" = set; then
fi
-if test -z "$HAVE_HESIOD"
+if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0"
then
HAVE_HESIOD=0
{ echo "$as_me:$LINENO: checking for libhesiod" >&5
@@ -4498,7 +4498,7 @@ if test "${with_openldap+set}" = set; then
fi
-if test -z "$HAVE_LDAP"; then
+if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then
HAVE_LDAP=0
LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1"
{ echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5
@@ -4566,71 +4566,106 @@ if test $ac_cv_lib_ldap_ldap_initialize = yes; then
HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv"
fi
- if test "$HAVE_LDAP" == "1"; then
+ if test "$HAVE_LDAP" = "1"; then
cat >>confdefs.h <<\_ACEOF
#define WITH_LDAP 1
_ACEOF
fi
+ { echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5
+echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; }
+
+# save current ldflags
+af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS -lldap_r"
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+ #include <ldap.h>
+int
+main ()
+{
+ LDAP *ld;
+ ber_int_t ps;
+ struct berval *c;
+ int ic, ret;
+ LDAPControl **clp;
+ ret = ldap_create_page_control(ld,ps,c,ic,clp);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ af_have_ldap_create_page_control=yes
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$af_have_ldap_create_page_control" = "yes"; then
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LDAP_CREATE_PAGE_CONTROL 1
+_ACEOF
-LDFLAGS="${AF_tmp_ldflags}"
+fi
+# restore ldflags
+LDFLAGS="$af_check_ldap_create_page_control_save_ldflags"
+ { echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5
+echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; }
-for ac_func in ldap_create_page_control ldap_parse_page_control
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
+# save current ldflags
+af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS -lldap_r"
+
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
+ #include <ldap.h>
int
main ()
{
-return $ac_func ();
+ LDAP *ld;
+ ber_int_t ct;
+ struct berval *c;
+ int ret;
+ LDAPControl **clp;
+ ret = ldap_parse_page_control(ld,clp,ct,c);
;
return 0;
}
@@ -4653,28 +4688,37 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
+ af_have_ldap_parse_page_control=yes
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- eval "$as_ac_var=no"
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+
+if test "$af_have_ldap_create_page_control" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LDAP_PARSE_PAGE_CONTROL 1
_ACEOF
fi
-done
+# restore ldflags
+LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags"
+
+fi
+
+
+
+
+LDFLAGS="${AF_tmp_ldflags}"
#
# SASL support
@@ -4703,7 +4747,7 @@ if test "${with_sasl+set}" = set; then
fi
-if test -z "$HAVE_SASL" -a "$HAVE_LIBXML" == "1"
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
then
HAVE_SASL=0
{ echo "$as_me:$LINENO: checking for sasl_client_start in -lsasl2" >&5
diff --git a/configure.in b/configure.in
index 952d040..a9c86dd 100644
--- a/configure.in
+++ b/configure.in
@@ -155,7 +155,7 @@ AC_ARG_WITH(hesiod,
fi
)
-if test -z "$HAVE_HESIOD"
+if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0"
then
HAVE_HESIOD=0
AF_CHECK_LIBHESIOD()
@@ -194,15 +194,17 @@ AC_ARG_WITH(openldap,
LDAP_FLAGS="-I${withval}/include"
fi
)
-if test -z "$HAVE_LDAP"; then
+if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then
HAVE_LDAP=0
LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1"
AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv", ,
-llber -lresolv $LIBS)
- if test "$HAVE_LDAP" == "1"; then
+ if test "$HAVE_LDAP" = "1"; then
AC_DEFINE(WITH_LDAP,1,
[Define if using LDAP as a source of automount maps])
fi
+ AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL()
+ AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL()
fi
AC_SUBST(LDAP_FLAGS)
@@ -210,8 +212,6 @@ AC_SUBST(HAVE_LDAP)
AC_SUBST(LIBLDAP)
LDFLAGS="${AF_tmp_ldflags}"
-AC_CHECK_FUNCS(ldap_create_page_control ldap_parse_page_control)
-
#
# SASL support
# configure magic taken from:
@@ -236,7 +236,7 @@ AC_ARG_WITH(sasl,
SASL_FLAGS="-I${withval}/include"
fi
)
-if test -z "$HAVE_SASL" -a "$HAVE_LIBXML" == "1"
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
then
HAVE_SASL=0
AC_CHECK_LIB(sasl2, sasl_client_start, HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2", , -lsasl2 $LIBS)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 0723fd8..e8530f6 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -55,7 +55,7 @@ struct ldap_search_params {
char *query, **attrs;
struct berval *cookie;
int morePages;
- unsigned int totalCount;
+ ber_int_t totalCount;
LDAPMessage *result;
time_t age;
};
@@ -63,7 +63,7 @@ struct ldap_search_params {
static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *);
#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
-int ldap_create_page_control(LDAP *ldap, unsigned int pagesize,
+int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize,
struct berval *cookie, char isCritical,
LDAPControl **output)
{
@@ -93,7 +93,7 @@ int ldap_create_page_control(LDAP *ldap, unsigned int pagesize,
#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL
int ldap_parse_page_control(LDAP *ldap, LDAPControl **controls,
- unsigned int *totalcount, struct berval **cookie)
+ ber_int_t *totalcount, struct berval **cookie)
{
int i, rc;
BerElement *theBer;
@@ -1644,7 +1644,7 @@ static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *
struct autofs_point *ap = sp->ap;
LDAPControl *pageControl=NULL, *controls[2] = { NULL, NULL };
LDAPControl **returnedControls = NULL;
- static unsigned long pageSize = 1000;
+ static ber_int_t pageSize = 1000;
static char pagingCriticality = 'T';
int rv, scope = LDAP_SCOPE_SUBTREE;
autofs-5.0.3-nfs4-tcp-only.patch:
--- NEW FILE autofs-5.0.3-nfs4-tcp-only.patch ---
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 0e7aebe..df01fd6 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -129,7 +129,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
}
if (strcmp(fstype, "nfs4") == 0)
- vers = NFS4_VERS_MASK | NFS_PROTO_MASK;
+ vers = NFS4_VERS_MASK | TCP_SUPPORTED;
else
vers = NFS_VERS_MASK | NFS_PROTO_MASK;
autofs-5.0.3-unlink-mount-return-fix.patch:
--- NEW FILE autofs-5.0.3-unlink-mount-return-fix.patch ---
diff --git a/daemon/direct.c b/daemon/direct.c
index 760fbd4..8d1e9c6 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -275,7 +275,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
else
rv = umount2(mnt->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", mnt->path);
@@ -287,6 +286,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 39b42da..f0409ac 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -65,7 +65,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
else
rv = umount2(this->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", this->path);
@@ -77,6 +76,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}
autofs-5.0.3-xfn-not-supported.patch:
--- NEW FILE autofs-5.0.3-xfn-not-supported.patch ---
diff --git a/lib/master_parse.y b/lib/master_parse.y
index b450122..2184b4f 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -50,6 +50,7 @@ static int add_multi_mapstr(void);
static int master_error(const char *s);
static int master_notify(const char *s);
+static int master_msg(const char *s);
static char *path;
static char *type;
@@ -119,6 +120,7 @@ static int master_fprintf(FILE *, char *, ...);
%token <strtype> DNNAME
%token <strtype> MAPHOSTS
%token <strtype> MAPNULL
+%token <strtype> MAPXFN
%token <strtype> MAPNAME
%token <inttype> NUMBER
%token <strtype> OPTION
@@ -283,6 +285,12 @@ map: PATH
YYABORT;
}
}
+ | MAPXFN
+ {
+ master_notify($1);
+ master_msg("X/Open Federated Naming service not supported");
+ YYABORT;
+ }
| MAPNULL
{
type = master_strdup($1 + 1);
@@ -598,6 +606,12 @@ static int master_notify(const char *s)
return(0);
}
+static int master_msg(const char *s)
+{
+ logmsg("%s", s);
+ return 0;
+}
+
static void local_init_vars(void)
{
path = NULL;
diff --git a/lib/master_tok.l b/lib/master_tok.l
index d908047..2a6fdf9 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -215,6 +215,12 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
return MAPNULL;
}
+ "-xfn" {
+ BEGIN(OPTSTR);
+ strcpy(master_lval.strtype, master_text);
+ return MAPXFN;
+ }
+
"//" {
BEGIN(DNSTR);
yyless(0);
autofs-5.0.2-basedn-with-spaces.patch:
Index: autofs-5.0.2-basedn-with-spaces.patch
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-8/autofs-5.0.2-basedn-with-spaces.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- autofs-5.0.2-basedn-with-spaces.patch 20 Nov 2007 07:54:34 -0000 1.1
+++ autofs-5.0.2-basedn-with-spaces.patch 14 Feb 2008 07:28:32 -0000 1.2
@@ -1,105 +1,21 @@
-diff -Nurp autofs-5.0.2.orig/lib/master_tok.l autofs-5.0.2/lib/master_tok.l
---- autofs-5.0.2.orig/lib/master_tok.l 2007-11-20 15:37:48.000000000 +0900
-+++ autofs-5.0.2/lib/master_tok.l 2007-11-20 15:38:21.000000000 +0900
-@@ -108,7 +108,8 @@ AT_DC ([dD][[cC])
- AT_O ([oO])
+diff --git a/lib/master_tok.l b/lib/master_tok.l
+index 00cd223..48bc233 100644
+--- a/lib/master_tok.l
++++ b/lib/master_tok.l
+@@ -109,6 +109,7 @@ AT_O ([oO])
AT_C ([cC])
DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
--DNNAMESTR ([[:alnum:]_.\-]+)
-+DNNAMESTR1 ([[:alnum:]_.\- ]+)
-+DNNAMESTR2 ([[:alnum:]_.\-]+)
+ DNNAMESTR ([[:alnum:]_.\-]+)
++DNNAMETRM (,|{WS}{NL}|{WS}#.*|\x00)
INTMAP (-hosts|-null)
MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
-@@ -281,7 +282,12 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--
+@@ -281,7 +282,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
return EQUAL;
}
- {DNNAMESTR} {
-+ {DNNAMESTR1}/"," {
-+ strcpy(master_lval.strtype, master_text);
-+ return DNNAME;
-+ }
-+
-+ {DNNAMESTR2} {
++ {DNNAMESTR}/{DNNAMETRM} {
strcpy(master_lval.strtype, master_text);
return DNNAME;
}
-@@ -378,7 +384,13 @@ void master_set_scan_buffer(const char *
- {
- line = buffer;
- line_pos = &line[0];
-- line_lim = line + strlen(buffer);
-+ /*
-+ * Ensure buffer is 1 greater than string and is zeroed before
-+ * the parse so we can fit the extra NULL which allows us to
-+ * explicitly match an end of line within the buffer (ie. the
-+ * need for 2 NULLS when parsing in memeory buffers).
-+ */
-+ line_lim = line + strlen(buffer) + 1;
- }
-
- #define min(a,b) (((a) < (b)) ? (a) : (b))
-diff -Nurp autofs-5.0.2.orig/modules/lookup_file.c autofs-5.0.2/modules/lookup_file.c
---- autofs-5.0.2.orig/modules/lookup_file.c 2007-11-20 15:37:48.000000000 +0900
-+++ autofs-5.0.2/modules/lookup_file.c 2007-11-20 15:38:18.000000000 +0900
-@@ -479,7 +479,7 @@ int lookup_read_master(struct master *ma
-
- master->name = save_name;
- } else {
-- blen = path_len + 1 + ent_len + 1;
-+ blen = path_len + 1 + ent_len + 2;
- buffer = malloc(blen);
- if (!buffer) {
- error(logopt,
-diff -Nurp autofs-5.0.2.orig/modules/lookup_ldap.c autofs-5.0.2/modules/lookup_ldap.c
---- autofs-5.0.2.orig/modules/lookup_ldap.c 2007-11-20 15:37:48.000000000 +0900
-+++ autofs-5.0.2/modules/lookup_ldap.c 2007-11-20 15:38:18.000000000 +0900
-@@ -1368,7 +1368,7 @@ int lookup_read_master(struct master *ma
- goto next;
- }
-
-- blen = strlen(*keyValue) + 1 + strlen(*values) + 1;
-+ blen = strlen(*keyValue) + 1 + strlen(*values) + 2;
- if (blen > PARSE_MAX_BUF) {
- error(logopt, MODPREFIX "map entry too long");
- ldap_value_free(values);
-diff -Nurp autofs-5.0.2.orig/modules/lookup_nisplus.c autofs-5.0.2/modules/lookup_nisplus.c
---- autofs-5.0.2.orig/modules/lookup_nisplus.c 2007-11-20 15:37:48.000000000 +0900
-+++ autofs-5.0.2/modules/lookup_nisplus.c 2007-11-20 15:38:18.000000000 +0900
-@@ -90,7 +90,7 @@ int lookup_read_master(struct master *ma
- char *path, *ent;
- char *buffer;
- char buf[MAX_ERR_BUF];
-- int cur_state;
-+ int cur_state, len;
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
-@@ -138,11 +138,13 @@ int lookup_read_master(struct master *ma
-
- ent = ENTRY_VAL(this, 1);
-
-- buffer = malloc(ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 1);
-+ len = ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 2;
-+ buffer = malloc(len);
- if (!buffer) {
- logerr(MODPREFIX "could not malloc parse buffer");
- continue;
- }
-+ memset(buffer, 0, len);
-
- strcat(buffer, path);
- strcat(buffer, " ");
-diff -Nurp autofs-5.0.2.orig/modules/lookup_yp.c autofs-5.0.2/modules/lookup_yp.c
---- autofs-5.0.2.orig/modules/lookup_yp.c 2007-11-20 15:37:48.000000000 +0900
-+++ autofs-5.0.2/modules/lookup_yp.c 2007-11-20 15:38:18.000000000 +0900
-@@ -178,7 +178,7 @@ int yp_all_master_callback(int status, c
- *(ypkey + ypkeylen) = '\0';
- *(val + vallen) = '\0';
-
-- len = ypkeylen + 1 + vallen + 1;
-+ len = ypkeylen + 1 + vallen + 2;
-
- buffer = alloca(len);
- if (!buffer) {
autofs-5.0.2-foreground-logging.patch:
Index: autofs-5.0.2-foreground-logging.patch
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-8/autofs-5.0.2-foreground-logging.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- autofs-5.0.2-foreground-logging.patch 24 Sep 2007 06:58:44 -0000 1.1
+++ autofs-5.0.2-foreground-logging.patch 14 Feb 2008 07:28:32 -0000 1.2
@@ -1,43 +1,8 @@
-diff -up autofs-5.0.2/modules/lookup_ldap.c.foreground-logging autofs-5.0.2/modules/lookup_ldap.c
---- autofs-5.0.2/modules/lookup_ldap.c.foreground-logging 2007-09-24 14:42:28.000000000 +0800
-+++ autofs-5.0.2/modules/lookup_ldap.c 2007-09-24 14:44:18.000000000 +0800
-@@ -468,17 +468,17 @@ int parse_ldap_config(struct lookup_cont
- ctxt->client_princ = client_princ;
-
- debug(LOGOPT_NONE,
-- "ldap authentication configured with the following options:\n");
-+ "ldap authentication configured with the following options:");
- debug(LOGOPT_NONE,
- "use_tls: %u, "
- "tls_required: %u, "
- "auth_required: %u, "
-- "sasl_mech: %s\n",
-+ "sasl_mech: %s",
- use_tls, tls_required, auth_required, authtype);
- debug(LOGOPT_NONE,
- "user: %s, "
- "secret: %s, "
-- "client principal: %s\n",
-+ "client principal: %s",
- user, secret ? "specified" : "unspecified",
- client_princ);
-
-diff -up autofs-5.0.2/modules/cyrus-sasl.c.foreground-logging autofs-5.0.2/modules/cyrus-sasl.c
---- autofs-5.0.2/modules/cyrus-sasl.c.foreground-logging 2007-06-18 15:18:08.000000000 +0800
-+++ autofs-5.0.2/modules/cyrus-sasl.c 2007-09-24 14:44:18.000000000 +0800
-@@ -197,7 +197,7 @@ get_server_SASL_mechanisms(LDAP *ld)
- if (mechanisms == NULL) {
- /* Well, that was a waste of time. */
- msg("No SASL authentication mechanisms are supported"
-- " by the LDAP server.\n");
-+ " by the LDAP server.");
- return NULL;
- }
-
-diff -up autofs-5.0.2/daemon/automount.c.foreground-logging autofs-5.0.2/daemon/automount.c
---- autofs-5.0.2/daemon/automount.c.foreground-logging 2007-09-24 14:42:28.000000000 +0800
-+++ autofs-5.0.2/daemon/automount.c 2007-09-24 14:44:18.000000000 +0800
-@@ -58,14 +58,13 @@ unsigned int random_selection; /* use ra
+diff --git a/daemon/automount.c b/daemon/automount.c
+index 58f1901..51f6a8b 100644
+--- a/daemon/automount.c
++++ b/daemon/automount.c
+@@ -58,14 +58,13 @@ unsigned int global_random_selection; /* use random policy when selecting
static int start_pipefd[2];
static int st_stat = 0;
static int *pst_stat = &st_stat;
@@ -63,7 +28,7 @@
#define MAX_OPEN_FILES 10240
static int umount_all(struct autofs_point *ap, int force);
-@@ -792,7 +788,6 @@ static void become_daemon(unsigned foreg
+@@ -792,7 +788,6 @@ static void become_daemon(unsigned foreground)
{
FILE *pidfp;
char buf[MAX_ERR_BUF];
@@ -71,7 +36,7 @@
pid_t pid;
/* Don't BUSY any directories unnecessarily */
-@@ -809,7 +804,9 @@ static void become_daemon(unsigned foreg
+@@ -809,7 +804,9 @@ static void become_daemon(unsigned foreground)
}
/* Detach from foreground process */
@@ -82,7 +47,7 @@
pid = fork();
if (pid > 0) {
int r;
-@@ -834,13 +831,8 @@ static void become_daemon(unsigned foreg
+@@ -834,13 +831,8 @@ static void become_daemon(unsigned foreground)
fprintf(stderr, "setsid: %s", estr);
exit(1);
}
@@ -97,7 +62,7 @@
/* Write pid file if requested */
if (pid_file) {
-@@ -929,7 +921,7 @@ static pthread_t do_signals(struct maste
+@@ -929,7 +921,7 @@ static pthread_t do_signals(struct master *master, int sig)
if (status)
fatal(status);
@@ -106,7 +71,7 @@
if (status) {
error(master->default_logging,
"mount state notify thread create failed");
-@@ -1043,7 +1035,6 @@ static int do_hup_signal(struct master *
+@@ -1045,7 +1037,6 @@ static int do_hup_signal(struct master *master, time_t age)
/* Deal with all the signal-driven events in the state machine */
static void *statemachine(void *arg)
{
@@ -114,7 +79,7 @@
sigset_t signalset;
int sig;
-@@ -1056,15 +1047,12 @@ static void *statemachine(void *arg)
+@@ -1058,15 +1049,12 @@ static void *statemachine(void *arg)
switch (sig) {
case SIGTERM:
@@ -134,7 +99,7 @@
break;
case SIGHUP:
-@@ -1179,6 +1167,10 @@ static void handle_mounts_cleanup(void *
+@@ -1181,6 +1169,10 @@ static void handle_mounts_cleanup(void *arg)
msg("shut down path %s", path);
@@ -145,7 +110,7 @@
return;
}
-@@ -1357,7 +1349,7 @@ static void usage(void)
+@@ -1375,7 +1367,7 @@ static void usage(void)
" -v --verbose be verbose\n"
" -d --debug log debuging info\n"
" -D --define define global macro variable\n"
@@ -154,7 +119,7 @@
" -r --random-multimount-selection\n"
" use ramdom replicated server selection\n"
" -O --global-options\n"
-@@ -1632,14 +1624,6 @@ int main(int argc, char *argv[])
+@@ -1650,14 +1642,6 @@ int main(int argc, char *argv[])
}
#endif
@@ -169,7 +134,7 @@
msg("Starting automounter version %s, master map %s",
version, master_list->name);
msg("using kernel protocol version %d.%02d",
-@@ -1684,6 +1668,7 @@ int main(int argc, char *argv[])
+@@ -1702,6 +1686,7 @@ int main(int argc, char *argv[])
res = write(start_pipefd[1], pst_stat, sizeof(pst_stat));
close(start_pipefd[1]);
@@ -177,20 +142,10 @@
statemachine(NULL);
master_kill(master_list);
-diff -up autofs-5.0.2/lib/master.c.foreground-logging autofs-5.0.2/lib/master.c
---- autofs-5.0.2/lib/master.c.foreground-logging 2007-09-24 14:42:28.000000000 +0800
-+++ autofs-5.0.2/lib/master.c 2007-09-24 14:44:18.000000000 +0800
-@@ -954,6 +954,7 @@ void master_notify_state_change(struct m
-
- switch (sig) {
- case SIGTERM:
-+ case SIGINT:
- if (ap->state != ST_SHUTDOWN_PENDING &&
- ap->state != ST_SHUTDOWN_FORCE) {
- next = ST_SHUTDOWN_PENDING;
-diff -up autofs-5.0.2/lib/log.c.foreground-logging autofs-5.0.2/lib/log.c
---- autofs-5.0.2/lib/log.c.foreground-logging 2007-06-18 15:18:08.000000000 +0800
-+++ autofs-5.0.2/lib/log.c 2007-09-24 14:44:18.000000000 +0800
+diff --git a/lib/log.c b/lib/log.c
+index e639e60..b747e12 100644
+--- a/lib/log.c
++++ b/lib/log.c
@@ -27,9 +27,6 @@
#include "automount.h"
@@ -201,7 +156,7 @@
/*
struct syslog_data syslog_context = AUTOFS_SYSLOG_CONTEXT;
struct syslog_data *slc = &syslog_context;
-@@ -134,30 +131,40 @@ static void syslog_debug(unsigned int lo
+@@ -134,30 +131,40 @@ static void syslog_debug(unsigned int logopt, const char *msg, ...)
va_end(ap);
}
@@ -256,10 +211,23 @@
void log_to_syslog(void)
{
char buf[MAX_ERR_BUF];
-diff -up autofs-5.0.2/man/automount.8.foreground-logging autofs-5.0.2/man/automount.8
---- autofs-5.0.2/man/automount.8.foreground-logging 2007-09-24 14:42:28.000000000 +0800
-+++ autofs-5.0.2/man/automount.8 2007-09-24 14:44:18.000000000 +0800
-@@ -47,6 +47,9 @@ Define a global macro substitution varia
+diff --git a/lib/master.c b/lib/master.c
+index 637ce04..abc3bc2 100644
+--- a/lib/master.c
++++ b/lib/master.c
+@@ -954,6 +954,7 @@ void master_notify_state_change(struct master *master, int sig)
+
+ switch (sig) {
+ case SIGTERM:
++ case SIGINT:
+ if (ap->state != ST_SHUTDOWN_PENDING &&
+ ap->state != ST_SHUTDOWN_FORCE) {
+ next = ST_SHUTDOWN_PENDING;
+diff --git a/man/automount.8 b/man/automount.8
+index da67a5c..e203a3e 100644
+--- a/man/automount.8
++++ b/man/automount.8
+@@ -47,6 +47,9 @@ Define a global macro substitution variable. Global definitions
are over-ridden macro definitions of the same name specified in
mount entries.
.TP
@@ -269,3 +237,41 @@
.I "\-r, \-\-random-multimount-selection"
Enables the use of ramdom selection when choosing a host from a
list of replicated servers.
+diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
+index 9aac792..68e5dd7 100644
+--- a/modules/cyrus-sasl.c
++++ b/modules/cyrus-sasl.c
+@@ -197,7 +197,7 @@ get_server_SASL_mechanisms(LDAP *ld)
+ if (mechanisms == NULL) {
+ /* Well, that was a waste of time. */
+ msg("No SASL authentication mechanisms are supported"
+- " by the LDAP server.\n");
++ " by the LDAP server.");
+ return NULL;
+ }
+
+diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
+index 4068561..c0f228b 100644
+--- a/modules/lookup_ldap.c
++++ b/modules/lookup_ldap.c
+@@ -857,17 +857,17 @@ int parse_ldap_config(struct lookup_context *ctxt)
+ ctxt->client_princ = client_princ;
+
+ debug(LOGOPT_NONE,
+- "ldap authentication configured with the following options:\n");
++ "ldap authentication configured with the following options:");
+ debug(LOGOPT_NONE,
+ "use_tls: %u, "
+ "tls_required: %u, "
+ "auth_required: %u, "
+- "sasl_mech: %s\n",
++ "sasl_mech: %s",
+ use_tls, tls_required, auth_required, authtype);
+ debug(LOGOPT_NONE,
+ "user: %s, "
+ "secret: %s, "
+- "client principal: %s\n",
++ "client principal: %s",
+ user, secret ? "specified" : "unspecified",
+ client_princ);
+
autofs-5.0.2-ldap-search-basedn-list.patch:
Index: autofs-5.0.2-ldap-search-basedn-list.patch
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-8/autofs-5.0.2-ldap-search-basedn-list.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- autofs-5.0.2-ldap-search-basedn-list.patch 20 Nov 2007 07:54:34 -0000 1.1
+++ autofs-5.0.2-ldap-search-basedn-list.patch 14 Feb 2008 07:28:32 -0000 1.2
@@ -1,24 +1,30 @@
-diff -up autofs-5.0.2/redhat/autofs.sysconfig.in.ldap-search-basedn-list autofs-5.0.2/redhat/autofs.sysconfig.in
---- autofs-5.0.2/redhat/autofs.sysconfig.in.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/redhat/autofs.sysconfig.in 2007-11-20 14:08:26.000000000 +0900
-@@ -21,6 +21,14 @@ BROWSE_MODE="no"
- #
- #LOGGING="none"
- #
-+# Define base dn for map dn lookup.
-+#
-+# SEARCH_BASE - base dn to use for searching for map search dn.
-+# Multiple entries can be given and they are checked
-+# in the order they occur here.
-+#
-+#SEARCH_BASE=""
-+#
- # Define the LDAP schema to used for lookups
- #
- # If no schema is set autofs will check each of the schemas
-diff -up autofs-5.0.2/include/lookup_ldap.h.ldap-search-basedn-list autofs-5.0.2/include/lookup_ldap.h
---- autofs-5.0.2/include/lookup_ldap.h.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/include/lookup_ldap.h 2007-11-20 14:08:26.000000000 +0900
+diff --git a/include/defaults.h b/include/defaults.h
+index 9aec11a..0984b1c 100644
+--- a/include/defaults.h
++++ b/include/defaults.h
+@@ -37,6 +37,9 @@
+ #define DEFAULT_APPEND_OPTIONS 1
+ #define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf"
+
++struct ldap_schema;
++struct ldap_searchdn;
++
+ unsigned int defaults_read_config(void);
+ const char *defaults_get_master_map(void);
+ unsigned int defaults_get_timeout(void);
+@@ -45,6 +48,8 @@ unsigned int defaults_get_logging(void);
+ const char *defaults_get_ldap_server(void);
+ struct ldap_schema *defaults_get_default_schema(void);
+ struct ldap_schema *defaults_get_schema(void);
++struct ldap_searchdn *defaults_get_searchdns(void);
++void defaults_free_searchdns(struct ldap_searchdn *);
+ unsigned int defaults_get_append_options(void);
+ const char *defaults_get_auth_conf_file(void);
+
+diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
+index 1378b9e..1a924be 100644
+--- a/include/lookup_ldap.h
++++ b/include/lookup_ldap.h
@@ -18,6 +18,11 @@ struct ldap_schema {
char *value_attr;
};
@@ -42,32 +48,257 @@
/* TLS and SASL authentication information */
char *auth_conf;
unsigned use_tls;
-diff -up autofs-5.0.2/include/defaults.h.ldap-search-basedn-list autofs-5.0.2/include/defaults.h
---- autofs-5.0.2/include/defaults.h.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/include/defaults.h 2007-11-20 14:08:26.000000000 +0900
-@@ -37,6 +37,9 @@
- #define DEFAULT_APPEND_OPTIONS 1
- #define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf"
+diff --git a/lib/defaults.c b/lib/defaults.c
+index b146f13..c2f86c0 100644
+--- a/lib/defaults.c
++++ b/lib/defaults.c
+@@ -32,6 +32,8 @@
-+struct ldap_schema;
-+struct ldap_searchdn;
+ #define ENV_LDAP_SERVER "LDAP_SERVER"
+
++#define SEARCH_BASE "SEARCH_BASE"
+
- unsigned int defaults_read_config(void);
- const char *defaults_get_master_map(void);
- unsigned int defaults_get_timeout(void);
-@@ -45,6 +48,8 @@ unsigned int defaults_get_logging(void);
- const char *defaults_get_ldap_server(void);
- struct ldap_schema *defaults_get_default_schema(void);
- struct ldap_schema *defaults_get_schema(void);
-+struct ldap_searchdn *defaults_get_searchdns(void);
-+void defaults_free_searchdns(struct ldap_searchdn *);
- unsigned int defaults_get_append_options(void);
- const char *defaults_get_auth_conf_file(void);
+ #define ENV_NAME_MAP_OBJ_CLASS "MAP_OBJECT_CLASS"
+ #define ENV_NAME_ENTRY_OBJ_CLASS "ENTRY_OBJECT_CLASS"
+ #define ENV_NAME_MAP_ATTR "MAP_ATTRIBUTE"
+@@ -130,6 +132,52 @@ static int check_set_config_value(const char *res, const char *name, const char
+ return 0;
+ }
+
++static int parse_line(char *line, char **res, char **value)
++{
++ char *key, *val, *trailer;
++ int len;
++
++ key = line;
++
++ if (*key == '#' || !isalpha(*key))
++ return 0;
++
++ while (*key && *key == ' ')
++ key++;
++
++ if (!key)
++ return 0;
++
++ if (!(val = strchr(key, '=')))
++ return 0;
++
++ *val++ = '\0';
++
++ while (*val && (*val == '"' || isblank(*val)))
++ val++;
++
++ len = strlen(val);
++
++ if (val[len - 1] == '\n') {
++ val[len - 1] = '\0';
++ len--;
++ }
++
++ trailer = strchr(val, '#');
++ if (!trailer)
++ trailer = val + len - 1;
++ else
++ trailer--;
++
++ while (*trailer && (*trailer == '"' || isblank(*trailer)))
++ *(trailer--) = '\0';;
++
++ *res = key;
++ *value = val;
++
++ return 1;
++}
++
+ /*
+ * Read config env variables and check they have been set.
+ *
+@@ -141,61 +189,30 @@ unsigned int defaults_read_config(void)
+ {
+ FILE *f;
+ char buf[MAX_LINE_LEN];
+- char *res, *value;
++ char *res;
+
+ f = fopen(DEFAULTS_CONFIG_FILE, "r");
+ if (!f)
+ return 0;
+
+ while ((res = fgets(buf, MAX_LINE_LEN, f))) {
+- char *trailer;
+- int len;
+-
+- if (*res == '#' || !isalpha(*res))
+- continue;
+-
+- while (*res && *res == ' ')
+- res++;
+-
+- if (!res)
+- continue;
++ char *key, *value;
+
+- if (!(value = strchr(res, '=')))
++ if (!parse_line(res, &key, &value))
+ continue;
+
+- *value++ = '\0';
+-
+- while (*value && (*value == '"' || isblank(*value)))
+- value++;
+-
+- len = strlen(value);
+-
+- if (value[len - 1] == '\n') {
+- value[len - 1] = '\0';
+- len--;
+- }
+-
+- trailer = strchr(value, '#');
+- if (!trailer)
+- trailer = value + len - 1;
+- else
+- trailer--;
+-
+- while (*trailer && (*trailer == '"' || isblank(*trailer)))
+- *(trailer--) = '\0';;
+-
+- if (check_set_config_value(res, ENV_NAME_MASTER_MAP, value) ||
+- check_set_config_value(res, ENV_NAME_TIMEOUT, value) ||
+- check_set_config_value(res, ENV_NAME_BROWSE_MODE, value) ||
+- check_set_config_value(res, ENV_NAME_LOGGING, value) ||
+- check_set_config_value(res, ENV_LDAP_SERVER, value) ||
+- check_set_config_value(res, ENV_NAME_MAP_OBJ_CLASS, value) ||
+- check_set_config_value(res, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
+- check_set_config_value(res, ENV_NAME_MAP_ATTR, value) ||
+- check_set_config_value(res, ENV_NAME_ENTRY_ATTR, value) ||
+- check_set_config_value(res, ENV_NAME_VALUE_ATTR, value) ||
+- check_set_config_value(res, ENV_APPEND_OPTIONS, value) ||
+- check_set_config_value(res, ENV_AUTH_CONF_FILE, value))
++ if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value) ||
++ check_set_config_value(key, ENV_NAME_TIMEOUT, value) ||
++ check_set_config_value(key, ENV_NAME_BROWSE_MODE, value) ||
++ check_set_config_value(key, ENV_NAME_LOGGING, value) ||
++ check_set_config_value(key, ENV_LDAP_SERVER, value) ||
++ check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value) ||
++ check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
++ check_set_config_value(key, ENV_NAME_MAP_ATTR, value) ||
++ check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value) ||
++ check_set_config_value(key, ENV_NAME_VALUE_ATTR, value) ||
++ check_set_config_value(key, ENV_APPEND_OPTIONS, value) ||
++ check_set_config_value(key, ENV_AUTH_CONF_FILE, value))
+ ;
+ }
+
+@@ -336,6 +353,86 @@ struct ldap_schema *defaults_get_default_schema(void)
+ return schema;
+ }
-diff -up autofs-5.0.2/modules/lookup_ldap.c.ldap-search-basedn-list autofs-5.0.2/modules/lookup_ldap.c
---- autofs-5.0.2/modules/lookup_ldap.c.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/modules/lookup_ldap.c 2007-11-20 14:09:58.000000000 +0900
-@@ -171,10 +171,207 @@ LDAP *init_ldap_connection(struct lookup
++static struct ldap_searchdn *alloc_searchdn(const char *value)
++{
++ struct ldap_searchdn *sdn;
++ char *val;
++
++ sdn = malloc(sizeof(struct ldap_searchdn));
++ if (!sdn)
++ return NULL;
++
++ val = strdup(value);
++ if (!val) {
++ free(sdn);
++ return NULL;
++ }
++
++ sdn->basedn = val;
++ sdn->next = NULL;
++
++ return sdn;
++}
++
++void defaults_free_searchdns(struct ldap_searchdn *sdn)
++{
++ struct ldap_searchdn *this = sdn;
++ struct ldap_searchdn *next;
++
++ next = this;
++ while (this) {
++ next = this->next;
++ free(this->basedn);
++ free(this);
++ this = next;
++ }
++
++ return;
++}
++
++struct ldap_searchdn *defaults_get_searchdns(void)
++{
++ FILE *f;
++ char buf[MAX_LINE_LEN];
++ char *res;
++ struct ldap_searchdn *sdn, *last;
++
++ f = fopen(DEFAULTS_CONFIG_FILE, "r");
++ if (!f)
++ return NULL;
++
++ sdn = last = NULL;
++
++ while ((res = fgets(buf, MAX_LINE_LEN, f))) {
++ char *key, *value;
++
++ if (!parse_line(res, &key, &value))
++ continue;
++
++ if (!strcasecmp(key, SEARCH_BASE)) {
++ struct ldap_searchdn *new = alloc_searchdn(value);
++
++ if (!new) {
++ defaults_free_searchdns(sdn);
++ return NULL;
++ }
++
++ if (!last)
++ last = new;
++ else {
++ last->next = new;
++ last = new;
++ }
++
++ if (!sdn)
++ sdn = new;
++ }
++ }
++
++ fclose(f);
++ return sdn;
++}
++
+ struct ldap_schema *defaults_get_schema(void)
+ {
+ struct ldap_schema *schema;
+diff --git a/man/auto.master.5.in b/man/auto.master.5.in
+index ab5ab1e..0cb2f07 100644
+--- a/man/auto.master.5.in
++++ b/man/auto.master.5.in
+@@ -230,6 +230,11 @@ values must be set, any partial schema specification will be ignored.
+ .P
+ The configuration settings available are:
+ .TP
++.B SEARCH_BASE
++The base dn to use when searching for amap base dn. This entry may be
++given multiple times and each will be checked for a map base dn in
++the order they occur in the configuration.
++.TP
+ .B MAP_OBJECT_CLASS
+ The map object class. In the \fBnisMap\fP schema this corresponds to the class
+ \fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class
+diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
+index 9c18ca1..da52e71 100644
+--- a/modules/lookup_ldap.c
++++ b/modules/lookup_ldap.c
+@@ -171,10 +171,207 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
return ldap;
}
@@ -276,7 +507,7 @@
ldap = init_ldap_connection(ctxt);
if (!ldap)
-@@ -204,6 +401,61 @@ static LDAP *do_connect(struct lookup_co
+@@ -204,6 +401,61 @@ static LDAP *do_connect(struct lookup_context *ctxt)
return NULL;
}
@@ -338,7 +569,7 @@
return ldap;
}
-@@ -769,177 +1021,17 @@ static void free_context(struct lookup_c
+@@ -769,175 +1021,17 @@ static void free_context(struct lookup_context *ctxt)
ldap_memfree(ctxt->qdn);
if (ctxt->server)
free(ctxt->server);
@@ -359,11 +590,10 @@
- char *query, *dn;
- LDAPMessage *result, *e;
- char *attrs[2];
-- struct berval **value;
- int scope;
- int rv, l;
-
-- attrs[0] = (char *) key;
+- attrs[0] = LDAP_NO_ATTRS;
- attrs[1] = NULL;
-
- if (!ctxt->mapname && !ctxt->base) {
@@ -415,8 +645,7 @@
- }
-
- e = ldap_first_entry(ldap, result);
-- if (e && (value = ldap_get_values_len(ldap, e, key))) {
-- ldap_value_free_len(value);
+- if (e) {
- dn = ldap_get_dn(ldap, e);
- debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
- ldap_msgfree(result);
@@ -520,7 +749,7 @@
/*
* This initializes a context (persistent non-global data) for queries to
* this module. Return zero if we succeed.
-@@ -996,31 +1088,6 @@ int lookup_init(const char *mapfmt, int
+@@ -994,31 +1088,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
free_context(ctxt);
return 1;
}
@@ -552,9 +781,29 @@
unbind_ldap_connection(ldap, ctxt);
/* Open the parser, if we can. */
-diff -up autofs-5.0.2/samples/autofs.conf.default.in.ldap-search-basedn-list autofs-5.0.2/samples/autofs.conf.default.in
---- autofs-5.0.2/samples/autofs.conf.default.in.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/samples/autofs.conf.default.in 2007-11-20 14:08:26.000000000 +0900
+diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
+index 85f4e34..2b1e20a 100644
+--- a/redhat/autofs.sysconfig.in
++++ b/redhat/autofs.sysconfig.in
+@@ -21,6 +21,14 @@ BROWSE_MODE="no"
+ #
+ #LOGGING="none"
+ #
++# Define base dn for map dn lookup.
++#
++# SEARCH_BASE - base dn to use for searching for map search dn.
++# Multiple entries can be given and they are checked
++# in the order they occur here.
++#
++#SEARCH_BASE=""
++#
+ # Define the LDAP schema to used for lookups
+ #
+ # If no schema is set autofs will check each of the schemas
+diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
+index 85f4e34..2b1e20a 100644
+--- a/samples/autofs.conf.default.in
++++ b/samples/autofs.conf.default.in
@@ -21,6 +21,14 @@ BROWSE_MODE="no"
#
#LOGGING="none"
@@ -570,247 +819,3 @@
# Define the LDAP schema to used for lookups
#
# If no schema is set autofs will check each of the schemas
-diff -up autofs-5.0.2/lib/defaults.c.ldap-search-basedn-list autofs-5.0.2/lib/defaults.c
---- autofs-5.0.2/lib/defaults.c.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/lib/defaults.c 2007-11-20 14:08:26.000000000 +0900
-@@ -32,6 +32,8 @@
-
- #define ENV_LDAP_SERVER "LDAP_SERVER"
-
-+#define SEARCH_BASE "SEARCH_BASE"
-+
- #define ENV_NAME_MAP_OBJ_CLASS "MAP_OBJECT_CLASS"
- #define ENV_NAME_ENTRY_OBJ_CLASS "ENTRY_OBJECT_CLASS"
- #define ENV_NAME_MAP_ATTR "MAP_ATTRIBUTE"
-@@ -130,6 +132,52 @@ static int check_set_config_value(const
- return 0;
- }
-
-+static int parse_line(char *line, char **res, char **value)
-+{
-+ char *key, *val, *trailer;
-+ int len;
-+
-+ key = line;
-+
-+ if (*key == '#' || !isalpha(*key))
-+ return 0;
-+
-+ while (*key && *key == ' ')
-+ key++;
-+
-+ if (!key)
-+ return 0;
-+
-+ if (!(val = strchr(key, '=')))
-+ return 0;
-+
-+ *val++ = '\0';
-+
-+ while (*val && (*val == '"' || isblank(*val)))
-+ val++;
-+
-+ len = strlen(val);
-+
-+ if (val[len - 1] == '\n') {
-+ val[len - 1] = '\0';
-+ len--;
-+ }
-+
-+ trailer = strchr(val, '#');
-+ if (!trailer)
-+ trailer = val + len - 1;
-+ else
-+ trailer--;
-+
-+ while (*trailer && (*trailer == '"' || isblank(*trailer)))
-+ *(trailer--) = '\0';;
-+
-+ *res = key;
-+ *value = val;
-+
-+ return 1;
-+}
-+
- /*
- * Read config env variables and check they have been set.
- *
-@@ -141,61 +189,30 @@ unsigned int defaults_read_config(void)
- {
- FILE *f;
- char buf[MAX_LINE_LEN];
-- char *res, *value;
-+ char *res;
-
- f = fopen(DEFAULTS_CONFIG_FILE, "r");
- if (!f)
- return 0;
-
- while ((res = fgets(buf, MAX_LINE_LEN, f))) {
-- char *trailer;
-- int len;
--
-- if (*res == '#' || !isalpha(*res))
-- continue;
--
-- while (*res && *res == ' ')
-- res++;
--
-- if (!res)
-- continue;
-+ char *key, *value;
-
-- if (!(value = strchr(res, '=')))
-+ if (!parse_line(res, &key, &value))
- continue;
-
-- *value++ = '\0';
--
-- while (*value && (*value == '"' || isblank(*value)))
-- value++;
--
-- len = strlen(value);
--
-- if (value[len - 1] == '\n') {
-- value[len - 1] = '\0';
-- len--;
-- }
--
-- trailer = strchr(value, '#');
-- if (!trailer)
-- trailer = value + len - 1;
-- else
-- trailer--;
--
-- while (*trailer && (*trailer == '"' || isblank(*trailer)))
-- *(trailer--) = '\0';;
--
-- if (check_set_config_value(res, ENV_NAME_MASTER_MAP, value) ||
-- check_set_config_value(res, ENV_NAME_TIMEOUT, value) ||
-- check_set_config_value(res, ENV_NAME_BROWSE_MODE, value) ||
-- check_set_config_value(res, ENV_NAME_LOGGING, value) ||
-- check_set_config_value(res, ENV_LDAP_SERVER, value) ||
-- check_set_config_value(res, ENV_NAME_MAP_OBJ_CLASS, value) ||
-- check_set_config_value(res, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
-- check_set_config_value(res, ENV_NAME_MAP_ATTR, value) ||
-- check_set_config_value(res, ENV_NAME_ENTRY_ATTR, value) ||
-- check_set_config_value(res, ENV_NAME_VALUE_ATTR, value) ||
-- check_set_config_value(res, ENV_APPEND_OPTIONS, value) ||
-- check_set_config_value(res, ENV_AUTH_CONF_FILE, value))
-+ if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value) ||
-+ check_set_config_value(key, ENV_NAME_TIMEOUT, value) ||
-+ check_set_config_value(key, ENV_NAME_BROWSE_MODE, value) ||
-+ check_set_config_value(key, ENV_NAME_LOGGING, value) ||
-+ check_set_config_value(key, ENV_LDAP_SERVER, value) ||
-+ check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value) ||
-+ check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
-+ check_set_config_value(key, ENV_NAME_MAP_ATTR, value) ||
-+ check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value) ||
-+ check_set_config_value(key, ENV_NAME_VALUE_ATTR, value) ||
-+ check_set_config_value(key, ENV_APPEND_OPTIONS, value) ||
-+ check_set_config_value(key, ENV_AUTH_CONF_FILE, value))
- ;
- }
-
-@@ -336,6 +353,86 @@ struct ldap_schema *defaults_get_default
- return schema;
- }
-
-+static struct ldap_searchdn *alloc_searchdn(const char *value)
-+{
-+ struct ldap_searchdn *sdn;
-+ char *val;
-+
-+ sdn = malloc(sizeof(struct ldap_searchdn));
-+ if (!sdn)
-+ return NULL;
-+
-+ val = strdup(value);
-+ if (!val) {
-+ free(sdn);
-+ return NULL;
-+ }
-+
-+ sdn->basedn = val;
-+ sdn->next = NULL;
-+
-+ return sdn;
-+}
-+
-+void defaults_free_searchdns(struct ldap_searchdn *sdn)
-+{
-+ struct ldap_searchdn *this = sdn;
-+ struct ldap_searchdn *next;
-+
-+ next = this;
-+ while (this) {
-+ next = this->next;
-+ free(this->basedn);
-+ free(this);
-+ this = next;
-+ }
-+
-+ return;
-+}
-+
-+struct ldap_searchdn *defaults_get_searchdns(void)
-+{
-+ FILE *f;
-+ char buf[MAX_LINE_LEN];
-+ char *res;
-+ struct ldap_searchdn *sdn, *last;
-+
-+ f = fopen(DEFAULTS_CONFIG_FILE, "r");
-+ if (!f)
-+ return NULL;
-+
-+ sdn = last = NULL;
-+
-+ while ((res = fgets(buf, MAX_LINE_LEN, f))) {
-+ char *key, *value;
-+
-+ if (!parse_line(res, &key, &value))
-+ continue;
-+
-+ if (!strcasecmp(key, SEARCH_BASE)) {
-+ struct ldap_searchdn *new = alloc_searchdn(value);
-+
-+ if (!new) {
-+ defaults_free_searchdns(sdn);
-+ return NULL;
-+ }
-+
-+ if (!last)
-+ last = new;
-+ else {
-+ last->next = new;
-+ last = new;
-+ }
-+
-+ if (!sdn)
-+ sdn = new;
-+ }
-+ }
-+
-+ fclose(f);
-+ return sdn;
-+}
-+
- struct ldap_schema *defaults_get_schema(void)
- {
- struct ldap_schema *schema;
-diff -up autofs-5.0.2/man/auto.master.5.in.ldap-search-basedn-list autofs-5.0.2/man/auto.master.5.in
---- autofs-5.0.2/man/auto.master.5.in.ldap-search-basedn-list 2007-11-20 14:07:52.000000000 +0900
-+++ autofs-5.0.2/man/auto.master.5.in 2007-11-20 14:08:26.000000000 +0900
-@@ -224,6 +224,11 @@ values must be set, any partial schema s
- .P
- The configuration settings available are:
- .TP
-+.B SEARCH_BASE
-+The base dn to use when searching for amap base dn. This entry may be
-+given multiple times and each will be checked for a map base dn in
-+the order they occur in the configuration.
-+.TP
- .B MAP_OBJECT_CLASS
- The map object class. In the \fBnisMap\fP schema this corresponds to the class
- \fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class
autofs-5.0.2-random-selection-fix.patch:
Index: autofs-5.0.2-random-selection-fix.patch
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-8/autofs-5.0.2-random-selection-fix.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- autofs-5.0.2-random-selection-fix.patch 20 Nov 2007 07:54:34 -0000 1.1
+++ autofs-5.0.2-random-selection-fix.patch 14 Feb 2008 07:28:32 -0000 1.2
@@ -1,18 +1,42 @@
-diff -up autofs-5.0.2/include/replicated.h.random-selection-fix autofs-5.0.2/include/replicated.h
---- autofs-5.0.2/include/replicated.h.random-selection-fix 2007-06-18 15:18:08.000000000 +0800
-+++ autofs-5.0.2/include/replicated.h 2007-11-20 14:55:28.000000000 +0900
-@@ -63,7 +63,7 @@ struct host {
- void seed_random(void);
- void free_host_list(struct host **);
- int parse_location(struct host **, const char *);
--int prune_host_list(struct host **, unsigned int, const char *);
-+int prune_host_list(struct host **, unsigned int, const char *, unsigned int);
- void dump_host_list(struct host *);
+diff --git a/daemon/automount.c b/daemon/automount.c
+index 7b79f02..4b6584a 100644
+--- a/daemon/automount.c
++++ b/daemon/automount.c
+@@ -49,9 +49,9 @@ const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */
- #endif
-diff -up autofs-5.0.2/include/automount.h.random-selection-fix autofs-5.0.2/include/automount.h
---- autofs-5.0.2/include/automount.h.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/include/automount.h 2007-11-20 14:55:28.000000000 +0900
+ const char *global_options; /* Global option, from command line */
+
+-static char *pid_file = NULL; /* File in which to keep pid */
+-unsigned int random_selection; /* use random policy when selecting
+- * which multi-mount host to mount */
++static char *pid_file = NULL; /* File in which to keep pid */
++unsigned int global_random_selection; /* use random policy when selecting
++ * which multi-mount host to mount */
+ static int start_pipefd[2];
+ static int st_stat = 0;
+ static int *pst_stat = &st_stat;
+@@ -1490,7 +1490,7 @@ int main(int argc, char *argv[])
+ timeout = defaults_get_timeout();
+ ghost = defaults_get_browse_mode();
+ logging = defaults_get_logging();
+- random_selection = 0;
++ global_random_selection = 0;
+ global_options = NULL;
+ have_global_options = 0;
+ foreground = 0;
+@@ -1531,7 +1531,7 @@ int main(int argc, char *argv[])
+ exit(0);
+
+ case 'r':
+- random_selection = 1;
++ global_random_selection = 1;
+ break;
+
+ case 'O':
+diff --git a/include/automount.h b/include/automount.h
+index d9e4ecd..d55ba5c 100644
+--- a/include/automount.h
++++ b/include/automount.h
@@ -448,6 +448,8 @@ struct autofs_point {
enum states state; /* Current state */
int state_pipe[2]; /* State change router pipe */
@@ -22,10 +46,107 @@
struct autofs_point *parent; /* Owner of mounts list for submount */
pthread_mutex_t mounts_mutex; /* Protect mount lists */
pthread_cond_t mounts_cond; /* Submounts condition variable */
-diff -up autofs-5.0.2/modules/mount_nfs.c.random-selection-fix autofs-5.0.2/modules/mount_nfs.c
---- autofs-5.0.2/modules/mount_nfs.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/modules/mount_nfs.c 2007-11-20 14:55:28.000000000 +0900
-@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap,
+diff --git a/include/replicated.h b/include/replicated.h
+index c77cda6..3afe9f7 100644
+--- a/include/replicated.h
++++ b/include/replicated.h
+@@ -63,7 +63,7 @@ struct host {
+ void seed_random(void);
+ void free_host_list(struct host **);
+ int parse_location(struct host **, const char *);
+-int prune_host_list(struct host **, unsigned int, const char *);
++int prune_host_list(struct host **, unsigned int, const char *, unsigned int);
+ void dump_host_list(struct host *);
+
+ #endif
+diff --git a/lib/master_parse.y b/lib/master_parse.y
+index ab2895d..70b48be 100644
+--- a/lib/master_parse.y
++++ b/lib/master_parse.y
+@@ -56,6 +56,8 @@ static char *type;
+ static char *format;
+ static long timeout;
+ static unsigned ghost;
++extern unsigned global_random_selection;
++static unsigned random_selection;
+ static char **tmp_argv;
+ static int tmp_argc;
+ static char **local_argv;
+@@ -93,7 +95,7 @@ static int master_fprintf(FILE *, char *, ...);
+
+ %token COMMENT
+ %token MAP
+-%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG
++%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG OPT_RANDOM
+ %token COLON COMMA NL DDASH
+ %type <strtype> map
+ %type <strtype> options
+@@ -174,6 +176,7 @@ line:
+ | PATH COLON { master_notify($1); YYABORT; }
+ | PATH OPTION { master_notify($2); YYABORT; }
+ | PATH NILL { master_notify($2); YYABORT; }
++ | PATH OPT_RANDOM { master_notify($1); YYABORT; }
+ | PATH OPT_DEBUG { master_notify($1); YYABORT; }
+ | PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
+ | PATH OPT_GHOST { master_notify($1); YYABORT; }
+@@ -543,6 +546,7 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
+ | OPT_GHOST { ghost = 1; }
+ | OPT_VERBOSE { verbose = 1; }
+ | OPT_DEBUG { debug = 1; }
++ | OPT_RANDOM { random_selection = 1; }
+ ;
+
+ mount_option: OPTION
+@@ -600,6 +604,7 @@ static void local_init_vars(void)
+ debug = 0;
+ timeout = -1;
+ ghost = defaults_get_browse_mode();
++ random_selection = global_random_selection;
+ tmp_argv = NULL;
+ tmp_argc = 0;
+ local_argv = NULL;
+@@ -790,6 +795,7 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
+ }
+ set_mnt_logging(ap);
+ }
++ entry->ap->random_selection = random_selection;
+
+ /*
+ source = master_find_map_source(entry, type, format,
+diff --git a/lib/master_tok.l b/lib/master_tok.l
+index ff69a24..013a15a 100644
+--- a/lib/master_tok.l
++++ b/lib/master_tok.l
+@@ -324,6 +324,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
+ -g|--ghost|-?browse { return(OPT_GHOST); }
+ -v|--verbose { return(OPT_VERBOSE); }
+ -d|--debug { return(OPT_DEBUG); }
++ -r|--random-multimount-selection { return(OPT_RANDOM); }
+
+ {OPTWS}","{OPTWS} { return(COMMA); }
+
+diff --git a/man/auto.master.5.in b/man/auto.master.5.in
+index 249c9a7..ab5ab1e 100644
+--- a/man/auto.master.5.in
++++ b/man/auto.master.5.in
+@@ -146,6 +146,12 @@ to prevent symlinking of local NFS mounts. Nowadays it can be used to
+ prevent bind mounting of local NFS filesystems as well. If you need to
+ prevent bind mounting for only specific entrys in a map then this
+ can be done by adding the "port=" mount option to the given entries.
++.TP
++.I "\-r, \-\-random-multimount-selection"
++Enables the use of ramdom selection when choosing a host from a
++list of replicated servers. This option is applied to this mount
++only, overriding the global setting that may be specified on the
++command line.
+ .SH GENERAL SYSTEM DEFAULTS CONFIGURATION
+ .P
+ The default value of several general settings may be changed in the
+diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
+index e7a9a8a..e4480c5 100644
+--- a/modules/mount_nfs.c
++++ b/modules/mount_nfs.c
+@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
warn(ap->logopt, MODPREFIX "no hosts available");
return 1;
}
@@ -34,9 +155,10 @@
if (!hosts) {
warn(ap->logopt, MODPREFIX "no hosts available");
-diff -up autofs-5.0.2/modules/replicated.c.random-selection-fix autofs-5.0.2/modules/replicated.c
---- autofs-5.0.2/modules/replicated.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/modules/replicated.c 2007-11-20 14:55:28.000000000 +0900
+diff --git a/modules/replicated.c b/modules/replicated.c
+index 0764d4a..e15587c 100644
+--- a/modules/replicated.c
++++ b/modules/replicated.c
@@ -74,8 +74,6 @@
#define max(x, y) (x >= y ? x : y)
#define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z))
@@ -46,7 +168,7 @@
void seed_random(void)
{
int fd;
-@@ -392,7 +390,7 @@ static unsigned short get_port_option(co
+@@ -392,7 +390,7 @@ static unsigned short get_port_option(const char *options)
static unsigned int get_nfs_info(struct host *host,
struct conn_info *pm_info, struct conn_info *rpc_info,
const char *proto, unsigned int version,
@@ -66,7 +188,7 @@
{
struct conn_info pm_info, rpc_info;
time_t timeout = RPC_TIMEOUT;
-@@ -559,7 +559,9 @@ static int get_vers_and_cost(struct host
+@@ -559,7 +559,9 @@ static int get_vers_and_cost(struct host *host, unsigned int version, const char
vers &= version;
if (version & UDP_REQUESTED) {
@@ -77,7 +199,7 @@
if (supported) {
ret = 1;
host->version |= (supported << 8);
-@@ -567,7 +569,9 @@ static int get_vers_and_cost(struct host
+@@ -567,7 +569,9 @@ static int get_vers_and_cost(struct host *host, unsigned int version, const char
}
if (version & TCP_REQUESTED) {
@@ -88,7 +210,7 @@
if (supported) {
ret = 1;
host->version |= supported;
-@@ -577,7 +581,9 @@ static int get_vers_and_cost(struct host
+@@ -577,7 +581,9 @@ static int get_vers_and_cost(struct host *host, unsigned int version, const char
return ret;
}
@@ -110,7 +232,7 @@
{
struct host *this, *last, *first;
struct host *new = NULL;
-@@ -734,7 +742,8 @@ int prune_host_list(struct host **list,
+@@ -734,7 +742,8 @@ int prune_host_list(struct host **list, unsigned int vers, const char *options)
break;
if (this->name) {
@@ -120,7 +242,7 @@
if (!status) {
if (this == first) {
first = next;
-@@ -824,7 +833,9 @@ int prune_host_list(struct host **list,
+@@ -824,7 +833,9 @@ int prune_host_list(struct host **list, unsigned int vers, const char *options)
remove_host(list, this);
add_host(&new, this);
} else {
@@ -131,117 +253,3 @@
if (status) {
this->version = selected_version;
remove_host(list, this);
-diff -up autofs-5.0.2/daemon/automount.c.random-selection-fix autofs-5.0.2/daemon/automount.c
---- autofs-5.0.2/daemon/automount.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/daemon/automount.c 2007-11-20 14:55:28.000000000 +0900
-@@ -52,9 +52,9 @@ const char *confdir = AUTOFS_CONF_DIR; /
-
- const char *global_options; /* Global option, from command line */
-
--static char *pid_file = NULL; /* File in which to keep pid */
--unsigned int random_selection; /* use random policy when selecting
-- * which multi-mount host to mount */
-+static char *pid_file = NULL; /* File in which to keep pid */
-+unsigned int global_random_selection; /* use random policy when selecting
-+ * which multi-mount host to mount */
- static int start_pipefd[2];
- static int st_stat = 0;
- static int *pst_stat = &st_stat;
-@@ -1469,7 +1469,7 @@ int main(int argc, char *argv[])
- timeout = defaults_get_timeout();
- ghost = defaults_get_browse_mode();
- logging = defaults_get_logging();
-- random_selection = 0;
-+ global_random_selection = 0;
- global_options = NULL;
- have_global_options = 0;
- foreground = 0;
-@@ -1510,7 +1510,7 @@ int main(int argc, char *argv[])
- exit(0);
-
- case 'r':
-- random_selection = 1;
-+ global_random_selection = 1;
- break;
-
- case 'O':
-diff -up autofs-5.0.2/lib/master_tok.l.random-selection-fix autofs-5.0.2/lib/master_tok.l
---- autofs-5.0.2/lib/master_tok.l.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/lib/master_tok.l 2007-11-20 14:55:28.000000000 +0900
-@@ -324,6 +324,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--
- -g|--ghost|-?browse { return(OPT_GHOST); }
- -v|--verbose { return(OPT_VERBOSE); }
- -d|--debug { return(OPT_DEBUG); }
-+ -r|--random-multimount-selection { return(OPT_RANDOM); }
-
- {OPTWS}","{OPTWS} { return(COMMA); }
-
-diff -up autofs-5.0.2/lib/master_parse.y.random-selection-fix autofs-5.0.2/lib/master_parse.y
---- autofs-5.0.2/lib/master_parse.y.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/lib/master_parse.y 2007-11-20 14:55:28.000000000 +0900
-@@ -56,6 +56,8 @@ static char *type;
- static char *format;
- static long timeout;
- static unsigned ghost;
-+extern unsigned global_random_selection;
-+static unsigned random_selection;
- static char **tmp_argv;
- static int tmp_argc;
- static char **local_argv;
-@@ -93,7 +95,7 @@ static int master_fprintf(FILE *, char *
-
- %token COMMENT
- %token MAP
--%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG
-+%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG OPT_RANDOM
- %token COLON COMMA NL DDASH
- %type <strtype> map
- %type <strtype> options
-@@ -174,6 +176,7 @@ line:
- | PATH COLON { master_notify($1); YYABORT; }
- | PATH OPTION { master_notify($2); YYABORT; }
- | PATH NILL { master_notify($2); YYABORT; }
-+ | PATH OPT_RANDOM { master_notify($1); YYABORT; }
- | PATH OPT_DEBUG { master_notify($1); YYABORT; }
- | PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
- | PATH OPT_GHOST { master_notify($1); YYABORT; }
-@@ -543,6 +546,7 @@ daemon_option: OPT_TIMEOUT NUMBER { time
- | OPT_GHOST { ghost = 1; }
- | OPT_VERBOSE { verbose = 1; }
- | OPT_DEBUG { debug = 1; }
-+ | OPT_RANDOM { random_selection = 1; }
- ;
-
- mount_option: OPTION
-@@ -600,6 +604,7 @@ static void local_init_vars(void)
- debug = 0;
- timeout = -1;
- ghost = defaults_get_browse_mode();
-+ random_selection = global_random_selection;
- tmp_argv = NULL;
- tmp_argc = 0;
- local_argv = NULL;
-@@ -790,6 +795,7 @@ int master_parse_entry(const char *buffe
- }
- set_mnt_logging(ap);
- }
-+ entry->ap->random_selection = random_selection;
-
- /*
- source = master_find_map_source(entry, type, format,
-diff -up autofs-5.0.2/man/auto.master.5.in.random-selection-fix autofs-5.0.2/man/auto.master.5.in
---- autofs-5.0.2/man/auto.master.5.in.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
-+++ autofs-5.0.2/man/auto.master.5.in 2007-11-20 14:55:28.000000000 +0900
-@@ -146,6 +146,12 @@ to prevent symlinking of local NFS mount
- prevent bind mounting of local NFS filesystems as well. If you need to
- prevent bind mounting for only specific entrys in a map then this
- can be done by adding the "port=" mount option to the given entries.
-+.TP
-+.I "\-r, \-\-random-multimount-selection"
-+Enables the use of ramdom selection when choosing a host from a
-+list of replicated servers. This option is applied to this mount
-+only, overriding the global setting that may be specified on the
-+command line.
- .SH GENERAL SYSTEM DEFAULTS CONFIGURATION
- .P
- The default value of several general settings may be changed in the
autofs-5.0.2-reread-config-on-hup.patch:
Index: autofs-5.0.2-reread-config-on-hup.patch
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-8/autofs-5.0.2-reread-config-on-hup.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- autofs-5.0.2-reread-config-on-hup.patch 20 Nov 2007 07:54:34 -0000 1.1
+++ autofs-5.0.2-reread-config-on-hup.patch 14 Feb 2008 07:28:32 -0000 1.2
@@ -1,7 +1,36 @@
-diff -up autofs-5.0.2/modules/cyrus-sasl.c.reread-config-on-hup autofs-5.0.2/modules/cyrus-sasl.c
---- autofs-5.0.2/modules/cyrus-sasl.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
-+++ autofs-5.0.2/modules/cyrus-sasl.c 2007-11-20 15:00:13.000000000 +0900
-@@ -528,6 +528,7 @@ sasl_do_kinit(struct lookup_context *ctx
+diff --git a/daemon/automount.c b/daemon/automount.c
+index e9cae4e..3d6a703 100644
+--- a/daemon/automount.c
++++ b/daemon/automount.c
+@@ -986,6 +986,8 @@ static void *do_read_master(void *arg)
+ if (status)
+ fatal(status);
+
++ defaults_read_config();
++
+ status = master_read_master(master, age, readall);
+
+ master->reading = 0;
+diff --git a/lib/master.c b/lib/master.c
+index da05bb6..637ce04 100644
+--- a/lib/master.c
++++ b/lib/master.c
+@@ -1169,6 +1169,10 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
+ continue;
+ }
+
++ master_source_writelock(this);
++ lookup_close_lookup(ap);
++ master_source_unlock(this);
++
+ cache_readlock(nc);
+ ne = cache_lookup_distinct(nc, this->path);
+ if (ne && this->age > ne->age) {
+diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
+index 8821f84..9aac792 100644
+--- a/modules/cyrus-sasl.c
++++ b/modules/cyrus-sasl.c
+@@ -528,6 +528,7 @@ sasl_do_kinit(struct lookup_context *ctxt)
return 0;
out_cleanup_unparse:
@@ -9,10 +38,11 @@
krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
out_cleanup_cc:
status = pthread_mutex_lock(&krb5cc_mutex);
-diff -up autofs-5.0.2/modules/lookup_ldap.c.reread-config-on-hup autofs-5.0.2/modules/lookup_ldap.c
---- autofs-5.0.2/modules/lookup_ldap.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
-+++ autofs-5.0.2/modules/lookup_ldap.c 2007-11-20 15:00:13.000000000 +0900
-@@ -174,7 +174,7 @@ LDAP *init_ldap_connection(struct lookup
+diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
+index 49a9a9b..2baf8b8 100644
+--- a/modules/lookup_ldap.c
++++ b/modules/lookup_ldap.c
+@@ -174,7 +174,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
{
char buf[PARSE_MAX_BUF];
@@ -21,7 +51,7 @@
LDAPMessage *result = NULL, *e;
struct ldap_searchdn *sdns = NULL;
char *attrs[2];
-@@ -225,15 +225,18 @@ static int get_query_dn(LDAP *ldap, stru
+@@ -225,15 +225,18 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
if (!ctxt->base) {
sdns = defaults_get_searchdns();
@@ -43,7 +73,7 @@
debug(LOGOPT_NONE, MODPREFIX
"check search base list");
-@@ -269,7 +272,6 @@ static int get_query_dn(LDAP *ldap, stru
+@@ -269,7 +272,6 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
if (e) {
dn = ldap_get_dn(ldap, e);
debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
@@ -51,7 +81,7 @@
} else {
debug(LOGOPT_NONE,
MODPREFIX "query succeeded, no matches for %s",
-@@ -278,7 +280,16 @@ static int get_query_dn(LDAP *ldap, stru
+@@ -278,7 +280,16 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
return 0;
}
@@ -69,7 +99,7 @@
return 1;
}
-@@ -1018,7 +1029,7 @@ static void free_context(struct lookup_c
+@@ -1018,7 +1029,7 @@ static void free_context(struct lookup_context *ctxt)
if (ctxt->mapname)
free(ctxt->mapname);
if (ctxt->qdn)
@@ -78,7 +108,7 @@
if (ctxt->server)
free(ctxt->server);
if (ctxt->cur_host)
-@@ -1600,14 +1611,14 @@ static int lookup_one(struct autofs_poin
+@@ -1600,14 +1611,14 @@ static int lookup_one(struct autofs_point *ap,
}
query[ql] = '\0';
@@ -96,29 +126,3 @@
rv = ldap_search_s(ldap, ctxt->qdn, scope, query, attrs, 0, &result);
if ((rv != LDAP_SUCCESS) || !result) {
-diff -up autofs-5.0.2/daemon/automount.c.reread-config-on-hup autofs-5.0.2/daemon/automount.c
---- autofs-5.0.2/daemon/automount.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
-+++ autofs-5.0.2/daemon/automount.c 2007-11-20 15:00:13.000000000 +0900
-@@ -978,6 +978,8 @@ static void *do_read_master(void *arg)
- if (status)
- fatal(status);
-
-+ defaults_read_config();
-+
- status = master_read_master(master, age, readall);
-
- master->reading = 0;
-diff -up autofs-5.0.2/lib/master.c.reread-config-on-hup autofs-5.0.2/lib/master.c
---- autofs-5.0.2/lib/master.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
-+++ autofs-5.0.2/lib/master.c 2007-11-20 15:00:13.000000000 +0900
-@@ -1170,6 +1170,10 @@ int master_mount_mounts(struct master *m
- continue;
- }
-
-+ master_source_writelock(this);
-+ lookup_close_lookup(ap);
-+ master_source_unlock(this);
-+
- cache_readlock(nc);
- ne = cache_lookup_distinct(nc, this->path);
- if (ne && this->age > ne->age) {
Index: autofs.spec
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-8/autofs.spec,v
retrieving revision 1.235
retrieving revision 1.236
diff -u -r1.235 -r1.236
--- autofs.spec 3 Feb 2008 11:23:05 -0000 1.235
+++ autofs.spec 14 Feb 2008 07:28:32 -0000 1.236
@@ -4,7 +4,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.0.2
-Release: 26
+Release: 27
Epoch: 1
License: GPL
Group: System Environment/Daemons
@@ -14,49 +14,72 @@
Patch1: autofs-5.0.2-bad-proto-init.patch
Patch2: autofs-5.0.2-add-missing-multi-support.patch
Patch3: autofs-5.0.2-add-multi-nsswitch-lookup.patch
-Patch4: autofs-5.0.2-fix-offset-dir-create.patch
-Patch5: autofs-5.0.2-quote-exports.patch
-Patch6: autofs-5.0.2-hi-res-time.patch
-Patch7: autofs-5.0.2-quoted-slash-alone.patch
-Patch8: autofs-5.0.2-fix-dnattr-parse.patch
-Patch9: autofs-5.0.2-fix-nfs-version-in-get-supported-ver-and-cost.patch
-Patch10: autofs-5.0.2-fix-largefile-dumbness.patch
+Patch4: autofs-5.0.2-consistent-random-selection-option-name.patch
+Patch5: autofs-5.0.2-fix-offset-dir-create.patch
+Patch6: autofs-5.0.2-quote-exports.patch
+Patch7: autofs-5.0.2-hi-res-time.patch
+Patch8: autofs-5.0.2-quoted-slash-alone.patch
+Patch9: autofs-5.0.2-fix-dnattr-parse.patch
+Patch10: autofs-5.0.2-fix-nfs-version-in-get-supported-ver-and-cost.patch
Patch11: autofs-5.0.2-instance-stale-mark.patch
-Patch12: autofs-5.0.2-dont-fail-on-empty-master.patch
-Patch13: autofs-5.0.2-ldap-percent-hack.patch
-Patch14: autofs-5.0.2-consistent-random-selection-option-name.patch
+Patch12: autofs-5.0.2-fix-largefile-dumbness.patch
+Patch13: autofs-5.0.2-dont-fail-on-empty-master.patch
+Patch14: autofs-5.0.2-ldap-percent-hack.patch
Patch15: autofs-5.0.2-fix-mount-nfs-nosymlink.patch
Patch16: autofs-5.0.2-default-nsswitch.patch
Patch17: autofs-5.0.2-add-ldap-schema-discovery.patch
-Patch18: autofs-5.0.2-ldap-schema-discovery-config-update.patch
-Patch19: autofs-5.0.2-libxml2-workaround.patch
-Patch20: autofs-5.0.2-foreground-logging.patch
-Patch21: autofs-5.0.2-add-ldap-schema-discovery-fix-2.patch
-Patch22: autofs-5.0.2-ldap-check-star.patch
-Patch23: autofs-5.0.2-timeout-option-parse-fix.patch
-Patch24: autofs-5.0.2-ldap-search-basedn-list.patch
-Patch25: autofs-5.0.2-random-selection-fix.patch
-Patch26: autofs-5.0.2-reread-config-on-hup.patch
-Patch27: autofs-5.0.2-add-multiple-server-selection-option.patch
-Patch28: autofs-5.0.2-submount-deadlock.patch
-Patch29: autofs-5.0.2-add-ferror-check.patch
-Patch30: autofs-5.0.2-autofs-5-typo.patch
-Patch31: autofs-5.0.2-swallow-null-macro.patch
-Patch32: autofs-5.0.2-remove-unused-export-validation-code.patch
-Patch33: autofs-5.0.2-dynamic-logging.patch
-Patch34: autofs-5.0.2-fix-recursive-loopback-mounts.patch
-Patch35: autofs-5.0.2-log-map-reload.patch
+Patch18: autofs-5.0.2-random-selection-fix.patch
+Patch19: autofs-5.0.2-timeout-option-parse-fix.patch
+Patch20: autofs-5.0.2-ldap-check-star.patch
+Patch21: autofs-5.0.2-ldap-schema-discovery-config-update.patch
+Patch22: autofs-5.0.2-ldap-search-basedn-list.patch
+Patch23: autofs-5.0.2-libxml2-workaround.patch
+Patch24: autofs-5.0.2-reread-config-on-hup.patch
+Patch25: autofs-5.0.2-add-multiple-server-selection-option.patch
+Patch26: autofs-5.0.2-foreground-logging.patch
+Patch27: autofs-5.0.2-submount-deadlock.patch
+Patch28: autofs-5.0.2-add-ferror-check.patch
+Patch29: autofs-5.0.2-autofs-5-typo.patch
+Patch30: autofs-5.0.2-swallow-null-macro.patch
+Patch31: autofs-5.0.2-remove-unused-export-validation-code.patch
+Patch32: autofs-5.0.2-dynamic-logging.patch
+Patch33: autofs-5.0.2-fix-recursive-loopback-mounts.patch
+Patch34: autofs-5.0.2-log-map-reload.patch
+Patch35: autofs-5.0.2-basedn-with-spaces.patch
Patch36: autofs-5.0.2-dynamic-logging-fixes.patch
-Patch37: autofs-5.0.2-basedn-with-spaces.patch
+Patch37: autofs-5.0.2-basedn-with-spaces-fix.patch
Patch38: autofs-5.0.2-check-mtab-updated.patch
-Patch39: autofs-5.0.2-check-auto_master.patch
-Patch40: autofs-5.0.2-negative-timeout-update.patch
-Patch41: autofs-5.0.2-large-groups.patch
-Patch42: autofs-5.0.2-report-failed-lookups.patch
-Patch43: autofs-5.0.2-dynamic-logging-non-sasl.patch
-Patch44: autofs-5.0.2-singleton-host-list.patch
-Patch45: autofs-5.0.2-hosts-nosuid-default.patch
-Patch46: autofs-5.0.2-hosts-nodev-default.patch
+Patch39: autofs-5.0.2-basedn-with-spaces-fix-2.patch
+Patch40: autofs-5.0.2-check-auto_master.patch
+Patch41: autofs-5.0.2-add-ldap-schema-discovery-fix-2.patch
+Patch42: autofs-5.0.2-negative-timeout-update.patch
+Patch43: autofs-5.0.2-large-groups.patch
+Patch44: autofs-5.0.2-report-failed-lookups.patch
+Patch45: autofs-5.0.2-dynamic-logging-non-sasl.patch
+Patch46: autofs-5.0.2-singleton-host-list.patch
+Patch47: autofs-5.0.2-hosts-nosuid-default.patch
+Patch48: autofs-5.0.2-hosts-nodev-default.patch
+Patch49: autofs-5.0.2-start-pipe-buff-size.patch
+Patch50: autofs-5.0.2-fix-off-by-one-lookup.patch
+Patch51: autofs-5.0.2-improve-server-unavail.patch
+Patch52: autofs-5.0.2-add-multiple-server-selection-option-fix.patch
+Patch53: autofs-5.0.2-external-cred-cache.patch
+Patch54: autofs-5.0.2-percent-hack-fix.patch
+Patch55: autofs-5.0.2-quote-exports-fix.patch
+Patch56: autofs-5.0.2-quell-mount-module-message.patch
+Patch57: autofs-5.0.2-improve-server-unavail-fix.patch
+Patch58: autofs-5.0.2-ldap-page-control.patch
+Patch59: autofs-5.0.2-instance-stale-mark-update.patch
+Patch60: autofs-5.0.2-submount-shutdown-race.patch
+Patch61: autofs-5.0.2-ldap-search-basedn-list-fix.patch
+Patch62: autofs-5.0.3-ldap-page-control-configure-fix.patch
+Patch63: autofs-5.0.3-xfn-not-supported.patch
+Patch64: autofs-5.0.3-basedn-with-spaces-fix-3.patch
+Patch65: autofs-5.0.3-nfs4-tcp-only.patch
+Patch66: autofs-5.0.3-correct-ldap-lib.patch
+Patch67: autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch
+Patch68: autofs-5.0.3-expire-works-too-hard.patch
+Patch69: autofs-5.0.3-unlink-mount-return-fix.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
Conflicts: kernel < 2.6.17
@@ -145,6 +168,29 @@
%patch44 -p1
%patch45 -p1
%patch46 -p1
+%patch47 -p1
+%patch48 -p1
+%patch49 -p1
+%patch50 -p1
+%patch51 -p1
+%patch52 -p1
+%patch53 -p1
+%patch54 -p1
+%patch55 -p1
+%patch56 -p1
+%patch57 -p1
+%patch58 -p1
+%patch59 -p1
+%patch60 -p1
+%patch61 -p1
+%patch62 -p1
+%patch63 -p1
+%patch64 -p1
+%patch65 -p1
+%patch66 -p1
+%patch67 -p1
+%patch68 -p1
+%patch69 -p1
%build
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -197,6 +243,37 @@
%{_libdir}/autofs/
%changelog
+* Thu Feb 14 2008 Ian Kent <ikent at redhat.com> - 5.0.2-26
+- re-order and update patches to sync with upstream.
+ - located missing patch.
+ - replaced couple of patches previously altered due to incorrect ordering.
+- add patches for upstream issues - synced with 5.0.3.
+ - fix incorrect read/write size of startup status token (Matthias Koenig).
+ - fix off-by-one error for lookup of map keys exactly 255 characters long.
+ - improve handling of server not available.
+ - fix LDAP_URI server selection.
+ - add authentication option for using an external credential cache.
+ - expand support for the "%" hack.
+ - fix to quoting for exports gathered by hosts map.
+ - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified.
+ - second attempt fixing quoting for exports gathered by hosts map.
+ - quell annoying "cannot open mount module" message.
+ - fix for improve handling of server not available.
+ - use mount option "nodev" for "-hosts" map unless "dev" is explicily specified.
+ - add LDAP paged query handling to deal with query size restrictions (Edward Newman).
+ - add additional case for "mark map instances stale so they aren't "cleaned" during updates".
+ - fix race during sub-mount shutdown.
+ - fix add SEARCH_BASE configuration option.
+- add patches for upstream issues - post 5.0.3.
+ - correct configure test for ldapr page control functions.
+ - catch "-xfn" map type and issue "no supported" message.
+ - correction for handling of LDAP base dns with spaces.
+ - avoid using UDP for probing NFSv4 mount requests.
+ - use libldap instead of libldap_r (Guillaume Rousse).
+ - another fix for don't fail on empty master map.
+ - fix expire working harder than needed.
+ - fix unlink of mount tree incorrectly causing autofs mount fail.
+
* Sun Feb 3 2008 Ian Kent <ikent at redhat.com> - 5.0.2-25
- Bug 397591 SELinux is preventing /sbin/rpc.statd (rpcd_t) "search" to <Unknown> (sysctl_fs_t).
- remove this patch.
More information about the fedora-extras-commits
mailing list