aboutsummaryrefslogtreecommitdiffstats
path: root/ldap/test-user-acl.sh
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-08-20 01:53:16 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-08-20 01:53:16 +0200
commitded29bf9eb3fa40c56eb9ace365d13e6348e215c (patch)
tree328d4a3fc3b9fd5e9d696df601bb193204565d8f /ldap/test-user-acl.sh
parentd7173895fa7c31b033c2bffd2fb43d1ffbe2159b (diff)
A little test suite for LDAP ACLs.
Diffstat (limited to 'ldap/test-user-acl.sh')
-rwxr-xr-xldap/test-user-acl.sh906
1 files changed, 906 insertions, 0 deletions
diff --git a/ldap/test-user-acl.sh b/ldap/test-user-acl.sh
new file mode 100755
index 0000000..4b233ef
--- /dev/null
+++ b/ldap/test-user-acl.sh
@@ -0,0 +1,906 @@
+#!/bin/sh
+
+# This a test suite for the user ACLs.
+# *Every* modification to the schema and/or to the ACLs should be made
+# here too! It is crucial that the test suite doesn't break.
+#
+# Requires a populated database with every possible test case, like
+# `populate.ldif'.
+# The database remains unchanged, but slapacl needs to have read access,
+# so the test suite may have to be run by root.
+
+
+SLAPACL=/usr/sbin/slapacl
+SUFFIX="ou=virtual,o=mailHosting,dc=fripost,dc=dev"
+
+RES=$(tempfile) || exit 1
+
+checkACL () {
+ CMD=${SLAPACL}
+ BIND="${1},${SUFFIX}"
+ if [ -n "${1}" ]; then CMD="${CMD} -D ${BIND}"; fi
+ if [ -n "${2}" ]; then BASE="${2},${SUFFIX}"; else BASE="${SUFFIX}"; fi
+ shift; shift
+
+ ${CMD} -b "${BASE}" "$@" 2>&1 | grep -vixF -e "authcDN: \"${BIND}\""
+ N=1
+}
+
+msg () {
+ /bin/echo -n " "
+ /bin/echo -n "$@"
+ /bin/echo -n "... "
+}
+
+isOK () {
+ # Ensures that every line in "$RES" satisfies the regexp "$1".
+ # The total count is the number of "$2" attributes, or the number of lines in "$RES".
+ [ -n "${1}" ] || exit 1
+ cat > "${RES}"
+ if [ -n "${2}" ]; then
+ if [ -n "${3}" ]; then
+ TOT=$(grep -Pic "^${3} access to ${2}: " < "${RES}")
+ else
+ TOT=$(grep -Pic "^((write|add|delete|read|search|compare|auth|disclose) access to )?${2}: " < "${RES}")
+ fi
+ else
+ TOT=$(wc -l < "${RES}")
+ fi
+ FAILS=$(grep -vc "${1}" < "${RES}")
+ if [ ${FAILS} -eq 0 ]; then
+ /bin/echo -n "OK"
+ else
+ echo "Fail! (x${FAILS})"; exit 1
+ fi
+ /bin/echo -n " (${TOT}/${TOT})"
+ echo
+ # We need a complete test suite
+ ([ -n "${TOT}" ] && [ ${TOT} -ne 0 ]) || (echo "Add more test data."; exit 1)
+}
+
+search () {
+ ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:// "$@"
+}
+
+
+########################################################################
+
+
+DOMAINS=$(search -u -b "${SUFFIX}" "objectClass=FripostVirtualDomain" dn | \
+ grep -i '^ufn: ' | sed -re 's/^ufn: ([^,]+),.*/fvd=\1/')
+USERS=$(search -u -b "${SUFFIX}" "objectClass=FripostVirtualMailbox" dn | \
+ grep -i '^ufn: ' | sed -re 's/^ufn: ([^,]+), *([^,]+),.*/fvu=\1,fvd=\2/')
+ALIASES=$(search -u -b "${SUFFIX}" "objectClass=FripostVirtualAlias" dn | \
+ grep -i '^ufn: ' | sed -re 's/^ufn: ([^,]+), *([^,]+),.*/fva=\1,fvd=\2/')
+MLS=$(search -u -b "${SUFFIX}" "objectClass=FripostVirtualML" dn | \
+ grep -i '^ufn: ' | sed -re 's/^ufn: ([^,]+), *([^,]+),.*/fvml=\1,fvd=\2/')
+
+
+########################################################################
+
+
+echo "Anonymous users:"
+
+
+# Anonymous need to bind to any fvu
+msg "Have =xd access to \"userPassword\" attributes"
+for U in ${USERS}; do
+ checkACL "" "${U}" userPassword
+done | isOK 'auth(=xd)$'
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to the rest of user entries"
+for U in ${USERS}; do
+ checkACL "" "${U}"
+done | grep -v '^userPassword=.*: auth(=xd)$' | isOK '=0$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to alias entries"
+for A in ${ALIASES}; do
+ checkACL "" "${A}"
+done | isOK '=0' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to mailing lists entries"
+for ML in ${MLS}; do
+ checkACL "" "${ML}"
+done | isOK '=0' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to domain entries"
+for D in ${DOMAINS}; do
+ checkACL "" "${D}"
+done | isOK '=0' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to the base"
+checkACL "" "" | isOK '=0' entry
+[ $? -eq 0 ] || exit $?
+
+
+###########################################################################
+
+
+echo
+echo "Authenticated users, access to the base"
+
+
+usersB () {
+ for U in ${USERS}; do
+ checkACL "${U}" "" "$@"
+ done
+}
+
+
+msg "Have =s access on the base's \"entry\" attribute"
+usersB entry | isOK '=s' entry
+[ $? -eq 0 ] || exit $?
+
+
+# Needed to delete domains. They cannot create domains though, as they
+# would need =a on the "children" attribute.
+msg "Have =z access on the base's \"children\" attribute"
+usersB children | isOK '=z$' children
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to the operational attributes"
+usersB structuralObjectClass entryUUID createTimestamp entryCSN modifiersName modifyTimestamp | isOK '=0$' entryUUID
+[ $? -eq 0 ] || exit $?
+
+
+###########################################################################
+
+
+echo
+echo "Authenticated users, access to domain entries"
+
+# * entry:
+# =s-a for all
+# +rd if children, canCreate{Alias,ML}, owner or postmaster
+# +z if owner or postmaster
+# * children:
+# =w for all
+# * fvd:
+# =rscd if children, canCreate{Alias,ML}, owner or postmaster
+# +w if owner or postmaster
+# * fripostIsStatusActive
+# =rscd if children, canCreate{Alias,ML}, owner or postmaster
+# +w if owner or postmaster
+# * fripostCanCreateAlias
+# =rscd if canCreateAlias, owner or postmaster
+# +w if postmaster
+# * fripostCanCreateML
+# =rscd if canCreateML, owner or postmaster
+# +w if postmaster
+# * fripostOwner
+# =s for all
+# +d if children
+# +rc if canCreate{Alias,ML}, owner or postmaster
+# * fripostPostmaster
+# =s for all
+# +d if children
+# +rc if canCreate{Alias,ML}, owner or postmaster
+# * fripostMaildrop
+# =wrscd if owner or postmaster
+# * description
+# =rscd if children, canCreate{Alias,ML}, owner or postmaster
+# +w if owner or postmaster
+
+usersD () {
+ for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ checkACL "${U}" "${D}" "$@"
+ done
+ done
+}
+
+msg "Cannot appoint domain Owners or Postmasters; Cannot add a domain"
+usersD fripostOwner/add fripostOwner/delete \
+ fripostPostmaster/add fripostPostmaster/delete \
+ entry/add \
+ | isOK 'DENIED$' entry
+[ $? -eq 0 ] || exit $?
+
+# We ensure not to give +a/+z access to the \"entry\" attribute of the
+# children, unless justified (required to add/delete a child).
+msg "Have =w access to \"children\""
+usersD children | isOK '=w$' children
+[ $? -eq 0 ] || exit $?
+
+msg "Have >=s access on \"entry\", \"fripostOwner\" and \"fripostPostmaster\""
+usersD entry/search fripostOwner/search fripostPostmaster/search | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+msg "Have =0 access to the operational attributes"
+usersD structuralObjectClass entryUUID createTimestamp entryCSN modifiersName modifyTimestamp | isOK '=0$' entryUUID
+[ $? -eq 0 ] || exit $?
+
+
+# We check the following permissions:
+# 0. Simple user
+# 1. canCreateAlias (exact,wildcard)
+# 2. canCreateML (exact,wildcard)
+# 3. Owner
+# 4. Postmaster
+
+# 0
+ATTRS0="entry/read entry/disclose
+ fvd/read fvd/search fvd/compare fvd/disclose
+ fripostIsStatusActive/read fripostIsStatusActive/search fripostIsStatusActive/compare fripostIsStatusActive/disclose
+ fripostOwner/disclose
+ fripostPostmaster/disclose
+ description/read description/search description/compare description/disclose"
+msg "Have >=rscd access to the public attributes of their parent"
+for U in ${USERS}; do
+ D="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ checkACL "${U}" "${D}" ${ATTRS0}
+done | isOK 'ALLOWED$' entry read
+[ $? -eq 0 ] || exit $?
+
+
+# 1
+ATTRSA="fripostOwner/read fripostOwner/compare
+ fripostPostmaster/read fripostPostmaster/compare
+ fripostCanCreateAlias/read fripostCanCreateAlias/search fripostCanCreateAlias/compare fripostCanCreateAlias/disclose"
+msg "Have >=rscd access to the public attributes and >=a to \"children\" (if CanCreateAlias, exact)"
+for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostCanCreateAlias=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${D}" children/add ${ATTRS0} ${ATTRSA}
+ done
+done | isOK 'ALLOWED$' children
+[ $? -eq 0 ] || exit $?
+
+
+# 1
+msg "Have >=rscd to the public attributes and >=a to \"children\" (if CanCreateAlias, wildcard)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostCanCreateAlias=${DU},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${D}" children/add ${ATTRS0} ${ATTRSA}
+ done
+done | isOK 'ALLOWED$' children
+[ $? -eq 0 ] || exit $?
+
+
+# 2
+ATTRSML="fripostOwner/read fripostOwner/compare
+ fripostPostmaster/read fripostPostmaster/compare
+ fripostCanCreateML/read fripostCanCreateML/search fripostCanCreateML/compare fripostCanCreateML/disclose"
+msg "Have >=rscd access to the public attributes and >=a to \"children\" (if CanCreateML, exact)"
+for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostCanCreateML=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${D}" children/add ${ATTRS0} ${ATTRSML}
+ done
+done | isOK 'ALLOWED$' children
+[ $? -eq 0 ] || exit $?
+
+
+# 2
+msg "Have >=rscd access to the public attributes and >=a to \"children\" (if CanCreateML, wildcard)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostCanCreateML=${DU},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${D}" children/add ${ATTRS0} ${ATTRSML}
+ done
+done | isOK 'ALLOWED$' children
+[ $? -eq 0 ] || exit $?
+
+
+# 3
+# >=w to "children", =zrscd to "entry", >=rscd to "fripostCanCreateAlias" and
+# "fripostCanCreateML", and =wrscd to the rest (other than "Owner" and
+# Postmaster")
+msg "Have =wrscd to the domain attributes (other than \"canCreate\"), and >=w to \"children\" (if Owner)"
+ATTRSO="entry/delete
+ fvd/write
+ fripostIsStatusActive/write
+ fripostMaildrop/delete fripostMaildrop/add fripostMaildrop/read fripostMaildrop/search fripostMaildrop/compare fripostMaildrop/disclose
+ description/add description/delete"
+for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${D}" children/write ${ATTRS0} ${ATTRSA} ${ATTRSML} ${ATTRSO}
+ done
+done | isOK 'ALLOWED$' children
+[ $? -eq 0 ] || exit $?
+
+
+# 4
+# >=w to "children", =zrscd to "entry", >=rscd to "fripostCanCreateAlias" and
+# "fripostCanCreateML", and =wrscd to the rest (other than "Owner" and
+# Postmaster")
+msg "Have =wrscd to the domain attributes, and >=w to \"children\" (if Postmaster)"
+ATTRSP="fripostCanCreateAlias/add fripostCanCreateAlias/delete
+ fripostCanCreateML/add fripostCanCreateML/delete"
+for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostPostmaster=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${D}" children/write ${ATTRS0} ${ATTRSA} ${ATTRSML} ${ATTRSO} ${ATTRSP}
+ done
+done | isOK 'ALLOWED$' children
+[ $? -eq 0 ] || exit $?
+
+
+# not (0 or 1 or 2 or 3 or 4)
+msg "Have no access to the public attributes of irrelevant domains"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for D in ${DOMAINS}; do
+ [ "x${DU}" = "x${D}" ] || \
+ search -s base -b "${D},${SUFFIX}" "(|(fripostCanCreateAlias=${U},${SUFFIX})
+ (fripostCanCreateAlias=${DU},${SUFFIX})
+ (fripostCanCreateML=${U},${SUFFIX})
+ (fripostCanCreateML=${DU},${SUFFIX})
+ (fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${D}" ${ATTRS0}
+ done
+done | isOK 'DENIED$' entry read
+[ $? -eq 0 ] || exit $?
+
+
+# not (1 or 2 or 3 or 4)
+msg "Do not have >=rc access to \"canCreate{Alias,ML}\", \"Owner\", \"Postmaster\" (unless member)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "(|(fripostCanCreateAlias=${U},${SUFFIX})
+ (fripostCanCreateAlias=${DU},${SUFFIX})
+ (fripostCanCreateML=${U},${SUFFIX})
+ (fripostCanCreateML=${DU},${SUFFIX})
+ (fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${D}" ${ATTRSA} ${ATTRSML} entry/add
+ done
+done | isOK 'DENIED$' entry # "entry" here is useless, but it's just to get the count
+[ $? -eq 0 ] || exit $?
+
+
+# not (1 or 3 or 4)
+msg "Have =0 access to \"canCreateAlias\" (unless member, Owner, or Postmaster)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "(|(fripostCanCreateAlias=${U},${SUFFIX})
+ (fripostCanCreateAlias=${DU},${SUFFIX})
+ (fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${D}" fripostCanCreateAlias entry/add
+ done
+done | isOK '\(=0\|DENIED\)$' entry # "entry" here is useless, but it's just to get the count
+[ $? -eq 0 ] || exit $?
+
+
+# not (2 or 3 or 4)
+msg "Have =0 access to \"canCreateML\" (unless member, Owner, or Postmaster)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "(|(fripostCanCreateML=${U},${SUFFIX})
+ (fripostCanCreateML=${DU},${SUFFIX})
+ (fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${D}" fripostCanCreateML entry/add
+ done
+done | isOK '\(=0\|DENIED\)$' entry # "entry" here is useless, but it's just to get the count
+[ $? -eq 0 ] || exit $?
+
+
+# not (3 or 4)
+msg "Have =0 access to \"fripostMaildrop\" (unless Owner or Postmaster)"
+for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "(|(fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${D}" ${ATTRSO}
+ done
+done | isOK 'DENIED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+# not 4
+msg "Do not have >=w access to \"canCreate{Alias,ML}\" (unless Postmaster)"
+for U in ${USERS}; do
+ for D in ${DOMAINS}; do
+ search -s base -b "${D},${SUFFIX}" "fripostPostmaster=${U},${SUFFIX}" | grep -q '^dn: ' || \
+ checkACL "${U}" "${D}" ${ATTRSP} entry/add
+ done
+done | isOK 'DENIED$' entry # "entry" here is useless, but it's just to get the count
+[ $? -eq 0 ] || exit $?
+
+
+
+###########################################################################
+
+
+echo
+echo "Authenticated users, access to user entries"
+
+# * entry:
+# =rsd if account owner
+# +a if domain postmaster
+# * children:
+# =0 for all
+# * fvu:
+# =wrscd if account owner or domain postmaster
+# * userPassword:
+# =w if account owner or domain postmaster
+# * fripostIsStatusActive:
+# =wrscd if account owner or domain postmaster
+# * fripostMailboxQuota:
+# =rscd if account owner or domain postmaster
+# * fripostMaildrop:
+# =wrscd if account owner or domain postmaster
+# * cn:
+# =wrscd if account owner or domain postmaster
+# * description:
+# =wrscd if account owner or domain postmaster
+
+usersU () {
+ for U in ${USERS}; do
+ checkACL "${U}" "${U}" "$@"
+ done
+}
+
+# They would need write access to their fripostMailboxQuota.
+# In practice they can't write fvu either, since it's single valued.
+msg "Have =rscxd access to their \"fripostMailboxQuota\""
+usersU fripostMailboxQuota | isOK 'read(=rscxd)$'
+[ $? -eq 0 ] || exit $?
+
+msg "Have =wd access to their own \"userPassword\""
+usersU userPassword | isOK '=w$'
+[ $? -eq 0 ] || exit $?
+
+msg "Have =wrscxd access to the other attributes of their own entry"
+usersU fvu fripostIsStatusActive fripostMaildrop cn description | isOK 'write(=wrscxd)$' fvu
+[ $? -eq 0 ] || exit $?
+
+msg "Have >=rsd access to the \"entry\" attribute of their own entry"
+usersU entry/read entry/search entry/disclose fvu/read \
+ | isOK 'ALLOWED$' fvu # fvu is useless here, but it's just to get the count
+[ $? -eq 0 ] || exit $?
+
+msg "Have =0 access to their \"children\" and operational attributes"
+usersU children structuralObjectClass entryUUID createTimestamp entryCSN modifiersName modifyTimestamp | isOK '=0$' children
+[ $? -eq 0 ] || exit $?
+
+msg "Have =0 access to other user entries (unless Postmaster)"
+for U1 in ${USERS}; do
+ for U2 in ${USERS}; do
+ D2="$(echo "${U2}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ [ "x${U1}" = "x${U2}" ] || \
+ search -s base -b "${D2},${SUFFIX}" "(fripostPostmaster=${U1},${SUFFIX})" | grep -q '^dn: ' || \
+ checkACL "${U1}" "${U2}" entry children \
+ fvu userPassword \
+ fripostIsStatusActive \
+ fripostMailboxQuota \
+ fripostMaildrop \
+ cn description
+ done
+done | isOK '=0$' entry
+[ $? -eq 0 ] || exit $?
+
+
+usersP () {
+ for P in ${USERS}; do
+ for U in ${USERS}; do
+ D="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ [ "x${U}" != "x${P}" ] && \
+ search -s base -b "${D},${SUFFIX}" "(fripostPostmaster=${P},${SUFFIX})" | grep -q '^dn: ' && \
+ checkACL "${P}" "${U}" "$@"
+ done
+ done
+}
+
+msg "Have =rscxd access to their user's \"fripostMailboxQuota\" (if Postmaster)"
+usersP fripostMailboxQuota | isOK 'read(=rscxd)$'
+[ $? -eq 0 ] || exit $?
+
+msg "Have =wd access to their user's \"userPassword\" (if Postmaster)"
+usersP userPassword | isOK '=w$'
+[ $? -eq 0 ] || exit $?
+
+msg "Have =wrscxd access to the other attributes of their users' entry (if Postmaster)"
+usersP fvu fripostIsStatusActive fripostMaildrop cn description | isOK 'write(=wrscxd)$' fvu
+[ $? -eq 0 ] || exit $?
+
+# "+a" is needed to create new accounts. "+z" would be required to
+# delete such accounts.
+msg "Have =arsd access to the \"entry\" attribute of their users' entry (if Postmaster)"
+usersP entry | isOK '=arsd$' entry
+[ $? -eq 0 ] || exit $?
+
+msg "Have =0 access to their users' \"children\" and operational attributes (if Postmaster)"
+usersP children structuralObjectClass entryUUID createTimestamp entryCSN modifiersName modifyTimestamp | isOK '=0$' children
+[ $? -eq 0 ] || exit $?
+
+
+###########################################################################
+
+
+echo
+echo "Authenticated users, access to alias entries"
+
+# * entry:
+# =s for all
+# +a if canCreateAlias
+# +rd if alias owner, domain owner or domain postmaster
+# +z (regular alias) if alias owner
+# +w (regular alias) if domain owner or domain postmaster
+# * children:
+# =0 for all
+# * fva:
+# =rscd (reserved alias) if domain owner or domain postmaster
+# =wrscd (regular alias) if alias owner, domain owner or domain postmaster
+# * fripostMaildrop:
+# =wrscd if alias owner, domain owner or domain postmaster
+# * fripostIsStatusActive:
+# =rscd (reserved alias) if domain owner or domain postmaster
+# =wrscd (regular alias) if alias owner, domain owner or domain postmaster
+# * fripostOwner:
+# =d for all
+# +rsc (reserved alias) if domain owner or domain postmaster
+# +rsc (regular alias) if alias owner, domain owner or domain postmaster
+# +w (regular alias) if domain owner or domain postmaster
+# * description:
+# =wrscd if alias owner, domain owner or domain postmaster
+
+usersA () {
+ for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ checkACL "${U}" "${A}" "$@"
+ done
+ done
+}
+
+
+msg "Have >=s access to \"entry\" and \"fripostOwner\""
+usersA fripostOwner/search entry/search | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access to the \"children\" and operational attributes"
+usersA children structuralObjectClass entryUUID createTimestamp entryCSN modifiersName modifyTimestamp | isOK '=0$' children
+[ $? -eq 0 ] || exit $?
+
+RESERVED_ATTRS="entry/delete
+ fva/write
+ fripostIsStatusActive/write"
+RESERVED_ATTRS2="fripostOwner/add fripostOwner/delete"
+
+ATTRS="entry/read entry/disclose
+ fva/read fva/search fva/compare fva/disclose
+ fripostMaildrop/add fripostMaildrop/delete fripostMaildrop/read fripostMaildrop/search fripostMaildrop/compare fripostMaildrop/disclose
+ fripostIsStatusActive/read fripostIsStatusActive/search fripostIsStatusActive/compare fripostIsStatusActive/disclose
+ fripostOwner/read fripostOwner/compare fripostOwner/disclose
+ description/add description/delete description/read description/search description/compare description/disclose"
+
+msg "Cannot delete/deactivate/change ownership of reserved aliases"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ LA="$(echo "${A}" | sed -re 's/^fva=(.*),fvd=[^,]+$/\1/')"
+ [ "x${LA}" = "xabuse" -o "x${LA}" = "xpostmaster" ] && \
+ checkACL "${U}" "${A}" ${RESERVED_ATTRS}
+ done
+done | isOK 'DENIED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can delete/deactivate/change ownership of regular aliases (if alias Owner)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ LA="$(echo "${A}" | sed -re 's/^fva=(.*),fvd=[^,]+$/\1/')"
+ [ "x${LA}" != "xabuse" -a "x${LA}" != "xpostmaster" ] && \
+ search -s base -b "${A},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" ${RESERVED_ATTRS}
+ done
+done | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can delete/deactivate/change ownership of regular aliases (if domain Owner)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ LA="$(echo "${A}" | sed -re 's/^fva=(.*),fvd=[^,]+$/\1/')"
+ [ "x${LA}" != "xabuse" -a "x${LA}" != "xpostmaster" ] && \
+ search -s base -b "${DA},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" ${RESERVED_ATTRS} ${RESERVED_ATTRS2}
+ done
+done | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can delete/deactivate/change ownership of regular aliases (if domain Postmaster)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ LA="$(echo "${A}" | sed -re 's/^fva=(.*),fvd=[^,]+$/\1/')"
+ [ "x${LA}" != "xabuse" -a "x${LA}" != "xpostmaster" ] && \
+ search -s base -b "${DA},${SUFFIX}" "fripostPostmaster=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" ${RESERVED_ATTRS} ${RESERVED_ATTRS2}
+ done
+done | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can change destination (if alias Owner)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ search -s base -b "${A},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" ${ATTRS}
+ done
+done | isOK 'ALLOWED$' entry read
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can change destination and create new aliases (if domain Owner)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" entry/add ${ATTRS}
+ done
+done | isOK 'ALLOWED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can change destination and create new aliases (if domain Postmaster)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "fripostPostmaster=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" entry/add ${ATTRS}
+ done
+done | isOK 'ALLOWED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+# Needed to create new entries. ("+z" is required to delete, btw.)
+msg "Have >=a access to \"entry\" (if CanCreateAlias, exact)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "fripostCanCreateAlias=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" entry/add
+ done
+done | isOK 'ALLOWED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+# Needed to create new entries. ("+z" is required to delete, btw.)
+msg "Have >=a access to \"entry\" (if CanCreateAlias, wildcard)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "fripostCanCreateAlias=${DU},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${A}" entry/add
+ done
+done | isOK 'ALLOWED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+msg "Do not have >=a access to \"entry\" (unless canCreateAlias)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "(|(fripostCanCreateAlias=${U},${SUFFIX})
+ (fripostCanCreateAlias=${DU},${SUFFIX})
+ (fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${A}" entry/add
+ done
+done | isOK 'DENIED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+msg "Cannot manage ownership (unless domain owner/domain postmaster)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "(|(fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${A}" ${RESERVED_ATTRS2}
+ done
+done | isOK 'DENIED$' fripostOwner add
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have no access to aliases entries (unless alias owner/domain owner/domain postmaster)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${A},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' || \
+ search -s base -b "${DA},${SUFFIX}" "(|(fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${A}" ${RESERVED_ATTRS} ${ATTRS}
+ done
+done | isOK 'DENIED$' entry delete
+[ $? -eq 0 ] || exit $?
+
+
+
+###########################################################################
+
+
+echo
+echo "Authenticated users, access to mailing list entries"
+
+# * entry:
+# =s for all
+# +a if canCreateML, domain owner or domain postmaster
+# +zrd if mailing list owner, domain owner or domain postmaster
+# * children:
+# =0 for all
+# * fvml:
+# =wrscd if mailing list owner, domain owner or domain postmaster
+# * fripostMLManager:
+# =rscd if mailing list owner, domain owner or domain postmaster
+# * fripostIsStatusActive:
+# =wrscd if mailing list owner, domain owner or domain postmaster
+# * fripostMLCommand:
+# =rscd if mailing list owner, domain owner or domain postmaster
+# * fripostOwner:
+# =d for all
+# +rsc if mailing list owner, domain owner or domain postmaster
+# +w if domain owner or domain postmaster
+# * description:
+# =wrscd if mailing list owner, domain owner or domain postmaster
+
+usersML () {
+ for U in ${USERS}; do
+ for ML in ${MLS}; do
+ checkACL "${U}" "${ML}" "$@"
+ done
+ done
+}
+
+
+msg "Have >=s access on \"entry\" and \"fripostOwner\""
+usersML fripostOwner/search entry/search | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have =0 access the \"children\" and operational attributes"
+usersML children structuralObjectClass entryUUID createTimestamp entryCSN modifiersName modifyTimestamp | isOK '=0$' children
+[ $? -eq 0 ] || exit $?
+
+
+msg "Cannot change transport-related attributes"
+for U in ${USERS}; do
+ for ML in ${MLS}; do
+ checkACL "${U}" "${ML}" fripostMLCommand/add fripostMLCommand/delete \
+ fripostMLManager/write
+ done
+done | isOK 'DENIED$' fripostMLManager
+[ $? -eq 0 ] || exit $?
+
+
+ATTRS="entry/read entry/disclose entry/delete
+ fvml/write fvml/read fvml/search fvml/compare fvml/disclose
+ fripostMLManager/read fripostMLManager/search fripostMLManager/compare fripostMLManager/disclose
+ fripostIsStatusActive/write fripostIsStatusActive/read fripostIsStatusActive/search fripostIsStatusActive/compare fripostIsStatusActive/disclose
+ fripostMLCommand/read fripostMLCommand/search fripostMLCommand/compare fripostMLCommand/disclose
+ fripostOwner/read fripostOwner/compare fripostOwner/disclose
+ description/add description/delete description/read description/compare description/disclose"
+ATTRS2="fripostOwner/add fripostOwner/delete"
+
+msg "Can edit/delete mailing list (if mailing list Owner)"
+for U in ${USERS}; do
+ for ML in ${MLS}; do
+ search -s base -b "${ML},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${ML}" ${ATTRS}
+ done
+done | isOK 'ALLOWED$' entry delete
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can edit/create/delete mailing list (if domain Owner)"
+[ $? -eq 0 ] || exit $?
+for U in ${USERS}; do
+ for ML in ${MLS}; do
+ DML="$(echo "${ML}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DML},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${ML}" ${ATTRS} ${ATTRS2} entry/add
+ done
+done | isOK 'ALLOWED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+msg "Can edit/create/delete mailing list (if domain Postmaster)"
+[ $? -eq 0 ] || exit $?
+for U in ${USERS}; do
+ for ML in ${MLS}; do
+ DML="$(echo "${ML}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DML},${SUFFIX}" "fripostPostmaster=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${ML}" ${ATTRS} ${ATTRS2} entry/add
+ done
+done | isOK 'ALLOWED$' entry add
+[ $? -eq 0 ] || exit $?
+
+
+# Needed to create new entries. ("+z" is required to delete, btw.)
+msg "Have >=a access to \"entry\" (if CanCreateML, exact)"
+for U in ${USERS}; do
+ for ML in ${MLS}; do
+ DML="$(echo "${ML}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DML},${SUFFIX}" "fripostCanCreateML=${U},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${ML}" entry/add
+ done
+done | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+# Needed to create new entries. ("+z" is required to delete, btw.)
+msg "Have >=a access to \"entry\" (if CanCreateML, wildcard)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for ML in ${MLS}; do
+ DML="$(echo "${ML}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DML},${SUFFIX}" "fripostCanCreateML=${DU},${SUFFIX}" | grep -q '^dn: ' && \
+ checkACL "${U}" "${ML}" entry/add
+ done
+done | isOK 'ALLOWED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Do not have >=a access to \"entry\" (unless canCreateML)"
+for U in ${USERS}; do
+ DU="$(echo "${U}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ for ML in ${MLS}; do
+ DML="$(echo "${ML}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DML},${SUFFIX}" "(|(fripostCanCreateML=${U},${SUFFIX})
+ (fripostCanCreateML=${DU},${SUFFIX})
+ (fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${ML}" entry/add
+ done
+done | isOK 'DENIED$' entry
+[ $? -eq 0 ] || exit $?
+
+
+msg "Cannot manage ownership (unless domain owner/domain postmaster)"
+for U in ${USERS}; do
+ for A in ${ALIASES}; do
+ DA="$(echo "${A}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${DA},${SUFFIX}" "(|(fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${A}" ${ATTRS2}
+ done
+done | isOK 'DENIED$' fripostOwner add
+[ $? -eq 0 ] || exit $?
+
+
+msg "Have no access to mailing list entries (unless mailing list owner/domain owner/domain postmaster)"
+for U in ${USERS}; do
+ for ML in ${MLS}; do
+ DML="$(echo "${ML}" | sed -re 's/.*,(fvd=[^,]+)$/\1/')"
+ search -s base -b "${ML},${SUFFIX}" "fripostOwner=${U},${SUFFIX}" | grep -q '^dn: ' || \
+ search -s base -b "${DML},${SUFFIX}" "(|(fripostOwner=${U},${SUFFIX})
+ (fripostPostmaster=${U},${SUFFIX}))" | grep -q '^dn: ' || \
+ checkACL "${U}" "${ML}" ${ATTRS} entry/delete
+ done
+done | isOK 'DENIED$' entry delete
+[ $? -eq 0 ] || exit $?
+
+
+
+###########################################################################
+
+
+rm "${RES}"