summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2012-03-28 18:11:28 -0400
committerNalin Dahyabhai <nalin@dahyabhai.net>2012-03-28 18:11:28 -0400
commitb0c7b3bfe85fdda5fe15a1e39e2c3c99e6352bb8 (patch)
tree5093d589bf98f0e76ed2a5f09c9face572839cc3
parent6d78b63916f725300472b28c3c7b283afc72ac2e (diff)
- add a "default" function
-rw-r--r--NEWS1
-rw-r--r--doc/format-specifiers.txt23
-rw-r--r--src/format.c50
-rwxr-xr-xtests/test32-schema-default/before.sh3
-rw-r--r--tests/test32-schema-default/before.txt6
-rw-r--r--tests/test32-schema-default/description.txt1
-rw-r--r--tests/test32-schema-default/dse.ldif12
-rw-r--r--tests/test32-schema-default/userRoot.ldif59
8 files changed, 155 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index b470f0d..0073ae1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
0.39 * Populate the entryUSN value in entries with either the value from
the source entry or the root DSE.
+ * Add a default function (part of #767372).
0.38 * Properly escape RDN values when building compat entries (#796509).
0.37 * Fix a compile error on systems which don't define
LDAP_SCOPE_SUBORDINATE, reported by Christian Neuhold.
diff --git a/doc/format-specifiers.txt b/doc/format-specifiers.txt
index 91c7b9c..f37ce9a 100644
--- a/doc/format-specifiers.txt
+++ b/doc/format-specifiers.txt
@@ -598,3 +598,26 @@ Here's an example entry:
And here's how an example expression evaluates for ''cn=group'':
%ifeq("member","jim","","%{membername}") -> (jim)
+
+=== default ===
+
+ default(''EXPRESSION1'',''EXPRESSION2''[,...])
+
+Evaluates ''EXPRESSION1'', returning its values if any are produced. If no
+result is produced, evaluates ''EXPRESSION2'', returning its values if any are
+produced. Keeps trying successive expressions until it gets results or runs
+out of expressions.
+
+Here's an example entry:
+
+ dn: cn=group
+ cn: group
+ membername: jim
+ member: uid=bob
+ member: uid=pete
+
+And here's how an example expression evaluates for ''cn=group'':
+
+ %default("%{member}","jim") -> (uid=bob,uid=pete)
+ %default("%{membername}","bob") -> (jim)
+ %default("%{nosuchvalue}","bob") -> (bob)
diff --git a/src/format.c b/src/format.c
index 2d18da7..aed71f1 100644
--- a/src/format.c
+++ b/src/format.c
@@ -2703,6 +2703,55 @@ format_ifeq(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return ret;
}
+/* If the expression given as the first argument returns any values, return
+ * them. Otherwise, return the second expression. */
+static int
+format_default(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, argc, i;
+ unsigned int *lengths;
+ char **argv, **values;
+ bool_t first;
+ struct berval bv, **choices;
+
+ ret = format_parse_args(state, args, &argc, &argv);
+ if (ret != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "default: error parsing arguments\n");
+ return -EINVAL;
+ }
+ if (argc < 2) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "default: expected at least two arguments "
+ "(got %d)\n",
+ argc);
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
+ /* Evaluate expressions until we run out of them or succeed. */
+ for (i = 0; i < argc; i++) {
+ ret = format_expand(state, pb, e, group, set,
+ argv[i], disallowed,
+ outbuf, outbuf_len,
+ outbuf_choices,
+ rel_attrs, ref_attrs, inref_attrs,
+ ref_attr_list, inref_attr_list);
+ if (ret >= 0) {
+ break;
+ }
+ }
+ format_free_parsed_args(argv);
+ return ret;
+}
+
/* Evaluate all of the arguments, and concatentate all of the lists of results
* to produce one long list. */
static int
@@ -3200,6 +3249,7 @@ format_lookup_fn(const char *fnname)
{"mregsub", format_mregsub},
{"mregsubi", format_mregsubi},
{"ifeq", format_ifeq},
+ {"default", format_default},
{"collect", format_collect},
{"link", format_link},
{"unique", format_unique},
diff --git a/tests/test32-schema-default/before.sh b/tests/test32-schema-default/before.sh
new file mode 100755
index 0000000..5b96cb0
--- /dev/null
+++ b/tests/test32-schema-default/before.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+search -b cn=compat,cn=accounts,dc=example,dc=com dn |\
+grep ^dn: | env LANG=C sort
diff --git a/tests/test32-schema-default/before.txt b/tests/test32-schema-default/before.txt
new file mode 100644
index 0000000..0f4713f
--- /dev/null
+++ b/tests/test32-schema-default/before.txt
@@ -0,0 +1,6 @@
+dn: cn=(unset),cn=users,cn=compat,cn=accounts,dc=example,dc=com
+dn: cn=BINGO,cn=users,cn=compat,cn=accounts,dc=example,dc=com
+dn: cn=Tim User,cn=users,cn=compat,cn=accounts,dc=example,dc=com
+dn: cn=compat,cn=accounts,dc=example,dc=com
+dn: cn=users,cn=compat,cn=accounts,dc=example,dc=com
+dn: uid=tuser2,cn=users,cn=compat,cn=accounts,dc=example,dc=com
diff --git a/tests/test32-schema-default/description.txt b/tests/test32-schema-default/description.txt
new file mode 100644
index 0000000..4ad96d5
--- /dev/null
+++ b/tests/test32-schema-default/description.txt
@@ -0,0 +1 @@
+default
diff --git a/tests/test32-schema-default/dse.ldif b/tests/test32-schema-default/dse.ldif
new file mode 100644
index 0000000..c727767
--- /dev/null
+++ b/tests/test32-schema-default/dse.ldif
@@ -0,0 +1,12 @@
+dn: cn=compat-passwd,cn=Schema Compatibility,cn=plugins,cn=config
+objectClass: top
+objectClass: extensibleObject
+cn: compat-passwd
+schema-compat-container-group: cn=compat,cn=Accounts,dc=example,dc=com
+schema-compat-container-rdn: cn=Users
+schema-compat-check-access: yes
+schema-compat-search-base: cn=Users,cn=Accounts,dc=example,dc=com
+schema-compat-search-filter: (|(objectClass=extensibleObject)(objectClass=posixAccount))
+schema-compat-entry-rdn: %default("%ifeq(\"uid\",\"tuser3\",\"cn=BINGO\",\"%{nosuchattribute}\")","cn=%{gecos}","uid=%{uid}","cn=(unset)")
+schema-compat-entry-attribute: objectclass=extensibleobject
+
diff --git a/tests/test32-schema-default/userRoot.ldif b/tests/test32-schema-default/userRoot.ldif
new file mode 100644
index 0000000..7e5bc1c
--- /dev/null
+++ b/tests/test32-schema-default/userRoot.ldif
@@ -0,0 +1,59 @@
+# users, accounts, example.com
+dn: cn=users,cn=accounts,dc=example,dc=com
+objectClass: top
+objectClass: nsContainer
+cn: users
+
+# tuser1, users, accounts, example.com
+dn: uid=tuser1,cn=users,cn=accounts,dc=example,dc=com
+uid: tuser1
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: inetUser
+loginShell: /bin/sh
+gidNumber: 1003
+gecos: Tim User
+sn: User
+homeDirectory: /home/tuser1
+cn: Tim User
+uidNumber: 1101
+description: __no_upg__
+
+# tuser2, users, accounts, example.com
+dn: uid=tuser2,cn=users,cn=accounts,dc=example,dc=com
+uid: tuser2
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: inetUser
+loginShell: /bin/sh
+gidNumber: 1004
+sn: User
+homeDirectory: /home/tuser2
+cn: Timmy User
+uidNumber: 1102
+description: __no_upg__
+
+# tuser3, users, accounts, example.com
+dn: uid=tuser3,cn=users,cn=accounts,dc=example,dc=com
+uid: tuser3
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: inetUser
+loginShell: /bin/sh
+gidNumber: 1004
+sn: User
+homeDirectory: /home/tuser2
+gecos: Timmy User
+cn: Timmy User
+uidNumber: 1102
+description: __no_upg__
+
+# tuser4, users, accounts, example.com
+dn: sn=User,cn=users,cn=accounts,dc=example,dc=com
+objectClass: extensibleObject
+sn: User
+description: __no_upg__
+