diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend.c | 87 | ||||
-rw-r--r-- | src/backend.h | 3 | ||||
-rw-r--r-- | src/dummymap.c | 13 | ||||
-rw-r--r-- | src/map.c | 68 | ||||
-rw-r--r-- | src/map.h | 5 | ||||
-rw-r--r-- | src/nis.c | 6 |
6 files changed, 147 insertions, 35 deletions
diff --git a/src/backend.c b/src/backend.c index bb4d38d..a004eae 100644 --- a/src/backend.c +++ b/src/backend.c @@ -24,6 +24,66 @@ struct backend_map_data { char *domain, *map, **bases, *filter, *key_fmt, *value_fmt; }; +/* Read the name of the NIS master. */ +void +backend_free_master_name(struct plugin_state *state, char *master) +{ + free(master); +} + +int +backend_read_master_name(struct plugin_state *state, char **master) +{ + Slapi_DN *config_dn; + Slapi_Entry *config; + Slapi_ValueSet *values; + Slapi_Value *value; + char *attrs[] = {"nsslapd-localhost", NULL}, *actual_attr; + const char *cvalue; + int disposition, buffer_flags; + *master = NULL; + /* Try to read our name from the top-level configuration node. */ + config_dn = slapi_sdn_new_dn_byval("cn=config"); + if (config_dn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "backend_master_name: " + "error parsing \"cn=config\"\n"); + return -1; + } + config = NULL; + slapi_search_internal_get_entry(config_dn, attrs, &config, + state->plugin_identity); + if (config == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "backend_master_name: failure reading " + "\"cn=config\""); + slapi_sdn_free(&config_dn); + return -1; + } + slapi_sdn_free(&config_dn); + /* Pull out the attribute. */ + if (slapi_vattr_values_get(config, attrs[0], &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + if (slapi_valueset_first_value(values, &value) == 0) { + cvalue = slapi_value_get_string(value); + if (cvalue != NULL) { + *master = strdup(cvalue); + } + } else { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "backend_master_name: no \"%s\" value " + "for \"cn=config\"", + attrs[0]); + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + slapi_entry_free(config); + return (*master != NULL) ? 0 : -1; +} static char ** backend_dup_strlist(char **strlist) { @@ -363,7 +423,8 @@ backend_startup(struct plugin_state *state) /* Our postoperation callbacks. */ static PRBool -backend_entry_matches_map(struct backend_map_data *map_data, Slapi_Entry *e) +backend_entry_matches_map(struct backend_map_data *map_data, + Slapi_PBlock *pb, Slapi_Entry *e) { Slapi_DN *base_sdn; const Slapi_DN *entry_sdn; @@ -406,7 +467,7 @@ backend_entry_matches_map(struct backend_map_data *map_data, Slapi_Entry *e) if (filter == NULL) { return PR_FALSE; } else { - if (slapi_filter_test_simple(e, filter) != 0) { + if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { /* Didn't match -- return. */ slapi_filter_free(filter, 1); return PR_FALSE; @@ -440,7 +501,7 @@ backend_add_entry_cb(const char *domain, const char *map, void *backend_data, cbdata = cbdata_ptr; /* If the entry doesn't match the map, skip it. */ - if (!backend_entry_matches_map(map_data, cbdata->e)) { + if (!backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { slapi_log_error(SLAPI_LOG_PLUGIN, map_data->state->plugin_desc->spd_id, "entry \"%s\" does not belong in " @@ -537,7 +598,7 @@ backend_modify_entry_cb(const char *domain, const char *map, void *backend_data, cbdata = cbdata_ptr; /* If the entry doesn't match the map, skip it. */ - if (!backend_entry_matches_map(map_data, cbdata->e)) { + if (!backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { slapi_log_error(SLAPI_LOG_PLUGIN, map_data->state->plugin_desc->spd_id, "clearing domain/map/id " @@ -644,8 +705,10 @@ backend_modrdn_entry_cb(const char *domain, const char *map, void *backend_data, map_data = backend_data; cbdata = cbdata_ptr; - matched_pre = backend_entry_matches_map(map_data, cbdata->e_pre); - matched_post = backend_entry_matches_map(map_data, cbdata->e_post); + matched_pre = backend_entry_matches_map(map_data, + cbdata->pb, cbdata->e_pre); + matched_post = backend_entry_matches_map(map_data, + cbdata->pb, cbdata->e_post); /* Pull out the key and value for the old entry. */ key_pre = format_get_data(cbdata->state, cbdata->pb, cbdata->e_pre, @@ -855,15 +918,3 @@ backend_init(Slapi_PBlock *pb, struct plugin_state *state) "error hooking up delete callback\n"); } } - -void * -xmemdup(char *region, int size) -{ - char *ret; - ret = malloc(size + 1); - if (ret != NULL) { - memcpy(ret, region, size); - ret[size] = '\0'; - } - return ret; -} diff --git a/src/backend.h b/src/backend.h index ed6bcd5..260204b 100644 --- a/src/backend.h +++ b/src/backend.h @@ -1,6 +1,7 @@ /* Initialize maps. */ struct plugin_state; struct slapi_pblock; +int backend_read_master_name(struct plugin_state *state, char **master); +void backend_free_master_name(struct plugin_state *state, char *master); void backend_startup(struct plugin_state *state); void backend_init(struct slapi_pblock *pb, struct plugin_state *state); -void *xmemdup(char *region, int size); diff --git a/src/dummymap.c b/src/dummymap.c index 104fdc6..7ba1728 100644 --- a/src/dummymap.c +++ b/src/dummymap.c @@ -63,14 +63,23 @@ struct domain domains[] = { {NULL, NULL}, }; -void +int map_startup(struct plugin_state *state) { + return 0; } -void +int map_init(struct slapi_pblock *pb, struct plugin_state *state) { + return 0; +} + +int +map_master_name(struct plugin_state *state, const char **master) +{ + *master = "me, right here"; + return 0; } bool_t @@ -3,6 +3,7 @@ #endif #include <sys/types.h> +#include <pthread.h> #include <search.h> #include <stdlib.h> #include <string.h> @@ -22,21 +23,32 @@ /* The singleton for the cache. */ struct { + char *master; struct domain { char *name; struct map { + /* Map name and order. */ char *name; time_t last_changed; + /* Individual map entries. */ struct map_entry { + /* Links to previous and next nodes in the + * list. */ struct map_entry *prev, *next; + /* The name of the backend entry for this + * entry, and the names of others which + * contributed to the value. */ char *id, **related_ids; + /* Key and value. */ char *key; unsigned int key_len; char *value; unsigned int value_len; } *entries; + /* Search trees to speed up searches for entries. */ void *key_tree; void *id_tree; + /* Callback data supplied by the map writer. */ void *backend_data; void (*free_backend_data)(void *backend_data); } *maps; @@ -45,6 +57,18 @@ struct { int n_domains; } map_data; +static void * +xmemdup(char *region, int size) +{ + char *ret; + ret = malloc(size + 1); + if (ret != NULL) { + memcpy(ret, region, size); + ret[size] = '\0'; + } + return ret; +} + /* Comparison functions used by the tree storage facility. */ static int t_compare_entry_by_id(const void *p1, const void *p2) @@ -130,12 +154,9 @@ map_data_find_entry(struct plugin_state *state, const char *domain_name, const char *map_name, unsigned int key_len, const char *key) { - return map_data_find_map_entry(state, - map_data_find_map(state, - domain_name, - map_name), - key_len, - key); + struct map *map; + map = map_data_find_map(state, domain_name, map_name); + return map_data_find_map_entry(state, map, key_len, key); } static struct map_entry * @@ -345,6 +366,27 @@ map_supports_map(struct plugin_state *state, return TRUE; } +/* Query function: return the name of this master. */ +int +map_master_name(struct plugin_state *state, const char **master) +{ + char *tmp, hostname[HOST_NAME_MAX + 1]; + if (backend_read_master_name(state, &tmp) == 0) { + free(map_data.master); + map_data.master = strdup(tmp); + backend_free_master_name(state, tmp); + } else { + memset(hostname, '\0', sizeof(hostname)); + if (gethostname(hostname, sizeof(hostname)) != 0) { + snprintf(hostname, sizeof(hostname), "%s", "localhost"); + } + free(map_data.master); + map_data.master = strdup(hostname); + } + *master = map_data.master; + return 0; +} + /* Query function: return an indication of the map's age. Should never * decrease. */ PRBool @@ -456,8 +498,9 @@ void map_data_clear_map(struct plugin_state *state, const char *domain_name, const char *map_name) { - map_data_clear_map_map(state, - map_data_find_map(state, domain_name, map_name)); + struct map *map; + map = map_data_find_map(state, domain_name, map_name); + map_data_clear_map_map(state, map); } /* Remove a map from the configuration, removing its domain record if the map @@ -730,18 +773,21 @@ map_data_set_entry(struct plugin_state *state, /* XXX */ } } + map->last_changed = time(NULL); } - map->last_changed = time(NULL); } -void +int map_startup(struct plugin_state *state) { backend_startup(state); + return 0; } -void +int map_init(struct slapi_pblock *pb, struct plugin_state *state) { + memset(&map_data, 0, sizeof(map_data)); backend_init(pb, state); + return 0; } @@ -1,8 +1,9 @@ struct plugin_state; struct slapi_pblock; /* Functions to pull data out of maps. */ -void map_startup(struct plugin_state *state); -void map_init(struct slapi_pblock *pb, struct plugin_state *state); +int map_startup(struct plugin_state *state); +int map_init(struct slapi_pblock *pb, struct plugin_state *state); +int map_master_name(struct plugin_state *state, const char **master); PRBool map_supports_domain(struct plugin_state *state, const char *domain, PRBool *supported); @@ -285,11 +285,15 @@ nis_master(struct plugin_state *state, struct ypresp_master *reply_master) { struct ypreq_nokey req_nokey; + const char *master; memset(&req_nokey, 0, sizeof(req_nokey)); memset(reply_master, 0, sizeof(*reply_master)); if (xdr_ypreq_nokey(request_xdrs, &req_nokey)) { reply_master->status = YP_TRUE; - reply_master->master = "me, right here"; /* XXX */ + if (map_master_name(state, &master) != 0) { + master = "localhost"; + } + reply_master->master = (char *) master; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "master(%s/%s) -> %s\n", |