diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-04 18:46:26 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-04 18:46:26 -0400 |
commit | 3e79d871c80cbec3ed306a17ce39f3d95f81c07d (patch) | |
tree | 3797a7242d3a2b08b7ea4be7f0e49f99b6ec20e7 /src | |
parent | e095d84d1c2a58dc20aecfd7215daa7a5084cea4 (diff) | |
download | slapi-nis-3e79d871c80cbec3ed306a17ce39f3d95f81c07d.tar.gz slapi-nis-3e79d871c80cbec3ed306a17ce39f3d95f81c07d.tar.xz slapi-nis-3e79d871c80cbec3ed306a17ce39f3d95f81c07d.zip |
- add a "referred" function
- make formatting functions take the domain and map name now
Diffstat (limited to 'src')
-rw-r--r-- | src/format.c | 208 | ||||
-rw-r--r-- | src/format.h | 1 |
2 files changed, 195 insertions, 14 deletions
diff --git a/src/format.c b/src/format.c index 2daef85..66a8940 100644 --- a/src/format.c +++ b/src/format.c @@ -39,6 +39,7 @@ #include <rpcsvc/yp.h> +#include "backend.h" #include "defaults.h" #include "format.h" #include "plugin.h" @@ -47,7 +48,7 @@ #define MAX_BUFFER_SIZE 0x100000 static int format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *fmt, + const char *domain, const char *map, const char *fmt, char *outbuf, int outbuf_len, char ***visited_ndns, bool_t contains_literals); @@ -133,6 +134,7 @@ format_parse_args(struct plugin_state *state, const char *args, /* Echo the parameter text. */ static int format_echo(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { @@ -172,6 +174,7 @@ format_echo(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, * joined by a separator given as the first argument. */ static int format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { @@ -250,6 +253,7 @@ format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, * argument, and create a list separated by the first argument. */ static int format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { @@ -299,8 +303,8 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, if (refdn == NULL) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "deref: internal error reading \"%s\"", - cref); + "deref: internal error reading " + "\"%s\"\n", cref); continue; } ref = NULL; @@ -386,10 +390,176 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return ret; } +/* Look up entries in the map named by the second argument, which have the + * entry's DN stored in the attribute named by the third argument, pull out the + * values for the attribute named by the fourth argument, and create a list + * separated by the first argument. */ +struct format_referred_cbdata { + struct plugin_state *state; + char *attr, *separator; + char *outbuf; + int outbuf_len; + int count; + int ret; +}; +static int +format_referred_entry_cb(Slapi_Entry *e, void *callback_data) +{ + Slapi_ValueSet *values; + Slapi_Value *value; + int i, j, disposition, buffer_flags, len, slen; + char *actual_attr; + const char *cvalue; + struct format_referred_cbdata *cbdata = callback_data; + + /* Iterate through the values for the specified attribute. */ + if (slapi_vattr_values_get(e, cbdata->attr, &values, + &disposition, &actual_attr, + 0, &buffer_flags) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "referred: no values for \"%s\" in \"%s\"?\n", + cbdata->attr, slapi_entry_get_ndn(e)); + return 0; + } + for (i = slapi_valueset_first_value(values, &value); + i != -1; + i = slapi_valueset_next_value(values, i, &value)) { + /* Pull up the value. */ + cvalue = slapi_value_get_string(value); + if (cvalue == NULL) { + continue; + } + len = strlen(cvalue); + if (len == 0) { + continue; + } + slen = strlen(cbdata->separator); + /* Check if there's space for the value. */ + if (len + (cbdata->count ? slen : 0) > cbdata->outbuf_len) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "referred: out of space\n"); + slapi_vattr_values_free(&values, + &actual_attr, + buffer_flags); + cbdata->ret = -ENOBUFS; + return -1; + } + /* Store the value. */ + if (cbdata->count > 0) { + memcpy(cbdata->outbuf, cbdata->separator, slen); + } + memcpy(cbdata->outbuf + (cbdata->count ? slen : 0), + cvalue, len); + cbdata->outbuf += (len + (cbdata->count ? slen : 0)); + cbdata->outbuf_len -= (len + (cbdata->count ? slen : 0)); + cbdata->count++; + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + return 0; +} +static int +format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, + const char *args, char *outbuf, int outbuf_len, + char ***visited_ndns) +{ + int i, j, len, slen, ret, count, argc; + Slapi_Entry *ref; + Slapi_DN *refdn; + Slapi_ValueSet *ref_values, *values; + Slapi_Value *ref_value, *value; + Slapi_PBlock *local_pb; + int disposition, ref_disposition, buffer_flags, ref_buffer_flags; + char **argv, *attrs[2], *actual_attr, *actual_ref_attr, *filter; + const char *sep, *cvalue, *cref, *map_filter, **map_bases; + struct format_referred_cbdata cbdata; + + ret = format_parse_args(state, args, &argc, &argv); + if (ret != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "referred: error parsing arguments\n"); + return -EINVAL; + } + if (argc < 4) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "referred: requires 4 arguments\n"); + format_free_parsed_args(argv); + return -EINVAL; + } + + /* Build the attribute list. */ + attrs[0] = argv[3]; + attrs[1] = NULL; + + /* Set up to search for matches. */ + local_pb = slapi_pblock_new(); + if (local_pb == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "referred: out of memory\n"); + format_free_parsed_args(argv); + return -ENOMEM; + } + cbdata.state = state; + cbdata.attr = argv[3]; + cbdata.separator = argv[0]; + cbdata.outbuf = outbuf; + cbdata.outbuf_len = outbuf_len; + cbdata.count = 0; + cbdata.ret = 0; + + /* Retrieve the map-specific paramters. */ + map_filter = NULL; + map_bases = NULL; + backend_get_map_config(state, domain, map, &map_bases, &map_filter); + if (map_filter == NULL) { + map_filter = "(objectClass=*)"; + } + + /* Now just search through the entries used for the map. */ + for (i = 0; (map_bases != NULL) && (map_bases[i] != NULL); i++) { + /* Build the search filter. */ + filter = malloc(strlen(map_filter) + strlen(argv[2]) + + strlen(slapi_entry_get_ndn(e)) + 7); + if (filter == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "referred: out of memory\n"); + slapi_pblock_destroy(local_pb); + format_free_parsed_args(argv); + return -ENOMEM; + } + sprintf(filter, "(&(%s=%s)%s)", argv[2], slapi_entry_get_ndn(e), + map_filter); + /* Set up the search. */ + slapi_search_internal_set_pb(local_pb, + map_bases[i], LDAP_SCOPE_SUB, + filter, attrs, FALSE, + NULL, NULL, + state->plugin_identity, 0); + /* Let the callback do the work. */ + slapi_search_internal_callback_pb(local_pb, state, + NULL, + format_referred_entry_cb, + NULL); + free(filter); + /* If the callback left an error code for us, then stop. */ + if (cbdata.ret != 0) { + break; + } + } + + slapi_pblock_destroy(local_pb); + format_free_parsed_args(argv); + return cbdata.ret; +} + /* Evaluate each argument, after the first, in turn, and merge them, using the * first argument as a separator. */ static int format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { @@ -412,7 +582,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Expand this argument. */ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "merge: expanding ->%s<-\n", argv[i]); - len = format_expand(state, pb, e, argv[i], + len = format_expand(state, pb, e, domain, map, argv[i], outbuf + ret + (count ? slen : 0), outbuf_len - (ret + (count ? slen : 0)), visited_ndns, TRUE); @@ -454,6 +624,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, static int format_match_generic(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, int min_args, int default_arg, char *outbuf, int outbuf_len, char ***visited_ndns, @@ -603,10 +774,11 @@ format_match_cb(const char *pattern, const char *value, char **argv) static int format_match(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { - return format_match_generic(state, pb, e, args, 2, 2, + return format_match_generic(state, pb, e, domain, map, args, 2, 2, outbuf, outbuf_len, visited_ndns, "format_match", format_match_cb); } @@ -629,10 +801,11 @@ format_regmatch_cb(const char *pattern, const char *value, char **argv) static int format_regmatch(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { - return format_match_generic(state, pb, e, args, 2, 2, + return format_match_generic(state, pb, e, domain, map, args, 2, 2, outbuf, outbuf_len, visited_ndns, "format_regmatch", format_regmatch_cb); } @@ -748,10 +921,11 @@ format_regsub_cb(const char *pattern, const char *value, char **argv) static int format_regsub(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns) { - return format_match_generic(state, pb, e, args, 3, 3, + return format_match_generic(state, pb, e, domain, map, args, 3, 3, outbuf, outbuf_len, visited_ndns, "format_regsub", format_regsub_cb); } @@ -765,6 +939,7 @@ format_lookup_fn(const char *fnname) const char *name; int (*fct_ptr)(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns); @@ -772,6 +947,7 @@ format_lookup_fn(const char *fnname) {"echo", format_echo}, {"list", format_list}, {"deref", format_deref}, + {"referred", format_referred}, {"merge", format_merge}, {"match", format_match}, {"regmatch", format_regmatch}, @@ -879,7 +1055,7 @@ xstrndupp(const char *start, const char *end) * treat the entire input format specifier as an expression. */ static int format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *fmt, + const char *domain, const char *map, const char *fmt, char *outbuf, int outbuf_len, char ***visited_ndns, bool_t contains_literals) @@ -892,7 +1068,8 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *default_value, *alternate_value, *paramstart, *paramend; size_t spn; int (*formatfn)(struct plugin_state *state, - Slapi_PBlock *pb, Slapi_Entry *e, const char *args, + Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, char ***visited_ndns); spd_id = state->plugin_desc->spd_id; @@ -951,6 +1128,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Recursively expand the * subexpression. */ exp_used = format_expand(state, pb, e, + domain, map, tmp, expr + j, exp_size - j, @@ -1058,9 +1236,9 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return -ENOSYS; } /* Call the "function". */ - exp_used = (*formatfn)(state, pb, e, tmp, - expr + j, - exp_size - j, + exp_used = (*formatfn)(state, pb, e, + domain, map, tmp, + expr + j, exp_size - j, visited_ndns); free(tmp); if (exp_used < 0) { @@ -1188,6 +1366,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, static char * format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *fmt, char ***visited_ndns) { char *buf, *tmp, *ret, *spd_id; @@ -1208,7 +1387,7 @@ format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return NULL; } - i = format_expand(state, pb, e, fmt, buf, buflen, + i = format_expand(state, pb, e, domain, map, fmt, buf, buflen, visited_ndns, TRUE); if ((i >= 0) && (i < buflen)) { buf[i] = '\0'; @@ -1254,6 +1433,7 @@ format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, char * format_get_data(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *domain, const char *map, const char *fmt, char ***visited_ndns) { Slapi_PBlock *local_pb; @@ -1275,7 +1455,7 @@ format_get_data(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, local_pb = NULL; } - ret = format_format(state, pb, e, fmt, ndn_list); + ret = format_format(state, pb, e, domain, map, fmt, ndn_list); /* If we supplied a PBlock, clean it up. */ if (pb == local_pb) { diff --git a/src/format.h b/src/format.h index 8168e26..d59a3a8 100644 --- a/src/format.h +++ b/src/format.h @@ -28,5 +28,6 @@ void format_free_data(char *data); void format_free_ndn_list(char **ndn_list); char *format_get_data(struct plugin_state *state, struct slapi_pblock *pb, struct slapi_entry *e, + const char *domain, const char *map, const char *fmt, char ***visited_ndn_list); #endif |