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