summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@redhat.com>2012-01-10 13:11:37 -0500
committerNalin Dahyabhai <nalin@redhat.com>2012-01-10 13:11:37 -0500
commit6b99f3803d98db5da6474b567d507a62a8dc9294 (patch)
treeb8a4c26b52fcadec58227d4be3c503df38994396
parentda820c236ab763563d20260defbd70494dd57b55 (diff)
- add and test a "unique" operator
-rw-r--r--src/format.c108
-rwxr-xr-xtests/test35-nis-nested-groups/after.sh8
-rw-r--r--tests/test35-nis-nested-groups/after.txt16
-rwxr-xr-xtests/test35-nis-nested-groups/before.sh8
-rw-r--r--tests/test35-nis-nested-groups/before.txt16
-rwxr-xr-xtests/test35-nis-nested-groups/change.sh15
-rw-r--r--tests/test35-nis-nested-groups/change.txt4
-rw-r--r--tests/test35-nis-nested-groups/description.txt1
-rw-r--r--tests/test35-nis-nested-groups/dse.ldif21
-rw-r--r--tests/test35-nis-nested-groups/plugin-skip-memberof.txt1
-rw-r--r--tests/test35-nis-nested-groups/userRoot.ldif26
-rwxr-xr-xtests/test36-nis-nested-groups/after.sh8
-rw-r--r--tests/test36-nis-nested-groups/after.txt16
-rwxr-xr-xtests/test36-nis-nested-groups/before.sh8
-rw-r--r--tests/test36-nis-nested-groups/before.txt16
-rwxr-xr-xtests/test36-nis-nested-groups/change.sh15
-rw-r--r--tests/test36-nis-nested-groups/change.txt4
-rw-r--r--tests/test36-nis-nested-groups/description.txt1
-rw-r--r--tests/test36-nis-nested-groups/dse.ldif21
-rw-r--r--tests/test36-nis-nested-groups/plugin-skip-memberof.txt1
-rw-r--r--tests/test36-nis-nested-groups/userRoot.ldif26
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
+