diff options
| author | Nalin Dahyabhai <nalin@redhat.com> | 2012-01-10 13:11:37 -0500 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin@redhat.com> | 2012-01-10 13:11:37 -0500 |
| commit | 6b99f3803d98db5da6474b567d507a62a8dc9294 (patch) | |
| tree | b8a4c26b52fcadec58227d4be3c503df38994396 | |
| parent | da820c236ab763563d20260defbd70494dd57b55 (diff) | |
- add and test a "unique" operator
21 files changed, 340 insertions, 0 deletions
diff --git a/src/format.c b/src/format.c index 9871ac6..9c25d4c 100644 --- a/src/format.c +++ b/src/format.c @@ -2900,6 +2900,112 @@ format_link(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return ret; } +/* Eliminate duplicate values from the list. */ +static int +format_unique(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *group, const char *set, + const char *args, const char *disallowed, + char *outbuf, int outbuf_len, + struct format_choice **outbuf_choices, + char ***rel_attrs, + char ***ref_attrs, struct format_inref_attr ***inref_attrs, + struct format_ref_attr_list ***ref_attr_list, + struct format_ref_attr_list ***inref_attr_list) +{ + int ret, i, j, argc; + char **argv, **values; + const char *value_format, *default_value; + unsigned int *lengths; + struct berval **choices, bv; + + ret = format_parse_args(state, args, &argc, &argv); + if (ret != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "unique: error parsing arguments\n"); + return -EINVAL; + } + if (argc < 1) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "unique: error parsing arguments\n"); + format_free_parsed_args(argv); + return -EINVAL; + } + if (argc < 2) { + value_format = argv[0]; + default_value = NULL; + } else { + value_format = argv[0]; + default_value = argv[1]; + } + ret = -ENOENT; + values = format_get_data_set(state, e, group, set, + value_format, disallowed, + rel_attrs, ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list, + &lengths); + if (values == NULL) { + if (default_value == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "unique: no values for ->%s<-, " + "and no default value provided\n", + value_format); + ret = -ENOENT; + } else { + i = format_expand(state, pb, e, + group, set, + default_value, NULL, + outbuf, outbuf_len, + outbuf_choices, + rel_attrs, ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list); + ret = i; + } + } else { + if (values != NULL) { + choices = NULL; + for (i = 0; values[i] != NULL; i++) { + /* XXX this is horribly slow */ + for (j = 0; j < i; j++) { + if ((lengths[i] == lengths[j]) && + (memcmp(values[i], values[j], lengths[i]) == 0)) { + break; + } + } + if (j == i) { + /* Add it to the list. */ + bv.bv_val = values[i]; + bv.bv_len = lengths[i]; + format_add_bv_list(&choices, &bv); + } + } + format_free_data_set(values, lengths); + if (choices != NULL) { + for (i = 0; choices[i] != NULL; i++) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "unique: returning \"%.*s\" as a " + "value for \"%s\"\n", + (int) choices[i]->bv_len, + choices[i]->bv_val, + slapi_entry_get_dn(e)); + continue; + } + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "unique: returning %d values for \"%s\"\n", i, + slapi_entry_get_dn(e)); + format_add_choice(outbuf_choices, outbuf, &choices); + ret = 0; + } else { + ret = -ENOENT; + } + } + } + format_free_parsed_args(argv); + return ret; +} + /* Choose a formatting function by name. */ static void * format_lookup_fn(const char *fnname) @@ -2936,6 +3042,8 @@ format_lookup_fn(const char *fnname) {"ifeq", format_ifeq}, {"collect", format_collect}, {"link", format_link}, + {"unique", format_unique}, + /* {"uuid", format_uuid}, */ }; for (i = 0; i < sizeof(fns) / sizeof(fns[0]); i++) { if ((fns[i].name != NULL) && diff --git a/tests/test35-nis-nested-groups/after.sh b/tests/test35-nis-nested-groups/after.sh new file mode 100755 index 0000000..27afbdf --- /dev/null +++ b/tests/test35-nis-nested-groups/after.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo map list: +$YP maplist example.com +$YP -c maplist example.com +for map in `$YP maplist example.com` ; do + echo contents of example.com:"$map": + $YP cat example.com $map +done diff --git a/tests/test35-nis-nested-groups/after.txt b/tests/test35-nis-nested-groups/after.txt new file mode 100644 index 0000000..dea7719 --- /dev/null +++ b/tests/test35-nis-nested-groups/after.txt @@ -0,0 +1,16 @@ +map list: +test +users +test +users +contents of example.com:test: +group1 user2a,user2a +group2 group1-fake-uid,user2b,user2a,group1-fake-uid,user2b,user2a +contents of example.com:users: +user1 user1:user1 +user1a user1a:User 1 A +user1b user1b:User 1 B +user1c user1c:User 1 C +user2a user2a:User 2 A +user2b user2b:User 2 B +user2c user2c:User 2 C diff --git a/tests/test35-nis-nested-groups/before.sh b/tests/test35-nis-nested-groups/before.sh new file mode 100755 index 0000000..27afbdf --- /dev/null +++ b/tests/test35-nis-nested-groups/before.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo map list: +$YP maplist example.com +$YP -c maplist example.com +for map in `$YP maplist example.com` ; do + echo contents of example.com:"$map": + $YP cat example.com $map +done diff --git a/tests/test35-nis-nested-groups/before.txt b/tests/test35-nis-nested-groups/before.txt new file mode 100644 index 0000000..e9fc0f6 --- /dev/null +++ b/tests/test35-nis-nested-groups/before.txt @@ -0,0 +1,16 @@ +map list: +test +users +test +users +contents of example.com:test: +group1 +group2 group1-fake-uid,group1-fake-uid +contents of example.com:users: +user1 user1:user1 +user1a user1a:User 1 A +user1b user1b:User 1 B +user1c user1c:User 1 C +user2a user2a:User 2 A +user2b user2b:User 2 B +user2c user2c:User 2 C diff --git a/tests/test35-nis-nested-groups/change.sh b/tests/test35-nis-nested-groups/change.sh new file mode 100755 index 0000000..d170da8 --- /dev/null +++ b/tests/test35-nis-nested-groups/change.sh @@ -0,0 +1,15 @@ +#!/bin/sh +modify << EOF +dn: cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com +changetype: modify +add: member +member: uid=user2a, cn=Users2, cn=Accounts, dc=example, dc=com +- + +dn: cn=group2, cn=Groups1, cn=Accounts, dc=example, dc=com +changetype: modify +add: member +member: uid=user2b, cn=Users2, cn=Accounts, dc=example, dc=com +- + +EOF diff --git a/tests/test35-nis-nested-groups/change.txt b/tests/test35-nis-nested-groups/change.txt new file mode 100644 index 0000000..aefc0f1 --- /dev/null +++ b/tests/test35-nis-nested-groups/change.txt @@ -0,0 +1,4 @@ +modifying entry "cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com" + +modifying entry "cn=group2, cn=Groups1, cn=Accounts, dc=example, dc=com" + diff --git a/tests/test35-nis-nested-groups/description.txt b/tests/test35-nis-nested-groups/description.txt new file mode 100644 index 0000000..36f7ff5 --- /dev/null +++ b/tests/test35-nis-nested-groups/description.txt @@ -0,0 +1 @@ +nested group memberships (group->member) not unique diff --git a/tests/test35-nis-nested-groups/dse.ldif b/tests/test35-nis-nested-groups/dse.ldif new file mode 100644 index 0000000..c5a3e3b --- /dev/null +++ b/tests/test35-nis-nested-groups/dse.ldif @@ -0,0 +1,21 @@ +dn: nis-domain=example.com+nis-map=users,cn=NIS Server,cn=plugins,cn=config +objectClass: top +objectClass: extensibleObject +nis-domain: example.com +nis-map: users +nis-base: cn=Users1, cn=Accounts, dc=example, dc=com +nis-base: cn=Users2, cn=Accounts, dc=example, dc=com +nis-filter: objectclass=posixAccount +nis-keys-format: %{uid} +nis-value-format: %{uid}:%{cn} + +dn: nis-domain=example.com+nis-map=test,cn=NIS Server,cn=plugins,cn=config +objectClass: top +objectClass: extensibleObject +nis-domain: example.com +nis-map: test +nis-base: cn=Groups1, cn=Accounts, dc=example, dc=com +nis-filter: objectclass=posixgroup +nis-keys-format: %{cn} +nis-value-format: %merge(",","%deref_r(\"member\",\"uid\")","%referred_r(\"users\",\"memberOf\",\"uid\")","%deref_r(\"member\",\"uid\")","%referred_r(\"users\",\"memberOf\",\"uid\")") + diff --git a/tests/test35-nis-nested-groups/plugin-skip-memberof.txt b/tests/test35-nis-nested-groups/plugin-skip-memberof.txt new file mode 100644 index 0000000..adbe54f --- /dev/null +++ b/tests/test35-nis-nested-groups/plugin-skip-memberof.txt @@ -0,0 +1 @@ +skip memberof diff --git a/tests/test35-nis-nested-groups/userRoot.ldif b/tests/test35-nis-nested-groups/userRoot.ldif new file mode 100644 index 0000000..7aa1110 --- /dev/null +++ b/tests/test35-nis-nested-groups/userRoot.ldif @@ -0,0 +1,26 @@ +dn: uid=user1, cn=Users1, cn=Accounts, dc=example, dc=com +objectClass: posixAccount +objectClass: inetUser +cn: user1 +uid: user1 +uidNumber: 1001 +gidNumber: 1001 +gecos: User +loginShell: /bin/bash +homeDirectory: /home/user + +dn: cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com +objectClass: posixgroup +objectClass: extensibleObject +cn: group1 +uid: group1-fake-uid +gidNumber: 1002 + +dn: cn=group2, cn=Groups1, cn=Accounts, dc=example, dc=com +objectClass: posixgroup +objectClass: extensibleObject +cn: group2 +uid: group2-fake-uid +gidNumber: 1003 +member: cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com + diff --git a/tests/test36-nis-nested-groups/after.sh b/tests/test36-nis-nested-groups/after.sh new file mode 100755 index 0000000..27afbdf --- /dev/null +++ b/tests/test36-nis-nested-groups/after.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo map list: +$YP maplist example.com +$YP -c maplist example.com +for map in `$YP maplist example.com` ; do + echo contents of example.com:"$map": + $YP cat example.com $map +done diff --git a/tests/test36-nis-nested-groups/after.txt b/tests/test36-nis-nested-groups/after.txt new file mode 100644 index 0000000..d6a143c --- /dev/null +++ b/tests/test36-nis-nested-groups/after.txt @@ -0,0 +1,16 @@ +map list: +test +users +test +users +contents of example.com:test: +group1 user2a +group2 group1-fake-uid,user2b,user2a +contents of example.com:users: +user1 user1:user1 +user1a user1a:User 1 A +user1b user1b:User 1 B +user1c user1c:User 1 C +user2a user2a:User 2 A +user2b user2b:User 2 B +user2c user2c:User 2 C diff --git a/tests/test36-nis-nested-groups/before.sh b/tests/test36-nis-nested-groups/before.sh new file mode 100755 index 0000000..27afbdf --- /dev/null +++ b/tests/test36-nis-nested-groups/before.sh @@ -0,0 +1,8 @@ +#!/bin/sh +echo map list: +$YP maplist example.com +$YP -c maplist example.com +for map in `$YP maplist example.com` ; do + echo contents of example.com:"$map": + $YP cat example.com $map +done diff --git a/tests/test36-nis-nested-groups/before.txt b/tests/test36-nis-nested-groups/before.txt new file mode 100644 index 0000000..1c55f39 --- /dev/null +++ b/tests/test36-nis-nested-groups/before.txt @@ -0,0 +1,16 @@ +map list: +test +users +test +users +contents of example.com:test: +group1 +group2 group1-fake-uid +contents of example.com:users: +user1 user1:user1 +user1a user1a:User 1 A +user1b user1b:User 1 B +user1c user1c:User 1 C +user2a user2a:User 2 A +user2b user2b:User 2 B +user2c user2c:User 2 C diff --git a/tests/test36-nis-nested-groups/change.sh b/tests/test36-nis-nested-groups/change.sh new file mode 100755 index 0000000..d170da8 --- /dev/null +++ b/tests/test36-nis-nested-groups/change.sh @@ -0,0 +1,15 @@ +#!/bin/sh +modify << EOF +dn: cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com +changetype: modify +add: member +member: uid=user2a, cn=Users2, cn=Accounts, dc=example, dc=com +- + +dn: cn=group2, cn=Groups1, cn=Accounts, dc=example, dc=com +changetype: modify +add: member +member: uid=user2b, cn=Users2, cn=Accounts, dc=example, dc=com +- + +EOF diff --git a/tests/test36-nis-nested-groups/change.txt b/tests/test36-nis-nested-groups/change.txt new file mode 100644 index 0000000..aefc0f1 --- /dev/null +++ b/tests/test36-nis-nested-groups/change.txt @@ -0,0 +1,4 @@ +modifying entry "cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com" + +modifying entry "cn=group2, cn=Groups1, cn=Accounts, dc=example, dc=com" + diff --git a/tests/test36-nis-nested-groups/description.txt b/tests/test36-nis-nested-groups/description.txt new file mode 100644 index 0000000..93cb64f --- /dev/null +++ b/tests/test36-nis-nested-groups/description.txt @@ -0,0 +1 @@ +nested group memberships (group->member) unique diff --git a/tests/test36-nis-nested-groups/dse.ldif b/tests/test36-nis-nested-groups/dse.ldif new file mode 100644 index 0000000..94b27e5 --- /dev/null +++ b/tests/test36-nis-nested-groups/dse.ldif @@ -0,0 +1,21 @@ +dn: nis-domain=example.com+nis-map=users,cn=NIS Server,cn=plugins,cn=config +objectClass: top +objectClass: extensibleObject +nis-domain: example.com +nis-map: users +nis-base: cn=Users1, cn=Accounts, dc=example, dc=com +nis-base: cn=Users2, cn=Accounts, dc=example, dc=com +nis-filter: objectclass=posixAccount +nis-keys-format: %{uid} +nis-value-format: %{uid}:%{cn} + +dn: nis-domain=example.com+nis-map=test,cn=NIS Server,cn=plugins,cn=config +objectClass: top +objectClass: extensibleObject +nis-domain: example.com +nis-map: test +nis-base: cn=Groups1, cn=Accounts, dc=example, dc=com +nis-filter: objectclass=posixgroup +nis-keys-format: %{cn} +nis-value-format: %merge(",","%unique(\"%deref_r(\\\"member\\\",\\\"uid\\\")\",\"%referred_r(\\\"users\\\",\\\"memberOf\\\",\\\"uid\\\")\",\"%deref_r(\\\"member\\\",\\\"uid\\\")\",\"%referred_r(\\\"users\\\",\\\"memberOf\\\",\\\"uid\\\")\")") + diff --git a/tests/test36-nis-nested-groups/plugin-skip-memberof.txt b/tests/test36-nis-nested-groups/plugin-skip-memberof.txt new file mode 100644 index 0000000..adbe54f --- /dev/null +++ b/tests/test36-nis-nested-groups/plugin-skip-memberof.txt @@ -0,0 +1 @@ +skip memberof diff --git a/tests/test36-nis-nested-groups/userRoot.ldif b/tests/test36-nis-nested-groups/userRoot.ldif new file mode 100644 index 0000000..7aa1110 --- /dev/null +++ b/tests/test36-nis-nested-groups/userRoot.ldif @@ -0,0 +1,26 @@ +dn: uid=user1, cn=Users1, cn=Accounts, dc=example, dc=com +objectClass: posixAccount +objectClass: inetUser +cn: user1 +uid: user1 +uidNumber: 1001 +gidNumber: 1001 +gecos: User +loginShell: /bin/bash +homeDirectory: /home/user + +dn: cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com +objectClass: posixgroup +objectClass: extensibleObject +cn: group1 +uid: group1-fake-uid +gidNumber: 1002 + +dn: cn=group2, cn=Groups1, cn=Accounts, dc=example, dc=com +objectClass: posixgroup +objectClass: extensibleObject +cn: group2 +uid: group2-fake-uid +gidNumber: 1003 +member: cn=group1, cn=Groups1, cn=Accounts, dc=example, dc=com + |
