|
|
306fa1 |
autofs-5.1.0-beta1 - fix multi entry ldap option handling
|
|
|
306fa1 |
|
|
|
306fa1 |
From: Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
|
|
|
306fa1 |
Handling new and old configurations presents special problems for
|
|
|
306fa1 |
configuration entries that may have repeated values, such as ldap_uris
|
|
|
306fa1 |
and ldap_search_base, which can be overridden when the old configuration
|
|
|
306fa1 |
is read.
|
|
|
306fa1 |
|
|
|
306fa1 |
If entries exist in the new configuration they need to be saved and
|
|
|
306fa1 |
restored if there's no entries in the old configuration or, if entries
|
|
|
306fa1 |
exist in the old configuration, they need to be discarded.
|
|
|
306fa1 |
---
|
|
|
306fa1 |
CHANGELOG | 1
|
|
|
306fa1 |
lib/defaults.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++-----------
|
|
|
306fa1 |
2 files changed, 198 insertions(+), 44 deletions(-)
|
|
|
306fa1 |
|
|
|
306fa1 |
--- autofs-5.0.7.orig/CHANGELOG
|
|
|
306fa1 |
+++ autofs-5.0.7/CHANGELOG
|
|
|
306fa1 |
@@ -122,6 +122,7 @@
|
|
|
306fa1 |
- fix typo in conf_load_autofs_defaults().
|
|
|
306fa1 |
- fix hash on confg option add and delete.
|
|
|
306fa1 |
- add plus to path match pattern.
|
|
|
306fa1 |
+- fix multi entry ldap option handling.
|
|
|
306fa1 |
|
|
|
306fa1 |
25/07/2012 autofs-5.0.7
|
|
|
306fa1 |
=======================
|
|
|
306fa1 |
--- autofs-5.0.7.orig/lib/defaults.c
|
|
|
306fa1 |
+++ autofs-5.0.7/lib/defaults.c
|
|
|
306fa1 |
@@ -916,83 +916,236 @@ static int read_config(unsigned int to_s
|
|
|
306fa1 |
return 0;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
-/*
|
|
|
306fa1 |
- * Read config env variables and check they have been set.
|
|
|
306fa1 |
- *
|
|
|
306fa1 |
- * This simple minded routine assumes the config file
|
|
|
306fa1 |
- * is valid bourne shell script without spaces around "="
|
|
|
306fa1 |
- * and that it has valid values.
|
|
|
306fa1 |
- */
|
|
|
306fa1 |
-unsigned int defaults_read_config(unsigned int to_syslog)
|
|
|
306fa1 |
+struct conf_option *save_ldap_option_list(const char *key)
|
|
|
306fa1 |
{
|
|
|
306fa1 |
- FILE *f;
|
|
|
306fa1 |
- struct stat stb;
|
|
|
306fa1 |
- int ret;
|
|
|
306fa1 |
+ struct conf_option *co, *head, *this, *last;
|
|
|
306fa1 |
+ unsigned int size = CFG_TABLE_SIZE;
|
|
|
306fa1 |
+ u_int32_t key_hash;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ key_hash = get_hash(key, size);
|
|
|
306fa1 |
+ co = config->hash[key_hash];
|
|
|
306fa1 |
+ if (!co)
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+ last = co;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ head = this = NULL;
|
|
|
306fa1 |
+ while (co) {
|
|
|
306fa1 |
+ if (strcasecmp(autofs_gbl_sec, co->section)) {
|
|
|
306fa1 |
+ last = co;
|
|
|
306fa1 |
+ goto next;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
|
|
|
306fa1 |
- pthread_mutex_lock(&conf_mutex);
|
|
|
306fa1 |
- if (!config) {
|
|
|
306fa1 |
- if (conf_init()) {
|
|
|
306fa1 |
- pthread_mutex_unlock(&conf_mutex);
|
|
|
306fa1 |
- message(to_syslog, "failed to init config");
|
|
|
306fa1 |
- return 0;
|
|
|
306fa1 |
+ if (!strcasecmp(co->name, key)) {
|
|
|
306fa1 |
+ /* Unlink from old */
|
|
|
306fa1 |
+ if (co == config->hash[key_hash])
|
|
|
306fa1 |
+ config->hash[key_hash] = co->next;
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ last->next = co->next;
|
|
|
306fa1 |
+ last = co->next;
|
|
|
306fa1 |
+ co->next = NULL;
|
|
|
306fa1 |
+ /* Add to new */
|
|
|
306fa1 |
+ if (this)
|
|
|
306fa1 |
+ this->next = co;
|
|
|
306fa1 |
+ this = co;
|
|
|
306fa1 |
+ /* If none have been found yet */
|
|
|
306fa1 |
+ if (!head)
|
|
|
306fa1 |
+ head = co;
|
|
|
306fa1 |
+ co = last;
|
|
|
306fa1 |
+ continue;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
+next:
|
|
|
306fa1 |
+ co = co->next;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return head;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void restore_ldap_option_list(struct conf_option *list)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct conf_option *co, *this, *last;
|
|
|
306fa1 |
+ unsigned int size = CFG_TABLE_SIZE;
|
|
|
306fa1 |
+ u_int32_t key_hash;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!list)
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ this = list;
|
|
|
306fa1 |
+ while (this) {
|
|
|
306fa1 |
+ last = this;
|
|
|
306fa1 |
+ this = this->next;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ key_hash = get_hash(list->name, size);
|
|
|
306fa1 |
+ co = config->hash[key_hash];
|
|
|
306fa1 |
+ config->hash[key_hash] = list;
|
|
|
306fa1 |
+ if (co)
|
|
|
306fa1 |
+ last->next = co;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void free_ldap_option_list(struct conf_option *list)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct conf_option *next, *this;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!list)
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ this = list;
|
|
|
306fa1 |
+ while (this) {
|
|
|
306fa1 |
+ next = this->next;
|
|
|
306fa1 |
+ free(this->section);
|
|
|
306fa1 |
+ free(this->name);
|
|
|
306fa1 |
+ free(this->value);
|
|
|
306fa1 |
+ free(this);
|
|
|
306fa1 |
+ this = next;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
- /* Set configuration to defaults */
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void clean_ldap_multi_option(const char *key)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ const char *sec = autofs_gbl_sec;
|
|
|
306fa1 |
+ struct conf_option *co;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ while ((co = conf_lookup(sec, key)))
|
|
|
306fa1 |
+ conf_delete(co->section, co->name);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int reset_defaults(unsigned int to_syslog)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int ret;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
ret = conf_load_autofs_defaults();
|
|
|
306fa1 |
if (!ret) {
|
|
|
306fa1 |
- pthread_mutex_unlock(&conf_mutex);
|
|
|
306fa1 |
message(to_syslog, "failed to reset autofs default config");
|
|
|
306fa1 |
return 0;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
ret = conf_load_amd_defaults();
|
|
|
306fa1 |
if (!ret) {
|
|
|
306fa1 |
- pthread_mutex_unlock(&conf_mutex);
|
|
|
306fa1 |
message(to_syslog, "failed to reset amd default config");
|
|
|
306fa1 |
return 0;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
- f = open_fopen_r(DEFAULT_CONFIG_FILE);
|
|
|
306fa1 |
- if (!f) {
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+/*
|
|
|
306fa1 |
+ * Read config env variables and check they have been set.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This simple minded routine assumes the config file
|
|
|
306fa1 |
+ * is valid bourne shell script without spaces around "="
|
|
|
306fa1 |
+ * and that it has valid values.
|
|
|
306fa1 |
+ */
|
|
|
306fa1 |
+unsigned int defaults_read_config(unsigned int to_syslog)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ FILE *conf, *oldconf;
|
|
|
306fa1 |
+ struct stat stb, oldstb;
|
|
|
306fa1 |
+ int ret, stat, oldstat;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ret = 1;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ pthread_mutex_lock(&conf_mutex);
|
|
|
306fa1 |
+ if (!config) {
|
|
|
306fa1 |
+ if (conf_init()) {
|
|
|
306fa1 |
+ message(to_syslog, "failed to init config");
|
|
|
306fa1 |
+ ret = 0;
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ conf = open_fopen_r(DEFAULT_CONFIG_FILE);
|
|
|
306fa1 |
+ if (!conf)
|
|
|
306fa1 |
message(to_syslog, "failed to to open config %s",
|
|
|
306fa1 |
DEFAULT_CONFIG_FILE);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ oldconf = open_fopen_r(OLD_CONFIG_FILE);
|
|
|
306fa1 |
+ if (!oldconf)
|
|
|
306fa1 |
+ message(to_syslog, "failed to to open old config %s",
|
|
|
306fa1 |
+ OLD_CONFIG_FILE);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* Neither config has been updated */
|
|
|
306fa1 |
+ stat = oldstat = -1;
|
|
|
306fa1 |
+ if (conf && oldconf &&
|
|
|
306fa1 |
+ (stat = fstat(fileno(conf), &stb) != -1) &&
|
|
|
306fa1 |
+ stb.st_mtime <= config->modified &&
|
|
|
306fa1 |
+ (oldstat = fstat(fileno(oldconf), &oldstb) == -1) &&
|
|
|
306fa1 |
+ oldstb.st_mtime <= config->modified) {
|
|
|
306fa1 |
+ fclose(conf);
|
|
|
306fa1 |
+ fclose(oldconf);
|
|
|
306fa1 |
goto out;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
- if (fstat(fileno(f), &stb) != -1) {
|
|
|
306fa1 |
- /* Config hasn't been updated */
|
|
|
306fa1 |
- if (stb.st_mtime <= config->modified) {
|
|
|
306fa1 |
- fclose(f);
|
|
|
306fa1 |
+ if (conf || oldconf) {
|
|
|
306fa1 |
+ if (!reset_defaults(to_syslog)) {
|
|
|
306fa1 |
+ fclose(conf);
|
|
|
306fa1 |
+ fclose(oldconf);
|
|
|
306fa1 |
+ ret = 0;
|
|
|
306fa1 |
goto out;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
- ret = read_config(to_syslog, f, DEFAULT_CONFIG_FILE);
|
|
|
306fa1 |
-
|
|
|
306fa1 |
- if (fstat(fileno(f), &stb) != -1)
|
|
|
306fa1 |
- config->modified = stb.st_mtime;
|
|
|
306fa1 |
- else
|
|
|
306fa1 |
- message(to_syslog, "failed to update config modified time");
|
|
|
306fa1 |
+ /* Update last modified */
|
|
|
306fa1 |
+ if (stat != -1) {
|
|
|
306fa1 |
+ if (oldstat == -1)
|
|
|
306fa1 |
+ config->modified = stb.st_mtime;
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ if (oldstb.st_mtime < stb.st_mtime)
|
|
|
306fa1 |
+ config->modified = oldstb.st_mtime;
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ config->modified = stb.st_mtime;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
|
|
|
306fa1 |
- fclose(f);
|
|
|
306fa1 |
+ if (conf) {
|
|
|
306fa1 |
+ read_config(to_syslog, conf, DEFAULT_CONFIG_FILE);
|
|
|
306fa1 |
+ fclose(conf);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
|
|
|
306fa1 |
/*
|
|
|
306fa1 |
- * Try to read the old config file and override the installed
|
|
|
306fa1 |
- * defaults in case user has a stale config following updating
|
|
|
306fa1 |
- * to the new config file location.
|
|
|
306fa1 |
+ * Read the old config file and override the installed
|
|
|
306fa1 |
+ * defaults in case user has a stale config following
|
|
|
306fa1 |
+ * updating to the new config file location.
|
|
|
306fa1 |
*/
|
|
|
306fa1 |
+ if (oldconf) {
|
|
|
306fa1 |
+ struct conf_option *ldap_search_base, *ldap_uris;
|
|
|
306fa1 |
+ const char *sec = amd_gbl_sec;
|
|
|
306fa1 |
+ struct conf_option *co;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ldap_search_base = save_ldap_option_list(NAME_SEARCH_BASE);
|
|
|
306fa1 |
+ if (ldap_search_base)
|
|
|
306fa1 |
+ clean_ldap_multi_option(NAME_SEARCH_BASE);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ldap_uris = save_ldap_option_list(NAME_LDAP_URI);
|
|
|
306fa1 |
+ if (ldap_uris)
|
|
|
306fa1 |
+ clean_ldap_multi_option(NAME_LDAP_URI);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ read_config(to_syslog, oldconf, OLD_CONFIG_FILE);
|
|
|
306fa1 |
+ fclose(oldconf);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (ldap_search_base) {
|
|
|
306fa1 |
+ co = conf_lookup(sec, NAME_SEARCH_BASE);
|
|
|
306fa1 |
+ if (co)
|
|
|
306fa1 |
+ free_ldap_option_list(ldap_search_base);
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ restore_ldap_option_list(ldap_search_base);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
|
|
|
306fa1 |
- f = open_fopen_r(OLD_CONFIG_FILE);
|
|
|
306fa1 |
- if (!f)
|
|
|
306fa1 |
- goto out;
|
|
|
306fa1 |
-
|
|
|
306fa1 |
- read_config(to_syslog, f, OLD_CONFIG_FILE);
|
|
|
306fa1 |
-
|
|
|
306fa1 |
- fclose(f);
|
|
|
306fa1 |
+ if (ldap_uris) {
|
|
|
306fa1 |
+ co = conf_lookup(sec, NAME_LDAP_URI);
|
|
|
306fa1 |
+ if (co)
|
|
|
306fa1 |
+ free_ldap_option_list(ldap_uris);
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ restore_ldap_option_list(ldap_uris);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
out:
|
|
|
306fa1 |
pthread_mutex_unlock(&conf_mutex);
|
|
|
306fa1 |
- return 1;
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
static char *conf_get_string(const char *section, const char *name)
|