|
|
@@ -3,11 +3,11 @@
|
|
|
* All rights reserved.
|
|
|
*
|
|
|
* License: GPL (version 3 or any later version).
|
|
|
- * See LICENSE for details.
|
|
|
+ * See LICENSE for details.
|
|
|
* END COPYRIGHT BLOCK **/
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
-# include <config.h>
|
|
|
+#include <config.h>
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@@ -20,367 +20,339 @@
|
|
|
/* capacity is the capacity of the gerstr, size is the current length */
|
|
|
static void
|
|
|
_append_gerstr(
|
|
|
- char **gerstr,
|
|
|
- size_t *capacity,
|
|
|
- size_t *size,
|
|
|
- const char *news,
|
|
|
- const char *news2
|
|
|
- )
|
|
|
+ char **gerstr,
|
|
|
+ size_t *capacity,
|
|
|
+ size_t *size,
|
|
|
+ const char *news,
|
|
|
+ const char *news2)
|
|
|
{
|
|
|
- size_t len;
|
|
|
- size_t increment = 128;
|
|
|
- size_t fornull;
|
|
|
-
|
|
|
- if (!news) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* find out how much space we need */
|
|
|
- len = strlen(news);
|
|
|
- fornull = 1;
|
|
|
- if (news2) {
|
|
|
- len += strlen(news2);
|
|
|
- fornull++;
|
|
|
- }
|
|
|
-
|
|
|
- /* increase space if needed */
|
|
|
- while ((*size + len + fornull) > *capacity) {
|
|
|
- if ((len + fornull) > increment) {
|
|
|
- *capacity += len + fornull; /* just go ahead and grow the string enough */
|
|
|
- } else {
|
|
|
- *capacity += increment; /* rather than having lots of small increments */
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!*gerstr) {
|
|
|
- *gerstr = slapi_ch_malloc(*capacity);
|
|
|
- **gerstr = 0;
|
|
|
- } else {
|
|
|
- *gerstr = slapi_ch_realloc(*gerstr, *capacity);
|
|
|
- }
|
|
|
- strcat(*gerstr, news);
|
|
|
- if (news2) {
|
|
|
- strcat(*gerstr, news2);
|
|
|
- }
|
|
|
-
|
|
|
- *size += len;
|
|
|
-
|
|
|
- return;
|
|
|
+ size_t len;
|
|
|
+ size_t increment = 128;
|
|
|
+ size_t fornull;
|
|
|
+
|
|
|
+ if (!news) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* find out how much space we need */
|
|
|
+ len = strlen(news);
|
|
|
+ fornull = 1;
|
|
|
+ if (news2) {
|
|
|
+ len += strlen(news2);
|
|
|
+ fornull++;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* increase space if needed */
|
|
|
+ while ((*size + len + fornull) > *capacity) {
|
|
|
+ if ((len + fornull) > increment) {
|
|
|
+ *capacity += len + fornull; /* just go ahead and grow the string enough */
|
|
|
+ } else {
|
|
|
+ *capacity += increment; /* rather than having lots of small increments */
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!*gerstr) {
|
|
|
+ *gerstr = slapi_ch_malloc(*capacity);
|
|
|
+ **gerstr = 0;
|
|
|
+ } else {
|
|
|
+ *gerstr = slapi_ch_realloc(*gerstr, *capacity);
|
|
|
+ }
|
|
|
+ strcat(*gerstr, news);
|
|
|
+ if (news2) {
|
|
|
+ strcat(*gerstr, news2);
|
|
|
+ }
|
|
|
+
|
|
|
+ *size += len;
|
|
|
+
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-_ger_g_permission_granted (
|
|
|
- Slapi_PBlock *pb,
|
|
|
- Slapi_Entry *e,
|
|
|
- const char *subjectdn,
|
|
|
- char **errbuf
|
|
|
- )
|
|
|
+_ger_g_permission_granted(
|
|
|
+ Slapi_PBlock *pb,
|
|
|
+ Slapi_Entry *e,
|
|
|
+ const char *subjectdn,
|
|
|
+ char **errbuf)
|
|
|
{
|
|
|
- char *proxydn = NULL;
|
|
|
- Slapi_DN *requestor_sdn, *entry_sdn;
|
|
|
- char *errtext = NULL;
|
|
|
- int isroot;
|
|
|
- int rc;
|
|
|
-
|
|
|
- /*
|
|
|
- * Theorically, we should check if the entry has "g"
|
|
|
- * permission granted to the requestor. If granted,
|
|
|
- * allows the effective rights on that entry and its
|
|
|
- * attributes within the entry to be returned for
|
|
|
- * ANY subject.
|
|
|
- *
|
|
|
- * "G" permission granting has not been implemented yet,
|
|
|
- * the current release assumes that "g" permission be
|
|
|
- * granted to root and owner of any entry.
|
|
|
- */
|
|
|
-
|
|
|
- /*
|
|
|
- * The requestor may be either the bind dn or a proxy dn
|
|
|
- */
|
|
|
- if ((proxyauth_get_dn( pb, &proxydn, &errtext ) == LDAP_SUCCESS) && ( proxydn != NULL ))
|
|
|
- {
|
|
|
- requestor_sdn = slapi_sdn_new_dn_passin ( proxydn );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- slapi_ch_free_string(&proxydn); /* this could still have been set - free it */
|
|
|
- Operation *pb_op;
|
|
|
- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
|
|
- requestor_sdn = &(pb_op->o_sdn);
|
|
|
- }
|
|
|
- if ( slapi_sdn_get_dn (requestor_sdn) == NULL )
|
|
|
- {
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_g_permission_granted - Anonymous has no g permission\n" );
|
|
|
- rc = LDAP_INSUFFICIENT_ACCESS;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- isroot = slapi_dn_isroot ( slapi_sdn_get_dn (requestor_sdn) );
|
|
|
- if ( isroot )
|
|
|
- {
|
|
|
- /* Root has "g" permission on any entry */
|
|
|
- rc = LDAP_SUCCESS;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- entry_sdn = slapi_entry_get_sdn ( e );
|
|
|
- if ( entry_sdn == NULL || slapi_sdn_get_dn (entry_sdn) == NULL )
|
|
|
- {
|
|
|
- rc = LDAP_SUCCESS;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- if ( slapi_sdn_compare ( requestor_sdn, entry_sdn ) == 0 )
|
|
|
- {
|
|
|
- /* Owner has "g" permission on his own entry */
|
|
|
- rc = LDAP_SUCCESS;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- /* if the requestor and the subject user are identical, let's grant it */
|
|
|
- if ( strcasecmp ( slapi_sdn_get_ndn(requestor_sdn), subjectdn ) == 0)
|
|
|
- {
|
|
|
- /* Requestor should see his own permission rights on any entry */
|
|
|
- rc = LDAP_SUCCESS;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_g_permission_granted - %s\n", *errbuf);
|
|
|
- rc = LDAP_INSUFFICIENT_ACCESS;
|
|
|
+ char *proxydn = NULL;
|
|
|
+ Slapi_DN *requestor_sdn, *entry_sdn;
|
|
|
+ char *errtext = NULL;
|
|
|
+ int isroot;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Theorically, we should check if the entry has "g"
|
|
|
+ * permission granted to the requestor. If granted,
|
|
|
+ * allows the effective rights on that entry and its
|
|
|
+ * attributes within the entry to be returned for
|
|
|
+ * ANY subject.
|
|
|
+ *
|
|
|
+ * "G" permission granting has not been implemented yet,
|
|
|
+ * the current release assumes that "g" permission be
|
|
|
+ * granted to root and owner of any entry.
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The requestor may be either the bind dn or a proxy dn
|
|
|
+ */
|
|
|
+ if ((proxyauth_get_dn(pb, &proxydn, &errtext) == LDAP_SUCCESS) && (proxydn != NULL)) {
|
|
|
+ requestor_sdn = slapi_sdn_new_dn_passin(proxydn);
|
|
|
+ } else {
|
|
|
+ slapi_ch_free_string(&proxydn); /* this could still have been set - free it */
|
|
|
+ Operation *pb_op;
|
|
|
+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
|
|
+ requestor_sdn = &(pb_op->o_sdn);
|
|
|
+ }
|
|
|
+ if (slapi_sdn_get_dn(requestor_sdn) == NULL) {
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_g_permission_granted - Anonymous has no g permission\n");
|
|
|
+ rc = LDAP_INSUFFICIENT_ACCESS;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ isroot = slapi_dn_isroot(slapi_sdn_get_dn(requestor_sdn));
|
|
|
+ if (isroot) {
|
|
|
+ /* Root has "g" permission on any entry */
|
|
|
+ rc = LDAP_SUCCESS;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ entry_sdn = slapi_entry_get_sdn(e);
|
|
|
+ if (entry_sdn == NULL || slapi_sdn_get_dn(entry_sdn) == NULL) {
|
|
|
+ rc = LDAP_SUCCESS;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (slapi_sdn_compare(requestor_sdn, entry_sdn) == 0) {
|
|
|
+ /* Owner has "g" permission on his own entry */
|
|
|
+ rc = LDAP_SUCCESS;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* if the requestor and the subject user are identical, let's grant it */
|
|
|
+ if (strcasecmp(slapi_sdn_get_ndn(requestor_sdn), subjectdn) == 0) {
|
|
|
+ /* Requestor should see his own permission rights on any entry */
|
|
|
+ rc = LDAP_SUCCESS;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ aclutil_str_append(errbuf, "get-effective-rights: requestor has no g permission on the entry");
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_g_permission_granted - %s\n", *errbuf);
|
|
|
+ rc = LDAP_INSUFFICIENT_ACCESS;
|
|
|
|
|
|
bailout:
|
|
|
- if ( proxydn )
|
|
|
- {
|
|
|
- /* The ownership of proxydn has passed to requestor_sdn */
|
|
|
- slapi_sdn_free ( &requestor_sdn );
|
|
|
- }
|
|
|
- return rc;
|
|
|
+ if (proxydn) {
|
|
|
+ /* The ownership of proxydn has passed to requestor_sdn */
|
|
|
+ slapi_sdn_free(&requestor_sdn);
|
|
|
+ }
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-_ger_parse_control (
|
|
|
- Slapi_PBlock *pb,
|
|
|
- char **subjectndn,
|
|
|
- int *iscritical,
|
|
|
- char **errbuf
|
|
|
- )
|
|
|
+_ger_parse_control(
|
|
|
+ Slapi_PBlock *pb,
|
|
|
+ char **subjectndn,
|
|
|
+ int *iscritical,
|
|
|
+ char **errbuf)
|
|
|
{
|
|
|
- LDAPControl **requestcontrols;
|
|
|
- struct berval *subjectber;
|
|
|
- BerElement *ber;
|
|
|
- size_t subjectndnlen = 0;
|
|
|
- char *orig = NULL;
|
|
|
- char *normed = NULL;
|
|
|
-
|
|
|
- if (NULL == subjectndn)
|
|
|
- {
|
|
|
- return LDAP_OPERATIONS_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
- *subjectndn = NULL;
|
|
|
-
|
|
|
- /*
|
|
|
- * Get the control
|
|
|
- */
|
|
|
- slapi_pblock_get ( pb, SLAPI_REQCONTROLS, (void *) &requestcontrols );
|
|
|
- slapi_control_present ( requestcontrols,
|
|
|
- LDAP_CONTROL_GET_EFFECTIVE_RIGHTS,
|
|
|
- &subjectber,
|
|
|
- iscritical );
|
|
|
- if ( subjectber == NULL || subjectber->bv_val == NULL ||
|
|
|
- subjectber->bv_len == 0 )
|
|
|
- {
|
|
|
- aclutil_str_append ( errbuf, "get-effective-rights: missing subject" );
|
|
|
- slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf );
|
|
|
- if (iscritical)
|
|
|
- return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
- else
|
|
|
- return LDAP_INVALID_SYNTAX;
|
|
|
- }
|
|
|
-
|
|
|
- if ( strncasecmp ( "dn:", subjectber->bv_val, 3 ) == 0 )
|
|
|
- {
|
|
|
- /*
|
|
|
- * This is a non-standard support to allow the subject being a plain
|
|
|
- * or base64 encoding string. Hence users using -J option in
|
|
|
- * ldapsearch don't have to do BER encoding for the subject.
|
|
|
- */
|
|
|
- orig = slapi_ch_malloc ( subjectber->bv_len + 1 );
|
|
|
- strncpy ( orig, subjectber->bv_val, subjectber->bv_len );
|
|
|
- *(orig + subjectber->bv_len) = '\0';
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ber = ber_init (subjectber);
|
|
|
- if ( ber == NULL )
|
|
|
- {
|
|
|
- aclutil_str_append ( errbuf, "get-effective-rights: ber_init failed for the subject" );
|
|
|
- slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf );
|
|
|
- if (iscritical)
|
|
|
- return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
- else
|
|
|
- return LDAP_OPERATIONS_ERROR;
|
|
|
- }
|
|
|
- /* "a" means to allocate storage as needed for octet string */
|
|
|
- if ( ber_scanf (ber, "a", &orig) == LBER_ERROR )
|
|
|
- {
|
|
|
- aclutil_str_append ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
|
|
|
- slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf );
|
|
|
- ber_free ( ber, 1 );
|
|
|
- if (iscritical)
|
|
|
- return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
- else
|
|
|
- return LDAP_INVALID_SYNTAX;
|
|
|
- }
|
|
|
- ber_free ( ber, 1 );
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * The current implementation limits the subject to authorization ID
|
|
|
- * (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
|
|
|
- * flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
|
|
|
- */
|
|
|
- subjectndnlen = orig ? strlen(orig) : 0;
|
|
|
- if ( NULL == orig || subjectndnlen < 3 || strncasecmp ( "dn:", orig, 3 ) != 0 )
|
|
|
- {
|
|
|
- aclutil_str_append ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
|
|
|
- slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf );
|
|
|
- slapi_ch_free_string(&orig);
|
|
|
- if (iscritical)
|
|
|
- return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
- else
|
|
|
- return LDAP_INVALID_SYNTAX;
|
|
|
- }
|
|
|
-
|
|
|
- /* memmove is safe for overlapping copy */
|
|
|
- normed = slapi_create_dn_string("%s", orig + 3);
|
|
|
- if (NULL == normed) {
|
|
|
- aclutil_str_append (errbuf, "get-effective-rights: failed to normalize dn: ");
|
|
|
- aclutil_str_append (errbuf, orig);
|
|
|
- slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf);
|
|
|
- slapi_ch_free_string(&orig);
|
|
|
- if (iscritical)
|
|
|
- return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
- else
|
|
|
- return LDAP_INVALID_SYNTAX;
|
|
|
- }
|
|
|
- slapi_ch_free_string(&orig);
|
|
|
- *subjectndn = normed;
|
|
|
- slapi_dn_ignore_case(*subjectndn);
|
|
|
- return LDAP_SUCCESS;
|
|
|
+ LDAPControl **requestcontrols;
|
|
|
+ struct berval *subjectber;
|
|
|
+ BerElement *ber;
|
|
|
+ size_t subjectndnlen = 0;
|
|
|
+ char *orig = NULL;
|
|
|
+ char *normed = NULL;
|
|
|
+
|
|
|
+ if (NULL == subjectndn) {
|
|
|
+ return LDAP_OPERATIONS_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ *subjectndn = NULL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get the control
|
|
|
+ */
|
|
|
+ slapi_pblock_get(pb, SLAPI_REQCONTROLS, (void *)&requestcontrols);
|
|
|
+ slapi_control_present(requestcontrols,
|
|
|
+ LDAP_CONTROL_GET_EFFECTIVE_RIGHTS,
|
|
|
+ &subjectber,
|
|
|
+ iscritical);
|
|
|
+ if (subjectber == NULL || subjectber->bv_val == NULL ||
|
|
|
+ subjectber->bv_len == 0) {
|
|
|
+ aclutil_str_append(errbuf, "get-effective-rights: missing subject");
|
|
|
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf);
|
|
|
+ if (iscritical)
|
|
|
+ return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
+ else
|
|
|
+ return LDAP_INVALID_SYNTAX;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (strncasecmp("dn:", subjectber->bv_val, 3) == 0) {
|
|
|
+ /*
|
|
|
+ * This is a non-standard support to allow the subject being a plain
|
|
|
+ * or base64 encoding string. Hence users using -J option in
|
|
|
+ * ldapsearch don't have to do BER encoding for the subject.
|
|
|
+ */
|
|
|
+ orig = slapi_ch_malloc(subjectber->bv_len + 1);
|
|
|
+ strncpy(orig, subjectber->bv_val, subjectber->bv_len);
|
|
|
+ *(orig + subjectber->bv_len) = '\0';
|
|
|
+ } else {
|
|
|
+ ber = ber_init(subjectber);
|
|
|
+ if (ber == NULL) {
|
|
|
+ aclutil_str_append(errbuf, "get-effective-rights: ber_init failed for the subject");
|
|
|
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf);
|
|
|
+ if (iscritical)
|
|
|
+ return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
+ else
|
|
|
+ return LDAP_OPERATIONS_ERROR;
|
|
|
+ }
|
|
|
+ /* "a" means to allocate storage as needed for octet string */
|
|
|
+ if (ber_scanf(ber, "a", &orig) == LBER_ERROR) {
|
|
|
+ aclutil_str_append(errbuf, "get-effective-rights: invalid ber tag in the subject");
|
|
|
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf);
|
|
|
+ ber_free(ber, 1);
|
|
|
+ if (iscritical)
|
|
|
+ return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
+ else
|
|
|
+ return LDAP_INVALID_SYNTAX;
|
|
|
+ }
|
|
|
+ ber_free(ber, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The current implementation limits the subject to authorization ID
|
|
|
+ * (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
|
|
|
+ * flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
|
|
|
+ */
|
|
|
+ subjectndnlen = orig ? strlen(orig) : 0;
|
|
|
+ if (NULL == orig || subjectndnlen < 3 || strncasecmp("dn:", orig, 3) != 0) {
|
|
|
+ aclutil_str_append(errbuf, "get-effective-rights: subject is not dnAuthzId");
|
|
|
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf);
|
|
|
+ slapi_ch_free_string(&orig);
|
|
|
+ if (iscritical)
|
|
|
+ return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
+ else
|
|
|
+ return LDAP_INVALID_SYNTAX;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* memmove is safe for overlapping copy */
|
|
|
+ normed = slapi_create_dn_string("%s", orig + 3);
|
|
|
+ if (NULL == normed) {
|
|
|
+ aclutil_str_append(errbuf, "get-effective-rights: failed to normalize dn: ");
|
|
|
+ aclutil_str_append(errbuf, orig);
|
|
|
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, "_ger_parse_control - %s\n", *errbuf);
|
|
|
+ slapi_ch_free_string(&orig);
|
|
|
+ if (iscritical)
|
|
|
+ return LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* RFC 4511 4.1.11 */
|
|
|
+ else
|
|
|
+ return LDAP_INVALID_SYNTAX;
|
|
|
+ }
|
|
|
+ slapi_ch_free_string(&orig);
|
|
|
+ *subjectndn = normed;
|
|
|
+ slapi_dn_ignore_case(*subjectndn);
|
|
|
+ return LDAP_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-_ger_release_gerpb (
|
|
|
- Slapi_PBlock **gerpb,
|
|
|
- void **aclcb, /* original aclcb */
|
|
|
- Slapi_PBlock *pb /* original pb */
|
|
|
- )
|
|
|
+_ger_release_gerpb(
|
|
|
+ Slapi_PBlock **gerpb,
|
|
|
+ void **aclcb, /* original aclcb */
|
|
|
+ Slapi_PBlock *pb /* original pb */
|
|
|
+ )
|
|
|
{
|
|
|
- if ( *gerpb )
|
|
|
- {
|
|
|
- slapi_pblock_destroy ( *gerpb );
|
|
|
- *gerpb = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- /* Put the original aclcb back to pb */
|
|
|
- if ( *aclcb )
|
|
|
- {
|
|
|
- Connection *conn = NULL;
|
|
|
- slapi_pblock_get ( pb, SLAPI_CONNECTION, &conn );
|
|
|
- if (conn)
|
|
|
- {
|
|
|
- struct aclcb *geraclcb;
|
|
|
- geraclcb = (struct aclcb *) acl_get_ext ( ACL_EXT_CONNECTION, conn );
|
|
|
- acl_conn_ext_destructor ( geraclcb, NULL, NULL );
|
|
|
- acl_set_ext ( ACL_EXT_CONNECTION, conn, *aclcb );
|
|
|
- *aclcb = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
+ if (*gerpb) {
|
|
|
+ slapi_pblock_destroy(*gerpb);
|
|
|
+ *gerpb = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Put the original aclcb back to pb */
|
|
|
+ if (*aclcb) {
|
|
|
+ Connection *conn = NULL;
|
|
|
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &conn);
|
|
|
+ if (conn) {
|
|
|
+ struct aclcb *geraclcb;
|
|
|
+ geraclcb = (struct aclcb *)acl_get_ext(ACL_EXT_CONNECTION, conn);
|
|
|
+ acl_conn_ext_destructor(geraclcb, NULL, NULL);
|
|
|
+ acl_set_ext(ACL_EXT_CONNECTION, conn, *aclcb);
|
|
|
+ *aclcb = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-_ger_new_gerpb (
|
|
|
- Slapi_PBlock *pb,
|
|
|
- Slapi_Entry *e __attribute__((unused)),
|
|
|
- const char *subjectndn,
|
|
|
- Slapi_PBlock **gerpb,
|
|
|
- void **aclcb, /* original aclcb */
|
|
|
- char **errbuf __attribute__((unused))
|
|
|
- )
|
|
|
+_ger_new_gerpb(
|
|
|
+ Slapi_PBlock *pb,
|
|
|
+ Slapi_Entry *e __attribute__((unused)),
|
|
|
+ const char *subjectndn,
|
|
|
+ Slapi_PBlock **gerpb,
|
|
|
+ void **aclcb, /* original aclcb */
|
|
|
+ char **errbuf __attribute__((unused)))
|
|
|
{
|
|
|
- Connection *conn;
|
|
|
- struct acl_cblock *geraclcb;
|
|
|
- Acl_PBlock *geraclpb;
|
|
|
- Operation *gerop;
|
|
|
- int rc = LDAP_SUCCESS;
|
|
|
-
|
|
|
- *aclcb = NULL;
|
|
|
- *gerpb = slapi_pblock_new ();
|
|
|
- if ( *gerpb == NULL )
|
|
|
- {
|
|
|
- rc = LDAP_NO_MEMORY;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- /* aclpb initialization needs the backend */
|
|
|
- Slapi_Backend *be;
|
|
|
- slapi_pblock_get ( pb, SLAPI_BACKEND, &be );
|
|
|
- slapi_pblock_set ( *gerpb, SLAPI_BACKEND, be );
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- int isroot = slapi_dn_isroot ( subjectndn );
|
|
|
- slapi_pblock_set ( *gerpb, SLAPI_REQUESTOR_ISROOT, &isroot );
|
|
|
- }
|
|
|
-
|
|
|
- /* Save requestor's aclcb and set subjectdn's one */
|
|
|
- {
|
|
|
- slapi_pblock_get ( pb, SLAPI_CONNECTION, &conn );
|
|
|
- slapi_pblock_set ( *gerpb, SLAPI_CONNECTION, conn );
|
|
|
-
|
|
|
- /* Can't share the conn->aclcb because of different context */
|
|
|
- geraclcb = (struct acl_cblock *) acl_conn_ext_constructor ( NULL, NULL);
|
|
|
- if ( geraclcb == NULL )
|
|
|
- {
|
|
|
- rc = LDAP_NO_MEMORY;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- slapi_sdn_set_ndn_byval ( geraclcb->aclcb_sdn, subjectndn );
|
|
|
- *aclcb = acl_get_ext ( ACL_EXT_CONNECTION, conn );
|
|
|
- acl_set_ext ( ACL_EXT_CONNECTION, conn, (void *) geraclcb );
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- gerop = operation_new ( OP_FLAG_INTERNAL );
|
|
|
- if ( gerop == NULL )
|
|
|
- {
|
|
|
- rc = LDAP_NO_MEMORY;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- /*
|
|
|
- * conn is a no-use parameter in the functions
|
|
|
- * chained down from factory_create_extension
|
|
|
- */
|
|
|
- gerop->o_extension = factory_create_extension ( get_operation_object_type(), (void *)gerop, (void *)conn );
|
|
|
- slapi_pblock_set ( *gerpb, SLAPI_OPERATION, gerop );
|
|
|
- slapi_sdn_set_ndn_byval ( &gerop->o_sdn, subjectndn );
|
|
|
- geraclpb = acl_get_ext ( ACL_EXT_OPERATION, (void *)gerop);
|
|
|
- acl_init_aclpb ( *gerpb, geraclpb, subjectndn, 0 );
|
|
|
- geraclpb->aclpb_res_type |= ACLPB_EFFECTIVE_RIGHTS;
|
|
|
- }
|
|
|
+ Connection *conn;
|
|
|
+ struct acl_cblock *geraclcb;
|
|
|
+ Acl_PBlock *geraclpb;
|
|
|
+ Operation *gerop;
|
|
|
+ int rc = LDAP_SUCCESS;
|
|
|
+
|
|
|
+ *aclcb = NULL;
|
|
|
+ *gerpb = slapi_pblock_new();
|
|
|
+ if (*gerpb == NULL) {
|
|
|
+ rc = LDAP_NO_MEMORY;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ /* aclpb initialization needs the backend */
|
|
|
+ Slapi_Backend *be;
|
|
|
+ slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
+ slapi_pblock_set(*gerpb, SLAPI_BACKEND, be);
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ int isroot = slapi_dn_isroot(subjectndn);
|
|
|
+ slapi_pblock_set(*gerpb, SLAPI_REQUESTOR_ISROOT, &isroot);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Save requestor's aclcb and set subjectdn's one */
|
|
|
+ {
|
|
|
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &conn);
|
|
|
+ slapi_pblock_set(*gerpb, SLAPI_CONNECTION, conn);
|
|
|
+
|
|
|
+ /* Can't share the conn->aclcb because of different context */
|
|
|
+ geraclcb = (struct acl_cblock *)acl_conn_ext_constructor(NULL, NULL);
|
|
|
+ if (geraclcb == NULL) {
|
|
|
+ rc = LDAP_NO_MEMORY;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ slapi_sdn_set_ndn_byval(geraclcb->aclcb_sdn, subjectndn);
|
|
|
+ *aclcb = acl_get_ext(ACL_EXT_CONNECTION, conn);
|
|
|
+ acl_set_ext(ACL_EXT_CONNECTION, conn, (void *)geraclcb);
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ gerop = operation_new(OP_FLAG_INTERNAL);
|
|
|
+ if (gerop == NULL) {
|
|
|
+ rc = LDAP_NO_MEMORY;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * conn is a no-use parameter in the functions
|
|
|
+ * chained down from factory_create_extension
|
|
|
+ */
|
|
|
+ gerop->o_extension = factory_create_extension(get_operation_object_type(), (void *)gerop, (void *)conn);
|
|
|
+ slapi_pblock_set(*gerpb, SLAPI_OPERATION, gerop);
|
|
|
+ slapi_sdn_set_ndn_byval(&gerop->o_sdn, subjectndn);
|
|
|
+ geraclpb = acl_get_ext(ACL_EXT_OPERATION, (void *)gerop);
|
|
|
+ acl_init_aclpb(*gerpb, geraclpb, subjectndn, 0);
|
|
|
+ geraclpb->aclpb_res_type |= ACLPB_EFFECTIVE_RIGHTS;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
bailout:
|
|
|
- if ( rc != LDAP_SUCCESS )
|
|
|
- {
|
|
|
- _ger_release_gerpb ( gerpb, aclcb, pb );
|
|
|
- }
|
|
|
+ if (rc != LDAP_SUCCESS) {
|
|
|
+ _ger_release_gerpb(gerpb, aclcb, pb);
|
|
|
+ }
|
|
|
|
|
|
- return rc;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -388,57 +360,53 @@ bailout:
|
|
|
* "entryLevelRights: adnvxxx\n".
|
|
|
*/
|
|
|
unsigned long
|
|
|
-_ger_get_entry_rights (
|
|
|
- Slapi_PBlock *gerpb,
|
|
|
- Slapi_Entry *e,
|
|
|
- const char *subjectndn __attribute__((unused)),
|
|
|
- char **gerstr,
|
|
|
- size_t *gerstrsize,
|
|
|
- size_t *gerstrcap,
|
|
|
- char **errbuf __attribute__((unused))
|
|
|
- )
|
|
|
+_ger_get_entry_rights(
|
|
|
+ Slapi_PBlock *gerpb,
|
|
|
+ Slapi_Entry *e,
|
|
|
+ const char *subjectndn __attribute__((unused)),
|
|
|
+ char **gerstr,
|
|
|
+ size_t *gerstrsize,
|
|
|
+ size_t *gerstrcap,
|
|
|
+ char **errbuf __attribute__((unused)))
|
|
|
{
|
|
|
- unsigned long entryrights = 0;
|
|
|
- Slapi_RDN *rdn = NULL;
|
|
|
- char *rdntype = NULL;
|
|
|
- char *rdnvalue = NULL;
|
|
|
-
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "entryLevelRights: ", NULL);
|
|
|
-
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_entry_rights - SLAPI_ACL_READ\n" );
|
|
|
- if (acl_access_allowed(gerpb, e, "*", NULL, SLAPI_ACL_READ) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* v - view e */
|
|
|
- entryrights |= SLAPI_ACL_READ;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "v", NULL);
|
|
|
- }
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_entry_rights - SLAPI_ACL_ADD\n" );
|
|
|
- if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_ADD) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* a - add child entry below e */
|
|
|
- entryrights |= SLAPI_ACL_ADD;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "a", NULL);
|
|
|
- }
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_entry_rights - SLAPI_ACL_DELETE\n" );
|
|
|
- if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_DELETE) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* d - delete e */
|
|
|
- entryrights |= SLAPI_ACL_DELETE;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "d", NULL);
|
|
|
- }
|
|
|
-
|
|
|
+ unsigned long entryrights = 0;
|
|
|
+ Slapi_RDN *rdn = NULL;
|
|
|
+ char *rdntype = NULL;
|
|
|
+ char *rdnvalue = NULL;
|
|
|
+
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "entryLevelRights: ", NULL);
|
|
|
+
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_entry_rights - SLAPI_ACL_READ\n");
|
|
|
+ if (acl_access_allowed(gerpb, e, "*", NULL, SLAPI_ACL_READ) == LDAP_SUCCESS) {
|
|
|
+ /* v - view e */
|
|
|
+ entryrights |= SLAPI_ACL_READ;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "v", NULL);
|
|
|
+ }
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_entry_rights - SLAPI_ACL_ADD\n");
|
|
|
+ if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_ADD) == LDAP_SUCCESS) {
|
|
|
+ /* a - add child entry below e */
|
|
|
+ entryrights |= SLAPI_ACL_ADD;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "a", NULL);
|
|
|
+ }
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_entry_rights - SLAPI_ACL_DELETE\n");
|
|
|
+ if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_DELETE) == LDAP_SUCCESS) {
|
|
|
+ /* d - delete e */
|
|
|
+ entryrights |= SLAPI_ACL_DELETE;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "d", NULL);
|
|
|
+ }
|
|
|
+
|
|
|
if (config_get_moddn_aci()) {
|
|
|
/* The server enforces the new MODDN aci right.
|
|
|
* So the status 'n' is set if this right is granted.
|
|
|
- * Opposed to the legacy mode where this flag is set if
|
|
|
+ * Opposed to the legacy mode where this flag is set if
|
|
|
* WRITE was granted on rdn attrbibute
|
|
|
*/
|
|
|
if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_MODDN) == LDAP_SUCCESS) {
|
|
|
slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_entry_rights - SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn(e));
|
|
|
+ "_ger_get_entry_rights - SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn(e));
|
|
|
/* n - rename e */
|
|
|
entryrights |= SLAPI_ACL_MODDN;
|
|
|
_append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL);
|
|
|
@@ -456,11 +424,11 @@ _ger_get_entry_rights (
|
|
|
slapi_rdn_get_first(rdn, &rdntype, &rdnvalue);
|
|
|
if (NULL != rdntype) {
|
|
|
slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_entry_rights - SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype);
|
|
|
+ "_ger_get_entry_rights - SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype);
|
|
|
if (acl_access_allowed(gerpb, e, rdntype, NULL,
|
|
|
- ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS &&
|
|
|
- acl_access_allowed(gerpb, e, rdntype, NULL,
|
|
|
- ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) {
|
|
|
+ ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS &&
|
|
|
+ acl_access_allowed(gerpb, e, rdntype, NULL,
|
|
|
+ ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) {
|
|
|
/* n - rename e */
|
|
|
entryrights |= SLAPI_ACL_WRITE;
|
|
|
_append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL);
|
|
|
@@ -468,14 +436,13 @@ _ger_get_entry_rights (
|
|
|
}
|
|
|
slapi_rdn_free(&rdn);
|
|
|
}
|
|
|
- if ( entryrights == 0 )
|
|
|
- {
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
|
|
|
- }
|
|
|
+ if (entryrights == 0) {
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
|
|
|
+ }
|
|
|
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "\n", NULL);
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "\n", NULL);
|
|
|
|
|
|
- return entryrights;
|
|
|
+ return entryrights;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -483,640 +450,558 @@ _ger_get_entry_rights (
|
|
|
* to expand dynamically.
|
|
|
*/
|
|
|
unsigned long
|
|
|
-_ger_get_attr_rights (
|
|
|
- Slapi_PBlock *gerpb,
|
|
|
- Slapi_Entry *e,
|
|
|
- const char *subjectndn,
|
|
|
- char *type,
|
|
|
- char **gerstr,
|
|
|
- size_t *gerstrsize,
|
|
|
- size_t *gerstrcap,
|
|
|
- int isfirstattr,
|
|
|
- char **errbuf
|
|
|
- )
|
|
|
+_ger_get_attr_rights(
|
|
|
+ Slapi_PBlock *gerpb,
|
|
|
+ Slapi_Entry *e,
|
|
|
+ const char *subjectndn,
|
|
|
+ char *type,
|
|
|
+ char **gerstr,
|
|
|
+ size_t *gerstrsize,
|
|
|
+ size_t *gerstrcap,
|
|
|
+ int isfirstattr,
|
|
|
+ char **errbuf)
|
|
|
{
|
|
|
- unsigned long attrrights = 0;
|
|
|
-
|
|
|
- if (!isfirstattr)
|
|
|
- {
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, ", ", NULL);
|
|
|
- }
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, type, ":");
|
|
|
-
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_attr_rights - SLAPI_ACL_READ %s\n", type );
|
|
|
- if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_READ) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* r - read the values of type */
|
|
|
- attrrights |= SLAPI_ACL_READ;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "r", NULL);
|
|
|
- }
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_attr_rights - SLAPI_ACL_SEARCH %s\n", type );
|
|
|
- if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_SEARCH) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* s - search the values of type */
|
|
|
- attrrights |= SLAPI_ACL_SEARCH;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "s", NULL);
|
|
|
- }
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_attr_rights - SLAPI_ACL_COMPARE %s\n", type );
|
|
|
- if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_COMPARE) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* c - compare the values of type */
|
|
|
- attrrights |= SLAPI_ACL_COMPARE;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "c", NULL);
|
|
|
- }
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_attr_rights - SLAPI_ACL_WRITE_ADD %s\n", type );
|
|
|
- if (acl_access_allowed(gerpb, e, type, NULL, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* w - add the values of type */
|
|
|
- attrrights |= ACLPB_SLAPI_ACL_WRITE_ADD;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "w", NULL);
|
|
|
- }
|
|
|
- slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
- "_ger_get_attr_rights - SLAPI_ACL_WRITE_DEL %s\n", type );
|
|
|
- if (acl_access_allowed(gerpb, e, type, NULL, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* o - delete the values of type */
|
|
|
- attrrights |= ACLPB_SLAPI_ACL_WRITE_DEL;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "o", NULL);
|
|
|
- }
|
|
|
- /* If subjectdn has no general write right, check for self write */
|
|
|
- if ( 0 == (attrrights & (ACLPB_SLAPI_ACL_WRITE_DEL | ACLPB_SLAPI_ACL_WRITE_ADD)) )
|
|
|
- {
|
|
|
- struct berval val;
|
|
|
-
|
|
|
- val.bv_val = (char *)subjectndn;
|
|
|
- val.bv_len = strlen (subjectndn);
|
|
|
-
|
|
|
- if (acl_access_allowed(gerpb, e, type, &val, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* W - add self to the attribute */
|
|
|
- attrrights |= ACLPB_SLAPI_ACL_WRITE_ADD;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "W", NULL);
|
|
|
- }
|
|
|
- if (acl_access_allowed(gerpb, e, type, &val, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS)
|
|
|
- {
|
|
|
- /* O - delete self from the attribute */
|
|
|
- attrrights |= ACLPB_SLAPI_ACL_WRITE_DEL;
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "O", NULL);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ( attrrights == 0 )
|
|
|
- {
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
|
|
|
- }
|
|
|
-
|
|
|
- return attrrights;
|
|
|
+ unsigned long attrrights = 0;
|
|
|
+
|
|
|
+ if (!isfirstattr) {
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, ", ", NULL);
|
|
|
+ }
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, type, ":");
|
|
|
+
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_attr_rights - SLAPI_ACL_READ %s\n", type);
|
|
|
+ if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_READ) == LDAP_SUCCESS) {
|
|
|
+ /* r - read the values of type */
|
|
|
+ attrrights |= SLAPI_ACL_READ;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "r", NULL);
|
|
|
+ }
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_attr_rights - SLAPI_ACL_SEARCH %s\n", type);
|
|
|
+ if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_SEARCH) == LDAP_SUCCESS) {
|
|
|
+ /* s - search the values of type */
|
|
|
+ attrrights |= SLAPI_ACL_SEARCH;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "s", NULL);
|
|
|
+ }
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_attr_rights - SLAPI_ACL_COMPARE %s\n", type);
|
|
|
+ if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_COMPARE) == LDAP_SUCCESS) {
|
|
|
+ /* c - compare the values of type */
|
|
|
+ attrrights |= SLAPI_ACL_COMPARE;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "c", NULL);
|
|
|
+ }
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_attr_rights - SLAPI_ACL_WRITE_ADD %s\n", type);
|
|
|
+ if (acl_access_allowed(gerpb, e, type, NULL, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) {
|
|
|
+ /* w - add the values of type */
|
|
|
+ attrrights |= ACLPB_SLAPI_ACL_WRITE_ADD;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "w", NULL);
|
|
|
+ }
|
|
|
+ slapi_log_err(SLAPI_LOG_ACL, plugin_name,
|
|
|
+ "_ger_get_attr_rights - SLAPI_ACL_WRITE_DEL %s\n", type);
|
|
|
+ if (acl_access_allowed(gerpb, e, type, NULL, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS) {
|
|
|
+ /* o - delete the values of type */
|
|
|
+ attrrights |= ACLPB_SLAPI_ACL_WRITE_DEL;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "o", NULL);
|
|
|
+ }
|
|
|
+ /* If subjectdn has no general write right, check for self write */
|
|
|
+ if (0 == (attrrights & (ACLPB_SLAPI_ACL_WRITE_DEL | ACLPB_SLAPI_ACL_WRITE_ADD))) {
|
|
|
+ struct berval val;
|
|
|
+
|
|
|
+ val.bv_val = (char *)subjectndn;
|
|
|
+ val.bv_len = strlen(subjectndn);
|
|
|
+
|
|
|
+ if (acl_access_allowed(gerpb, e, type, &val, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) {
|
|
|
+ /* W - add self to the attribute */
|
|
|
+ attrrights |= ACLPB_SLAPI_ACL_WRITE_ADD;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "W", NULL);
|
|
|
+ }
|
|
|
+ if (acl_access_allowed(gerpb, e, type, &val, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS) {
|
|
|
+ /* O - delete self from the attribute */
|
|
|
+ attrrights |= ACLPB_SLAPI_ACL_WRITE_DEL;
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "O", NULL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (attrrights == 0) {
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ return attrrights;
|
|
|
}
|
|
|
|
|
|
-#define GER_GET_ATTR_RIGHTS(attrs) \
|
|
|
- for (thisattr = (attrs); thisattr && *thisattr; thisattr++) \
|
|
|
- { \
|
|
|
- _ger_get_attr_rights (gerpb, e, subjectndn, *thisattr, \
|
|
|
- gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf); \
|
|
|
- isfirstattr = 0; \
|
|
|
- } \
|
|
|
-
|
|
|
-#define GER_GET_ATTR_RIGHTA_EXT(c, inattrs, exattrs); \
|
|
|
- for ( i = 0; attrs[i]; i++ ) \
|
|
|
- { \
|
|
|
- if ((c) != *attrs[i] && charray_inlist((inattrs), attrs[i]) && \
|
|
|
- !charray_inlist((exattrs), attrs[i])) \
|
|
|
- { \
|
|
|
- _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i], \
|
|
|
- gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf ); \
|
|
|
- isfirstattr = 0; \
|
|
|
- } \
|
|
|
- }
|
|
|
+#define GER_GET_ATTR_RIGHTS(attrs) \
|
|
|
+ for (thisattr = (attrs); thisattr && *thisattr; thisattr++) { \
|
|
|
+ _ger_get_attr_rights(gerpb, e, subjectndn, *thisattr, \
|
|
|
+ gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf); \
|
|
|
+ isfirstattr = 0; \
|
|
|
+ }
|
|
|
+
|
|
|
+#define GER_GET_ATTR_RIGHTA_EXT(c, inattrs, exattrs) \
|
|
|
+ ; \
|
|
|
+ for (i = 0; attrs[i]; i++) { \
|
|
|
+ if ((c) != *attrs[i] && charray_inlist((inattrs), attrs[i]) && \
|
|
|
+ !charray_inlist((exattrs), attrs[i])) { \
|
|
|
+ _ger_get_attr_rights(gerpb, e, subjectndn, attrs[i], \
|
|
|
+ gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf); \
|
|
|
+ isfirstattr = 0; \
|
|
|
+ } \
|
|
|
+ }
|
|
|
|
|
|
void
|
|
|
-_ger_get_attrs_rights (
|
|
|
- Slapi_PBlock *gerpb,
|
|
|
- Slapi_Entry *e,
|
|
|
- const char *subjectndn,
|
|
|
- char **attrs,
|
|
|
- char **gerstr,
|
|
|
- size_t *gerstrsize,
|
|
|
- size_t *gerstrcap,
|
|
|
- char **errbuf
|
|
|
- )
|
|
|
+_ger_get_attrs_rights(
|
|
|
+ Slapi_PBlock *gerpb,
|
|
|
+ Slapi_Entry *e,
|
|
|
+ const char *subjectndn,
|
|
|
+ char **attrs,
|
|
|
+ char **gerstr,
|
|
|
+ size_t *gerstrsize,
|
|
|
+ size_t *gerstrcap,
|
|
|
+ char **errbuf)
|
|
|
{
|
|
|
- int isfirstattr = 1;
|
|
|
-
|
|
|
- /* gerstr was initially allocated with enough space for one more line */
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "attributeLevelRights: ", NULL);
|
|
|
-
|
|
|
- /*
|
|
|
- * If it's stated attribute list is given,
|
|
|
- * the first attr in the list should not be empty.
|
|
|
- * Otherwise, it's considered the list is not given.
|
|
|
- */
|
|
|
- if (attrs && *attrs && (strlen(*attrs) > 0))
|
|
|
- {
|
|
|
- int i = 0;
|
|
|
- char **allattrs = NULL;
|
|
|
- char **opattrs = NULL;
|
|
|
- char **noexpattrs = NULL; /* attrs not to expose */
|
|
|
- char **myattrs = NULL;
|
|
|
- char **thisattr = NULL;
|
|
|
- int hasstar = charray_inlist(attrs, "*");
|
|
|
- int hasplus = charray_inlist(attrs, "+");
|
|
|
- Slapi_Attr *objclasses = NULL;
|
|
|
- Slapi_ValueSet *objclassvals = NULL;
|
|
|
- int isextensibleobj = 0;
|
|
|
-
|
|
|
- /* get all attrs available for the entry */
|
|
|
- slapi_entry_attr_find(e, "objectclass", &objclasses);
|
|
|
- if (NULL != objclasses) {
|
|
|
- Slapi_Value *v;
|
|
|
- slapi_attr_get_valueset(objclasses, &objclassvals);
|
|
|
- i = slapi_valueset_first_value(objclassvals, &v);
|
|
|
- if (-1 != i)
|
|
|
- {
|
|
|
- const char *ocname = NULL;
|
|
|
- allattrs = slapi_schema_list_objectclass_attributes(
|
|
|
- (const char *)v->bv.bv_val,
|
|
|
- SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED);
|
|
|
- /* check if this entry is an extensble object or not */
|
|
|
- ocname = slapi_value_get_string(v);
|
|
|
- if ( strcasecmp( ocname, "extensibleobject" ) == 0 )
|
|
|
- {
|
|
|
- isextensibleobj = 1;
|
|
|
- }
|
|
|
- /* add "aci" to the allattrs to adjust to do_search */
|
|
|
- charray_add(&allattrs, slapi_attr_syntax_normalize("aci"));
|
|
|
- while (-1 != i)
|
|
|
- {
|
|
|
- i = slapi_valueset_next_value(objclassvals, i, &v);
|
|
|
- if (-1 != i)
|
|
|
- {
|
|
|
- myattrs = slapi_schema_list_objectclass_attributes(
|
|
|
- (const char *)v->bv.bv_val,
|
|
|
- SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED);
|
|
|
- /* check if this entry is an extensble object or not */
|
|
|
- ocname = slapi_value_get_string(v);
|
|
|
- if ( strcasecmp( ocname, "extensibleobject" ) == 0 )
|
|
|
- {
|
|
|
- isextensibleobj = 1;
|
|
|
- }
|
|
|
- charray_merge_nodup(&allattrs, myattrs, 1/*copy_strs*/);
|
|
|
- charray_free(myattrs);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- slapi_valueset_free(objclassvals);
|
|
|
- }
|
|
|
-
|
|
|
- /* get operational attrs */
|
|
|
- opattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_OPATTR);
|
|
|
- noexpattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_NOEXPOSE);
|
|
|
- /* subtract no expose attrs from opattrs (e.g., unhashed pw) */
|
|
|
- charray_subtract(opattrs, noexpattrs, NULL);
|
|
|
-
|
|
|
- if (isextensibleobj)
|
|
|
- {
|
|
|
- for ( i = 0; attrs[i]; i++ )
|
|
|
- {
|
|
|
- if ('\0' == *attrs[i]) {
|
|
|
- continue; /* skip an empty attr */
|
|
|
- }
|
|
|
- _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i], gerstr,
|
|
|
- gerstrsize, gerstrcap, isfirstattr, errbuf );
|
|
|
- isfirstattr = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (hasstar && hasplus)
|
|
|
- {
|
|
|
- GER_GET_ATTR_RIGHTS(allattrs);
|
|
|
- GER_GET_ATTR_RIGHTS(opattrs);
|
|
|
- }
|
|
|
- else if (hasstar)
|
|
|
- {
|
|
|
- GER_GET_ATTR_RIGHTS(allattrs);
|
|
|
- GER_GET_ATTR_RIGHTA_EXT('*', opattrs, allattrs);
|
|
|
- }
|
|
|
- else if (hasplus)
|
|
|
- {
|
|
|
- GER_GET_ATTR_RIGHTS(opattrs);
|
|
|
- GER_GET_ATTR_RIGHTA_EXT('+', allattrs, opattrs);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- for ( i = 0; attrs[i]; i++ )
|
|
|
- {
|
|
|
- if ('\0' == *attrs[i]) {
|
|
|
- continue; /* skip an empty attr */
|
|
|
- }
|
|
|
- if (charray_inlist(noexpattrs, attrs[i]))
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- else if (charray_inlist(allattrs, attrs[i]) ||
|
|
|
- charray_inlist(opattrs, attrs[i]) ||
|
|
|
- (0 == strcasecmp(attrs[i], "dn")) ||
|
|
|
- (0 == strcasecmp(attrs[i], "distinguishedName")))
|
|
|
- {
|
|
|
- _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i],
|
|
|
- gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf );
|
|
|
- isfirstattr = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* if the attr does not belong to the entry,
|
|
|
- "<attr>:none" is returned */
|
|
|
- if (!isfirstattr)
|
|
|
- {
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, ", ", NULL);
|
|
|
- }
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, attrs[i], ":");
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
|
|
|
- isfirstattr = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- charray_free(allattrs);
|
|
|
- charray_free(opattrs);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Slapi_Attr *prevattr = NULL, *attr;
|
|
|
- char *type;
|
|
|
-
|
|
|
- while ( slapi_entry_next_attr ( e, prevattr, &attr ) == 0 )
|
|
|
- {
|
|
|
- if ( ! slapi_attr_flag_is_set (attr, SLAPI_ATTR_FLAG_OPATTR) )
|
|
|
- {
|
|
|
- slapi_attr_get_type ( attr, &type );
|
|
|
- _ger_get_attr_rights ( gerpb, e, subjectndn, type, gerstr,
|
|
|
- gerstrsize, gerstrcap, isfirstattr, errbuf );
|
|
|
- isfirstattr = 0;
|
|
|
- }
|
|
|
- prevattr = attr;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ( isfirstattr )
|
|
|
- {
|
|
|
- /* not a single attribute was retrived or specified */
|
|
|
- _append_gerstr(gerstr, gerstrsize, gerstrcap, "*:none", NULL);
|
|
|
- }
|
|
|
- return;
|
|
|
+ int isfirstattr = 1;
|
|
|
+
|
|
|
+ /* gerstr was initially allocated with enough space for one more line */
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "attributeLevelRights: ", NULL);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If it's stated attribute list is given,
|
|
|
+ * the first attr in the list should not be empty.
|
|
|
+ * Otherwise, it's considered the list is not given.
|
|
|
+ */
|
|
|
+ if (attrs && *attrs && (strlen(*attrs) > 0)) {
|
|
|
+ int i = 0;
|
|
|
+ char **allattrs = NULL;
|
|
|
+ char **opattrs = NULL;
|
|
|
+ char **noexpattrs = NULL; /* attrs not to expose */
|
|
|
+ char **myattrs = NULL;
|
|
|
+ char **thisattr = NULL;
|
|
|
+ int hasstar = charray_inlist(attrs, "*");
|
|
|
+ int hasplus = charray_inlist(attrs, "+");
|
|
|
+ Slapi_Attr *objclasses = NULL;
|
|
|
+ Slapi_ValueSet *objclassvals = NULL;
|
|
|
+ int isextensibleobj = 0;
|
|
|
+
|
|
|
+ /* get all attrs available for the entry */
|
|
|
+ slapi_entry_attr_find(e, "objectclass", &objclasses);
|
|
|
+ if (NULL != objclasses) {
|
|
|
+ Slapi_Value *v;
|
|
|
+ slapi_attr_get_valueset(objclasses, &objclassvals);
|
|
|
+ i = slapi_valueset_first_value(objclassvals, &v);
|
|
|
+ if (-1 != i) {
|
|
|
+ const char *ocname = NULL;
|
|
|
+ allattrs = slapi_schema_list_objectclass_attributes(
|
|
|
+ (const char *)v->bv.bv_val,
|
|
|
+ SLAPI_OC_FLAG_REQUIRED | SLAPI_OC_FLAG_ALLOWED);
|
|
|
+ /* check if this entry is an extensble object or not */
|
|
|
+ ocname = slapi_value_get_string(v);
|
|
|
+ if (strcasecmp(ocname, "extensibleobject") == 0) {
|
|
|
+ isextensibleobj = 1;
|
|
|
+ }
|
|
|
+ /* add "aci" to the allattrs to adjust to do_search */
|
|
|
+ charray_add(&allattrs, slapi_attr_syntax_normalize("aci"));
|
|
|
+ while (-1 != i) {
|
|
|
+ i = slapi_valueset_next_value(objclassvals, i, &v);
|
|
|
+ if (-1 != i) {
|
|
|
+ myattrs = slapi_schema_list_objectclass_attributes(
|
|
|
+ (const char *)v->bv.bv_val,
|
|
|
+ SLAPI_OC_FLAG_REQUIRED | SLAPI_OC_FLAG_ALLOWED);
|
|
|
+ /* check if this entry is an extensble object or not */
|
|
|
+ ocname = slapi_value_get_string(v);
|
|
|
+ if (strcasecmp(ocname, "extensibleobject") == 0) {
|
|
|
+ isextensibleobj = 1;
|
|
|
+ }
|
|
|
+ charray_merge_nodup(&allattrs, myattrs, 1 /*copy_strs*/);
|
|
|
+ charray_free(myattrs);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ slapi_valueset_free(objclassvals);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* get operational attrs */
|
|
|
+ opattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_OPATTR);
|
|
|
+ noexpattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_NOEXPOSE);
|
|
|
+ /* subtract no expose attrs from opattrs (e.g., unhashed pw) */
|
|
|
+ charray_subtract(opattrs, noexpattrs, NULL);
|
|
|
+
|
|
|
+ if (isextensibleobj) {
|
|
|
+ for (i = 0; attrs[i]; i++) {
|
|
|
+ if ('\0' == *attrs[i]) {
|
|
|
+ continue; /* skip an empty attr */
|
|
|
+ }
|
|
|
+ _ger_get_attr_rights(gerpb, e, subjectndn, attrs[i], gerstr,
|
|
|
+ gerstrsize, gerstrcap, isfirstattr, errbuf);
|
|
|
+ isfirstattr = 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (hasstar && hasplus) {
|
|
|
+ GER_GET_ATTR_RIGHTS(allattrs);
|
|
|
+ GER_GET_ATTR_RIGHTS(opattrs);
|
|
|
+ } else if (hasstar) {
|
|
|
+ GER_GET_ATTR_RIGHTS(allattrs);
|
|
|
+ GER_GET_ATTR_RIGHTA_EXT('*', opattrs, allattrs);
|
|
|
+ } else if (hasplus) {
|
|
|
+ GER_GET_ATTR_RIGHTS(opattrs);
|
|
|
+ GER_GET_ATTR_RIGHTA_EXT('+', allattrs, opattrs);
|
|
|
+ } else {
|
|
|
+ for (i = 0; attrs[i]; i++) {
|
|
|
+ if ('\0' == *attrs[i]) {
|
|
|
+ continue; /* skip an empty attr */
|
|
|
+ }
|
|
|
+ if (charray_inlist(noexpattrs, attrs[i])) {
|
|
|
+ continue;
|
|
|
+ } else if (charray_inlist(allattrs, attrs[i]) ||
|
|
|
+ charray_inlist(opattrs, attrs[i]) ||
|
|
|
+ (0 == strcasecmp(attrs[i], "dn")) ||
|
|
|
+ (0 == strcasecmp(attrs[i], "distinguishedName"))) {
|
|
|
+ _ger_get_attr_rights(gerpb, e, subjectndn, attrs[i],
|
|
|
+ gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf);
|
|
|
+ isfirstattr = 0;
|
|
|
+ } else {
|
|
|
+ /* if the attr does not belong to the entry,
|
|
|
+ "<attr>:none" is returned */
|
|
|
+ if (!isfirstattr) {
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, ", ", NULL);
|
|
|
+ }
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, attrs[i], ":");
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
|
|
|
+ isfirstattr = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ charray_free(allattrs);
|
|
|
+ charray_free(opattrs);
|
|
|
+ } else {
|
|
|
+ Slapi_Attr *prevattr = NULL, *attr;
|
|
|
+ char *type;
|
|
|
+
|
|
|
+ while (slapi_entry_next_attr(e, prevattr, &attr) == 0) {
|
|
|
+ if (!slapi_attr_flag_is_set(attr, SLAPI_ATTR_FLAG_OPATTR)) {
|
|
|
+ slapi_attr_get_type(attr, &type);
|
|
|
+ _ger_get_attr_rights(gerpb, e, subjectndn, type, gerstr,
|
|
|
+ gerstrsize, gerstrcap, isfirstattr, errbuf);
|
|
|
+ isfirstattr = 0;
|
|
|
+ }
|
|
|
+ prevattr = attr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isfirstattr) {
|
|
|
+ /* not a single attribute was retrived or specified */
|
|
|
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "*:none", NULL);
|
|
|
+ }
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* controlType = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS;
|
|
|
* criticality = n/a;
|
|
|
* controlValue = OCTET STRING of BER encoding of the SEQUENCE of
|
|
|
- * ENUMERATED LDAP code
|
|
|
+ * ENUMERATED LDAP code
|
|
|
*/
|
|
|
void
|
|
|
-_ger_set_response_control (
|
|
|
- Slapi_PBlock *pb,
|
|
|
- int iscritical,
|
|
|
- int rc
|
|
|
- )
|
|
|
+_ger_set_response_control(
|
|
|
+ Slapi_PBlock *pb,
|
|
|
+ int iscritical,
|
|
|
+ int rc)
|
|
|
{
|
|
|
- LDAPControl **resultctrls = NULL;
|
|
|
- LDAPControl gerrespctrl;
|
|
|
- BerElement *ber = NULL;
|
|
|
- struct berval *berval = NULL;
|
|
|
- int found = 0;
|
|
|
- int i;
|
|
|
-
|
|
|
- if ( (ber = der_alloc ()) == NULL )
|
|
|
- {
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- /* begin sequence, enumeration, end sequence */
|
|
|
- ber_printf ( ber, "{e}", rc );
|
|
|
- if ( ber_flatten ( ber, &berval ) != LDAP_SUCCESS )
|
|
|
- {
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- gerrespctrl.ldctl_oid = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS;
|
|
|
- gerrespctrl.ldctl_iscritical = iscritical;
|
|
|
- gerrespctrl.ldctl_value.bv_val = berval->bv_val;
|
|
|
- gerrespctrl.ldctl_value.bv_len = berval->bv_len;
|
|
|
-
|
|
|
- slapi_pblock_get ( pb, SLAPI_RESCONTROLS, &resultctrls );
|
|
|
- for (i = 0; resultctrls && resultctrls[i]; i++)
|
|
|
- {
|
|
|
- if (strcmp(resultctrls[i]->ldctl_oid, LDAP_CONTROL_GET_EFFECTIVE_RIGHTS) == 0)
|
|
|
- {
|
|
|
- /*
|
|
|
- * We get here if search returns more than one entry
|
|
|
- * and this is not the first entry.
|
|
|
- */
|
|
|
- ldap_control_free ( resultctrls[i] );
|
|
|
- resultctrls[i] = slapi_dup_control (&gerrespctrl);
|
|
|
- found = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ( !found )
|
|
|
- {
|
|
|
- /* slapi_pblock_set() will dup the control */
|
|
|
- slapi_pblock_set ( pb, SLAPI_ADD_RESCONTROL, &gerrespctrl );
|
|
|
- }
|
|
|
+ LDAPControl **resultctrls = NULL;
|
|
|
+ LDAPControl gerrespctrl;
|
|
|
+ BerElement *ber = NULL;
|
|
|
+ struct berval *berval = NULL;
|
|
|
+ int found = 0;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if ((ber = der_alloc()) == NULL) {
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* begin sequence, enumeration, end sequence */
|
|
|
+ ber_printf(ber, "{e}", rc);
|
|
|
+ if (ber_flatten(ber, &berval) != LDAP_SUCCESS) {
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ gerrespctrl.ldctl_oid = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS;
|
|
|
+ gerrespctrl.ldctl_iscritical = iscritical;
|
|
|
+ gerrespctrl.ldctl_value.bv_val = berval->bv_val;
|
|
|
+ gerrespctrl.ldctl_value.bv_len = berval->bv_len;
|
|
|
+
|
|
|
+ slapi_pblock_get(pb, SLAPI_RESCONTROLS, &resultctrls);
|
|
|
+ for (i = 0; resultctrls && resultctrls[i]; i++) {
|
|
|
+ if (strcmp(resultctrls[i]->ldctl_oid, LDAP_CONTROL_GET_EFFECTIVE_RIGHTS) == 0) {
|
|
|
+ /*
|
|
|
+ * We get here if search returns more than one entry
|
|
|
+ * and this is not the first entry.
|
|
|
+ */
|
|
|
+ ldap_control_free(resultctrls[i]);
|
|
|
+ resultctrls[i] = slapi_dup_control(&gerrespctrl);
|
|
|
+ found = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!found) {
|
|
|
+ /* slapi_pblock_set() will dup the control */
|
|
|
+ slapi_pblock_set(pb, SLAPI_ADD_RESCONTROL, &gerrespctrl);
|
|
|
+ }
|
|
|
|
|
|
bailout:
|
|
|
- ber_free ( ber, 1 ); /* ber_free() checks for NULL param */
|
|
|
- ber_bvfree ( berval ); /* ber_bvfree() checks for NULL param */
|
|
|
+ ber_free(ber, 1); /* ber_free() checks for NULL param */
|
|
|
+ ber_bvfree(berval); /* ber_bvfree() checks for NULL param */
|
|
|
}
|
|
|
|
|
|
int
|
|
|
-_ger_generate_template_entry (
|
|
|
- Slapi_PBlock *pb
|
|
|
- )
|
|
|
+_ger_generate_template_entry(
|
|
|
+ Slapi_PBlock *pb)
|
|
|
{
|
|
|
- Slapi_Entry *e = NULL;
|
|
|
- char **gerattrs = NULL;
|
|
|
- char **attrs = NULL;
|
|
|
- char **allowedattrs = NULL;
|
|
|
- char *templateentry = NULL;
|
|
|
- char *object = NULL;
|
|
|
- char *superior = NULL;
|
|
|
- char *p = NULL;
|
|
|
- const char *dn = NULL;
|
|
|
- Slapi_DN *sdn = NULL;
|
|
|
- char *dntype = NULL;
|
|
|
- int siz = 0;
|
|
|
- int len = 0;
|
|
|
- int i = 0;
|
|
|
- int notfirst = 0;
|
|
|
- int rc = LDAP_SUCCESS;
|
|
|
-
|
|
|
- slapi_pblock_get( pb, SLAPI_SEARCH_GERATTRS, &gerattrs );
|
|
|
- if (NULL == gerattrs)
|
|
|
- {
|
|
|
- slapi_log_err(SLAPI_LOG_ERR, plugin_name,
|
|
|
- "_ger_generate_template_entry - Objectclass info is expected "
|
|
|
- "in the attr list, e.g., \"*@person\"\n");
|
|
|
- rc = LDAP_SUCCESS;
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- for (i = 0; gerattrs && gerattrs[i]; i++)
|
|
|
- {
|
|
|
- object = strchr(gerattrs[i], '@');
|
|
|
- if (NULL != object && '\0' != *(++object))
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (NULL == object)
|
|
|
- {
|
|
|
- rc = LDAP_SUCCESS; /* no objectclass info; ok to return */
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- /*
|
|
|
- * Either @objectclass or @objectclass:dntype is accepted.
|
|
|
- * If @objectclass, the first MUST attributetype (or the first MAY
|
|
|
- * attributetype if MUST does not exist) is used for the attribute
|
|
|
- * type in the leaf RDN.
|
|
|
- * If @objectclass:dntype, dntype is used for the attribute type in the
|
|
|
- * leaf RDN.
|
|
|
- */
|
|
|
- dntype = strchr(object, ':');
|
|
|
- if (dntype) { /* @objectclasse:dntype */
|
|
|
- *dntype++ = '\0';
|
|
|
- }
|
|
|
-
|
|
|
- attrs = slapi_schema_list_objectclass_attributes(
|
|
|
- (const char *)object, SLAPI_OC_FLAG_REQUIRED);
|
|
|
- allowedattrs = slapi_schema_list_objectclass_attributes(
|
|
|
- (const char *)object, SLAPI_OC_FLAG_ALLOWED);
|
|
|
- charray_merge(&attrs, allowedattrs, 0 /* no copy */);
|
|
|
- slapi_ch_free((void **)&allowedattrs); /* free just allowedattrs */
|
|
|
- if (NULL == attrs) {
|
|
|
- rc = LDAP_SUCCESS; /* bogus objectclass info; ok to return */
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- for (i = 0; attrs[i]; i++)
|
|
|
- {
|
|
|
- if (0 == strcasecmp(attrs[i], "objectclass"))
|
|
|
- {
|
|
|
- /* <*attrp>: <object>\n\0 */
|
|
|
- siz += strlen(attrs[i]) + 4 + strlen(object);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* <*attrp>: (template_attribute)\n\0 */
|
|
|
- siz += strlen(attrs[i]) + 4 + 20;
|
|
|
- }
|
|
|
- }
|
|
|
- /* get the target dn where the template entry is located */
|
|
|
- slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
|
|
|
- dn = slapi_sdn_get_dn(sdn);
|
|
|
- if (dn)
|
|
|
- {
|
|
|
- /* dn: <attr>=<template_name>,<dn>\n\0 */
|
|
|
- if (dntype) {
|
|
|
- siz += strlen(dntype) + 30 + strlen(object) + strlen(dn);
|
|
|
- } else {
|
|
|
- siz += strlen(attrs[0]) + 30 + strlen(object) + strlen(dn);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* dn: <attr>=<template_name>\n\0 */
|
|
|
- if (dntype) {
|
|
|
- siz += strlen(dntype) + 30 + strlen(object);
|
|
|
- } else {
|
|
|
- siz += strlen(attrs[0]) + 30 + strlen(object);
|
|
|
- }
|
|
|
- }
|
|
|
- templateentry = (char *)slapi_ch_malloc(siz);
|
|
|
- if (NULL != dn && strlen(dn) > 0)
|
|
|
- {
|
|
|
- PR_snprintf(templateentry, siz,
|
|
|
- "dn: %s=template_%s_objectclass,%s\n",
|
|
|
- dntype?dntype:attrs[0], object, dn);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- PR_snprintf(templateentry, siz,
|
|
|
- "dn: %s=template_%s_objectclass\n",
|
|
|
- dntype?dntype:attrs[0], object);
|
|
|
- }
|
|
|
- for (--i; i >= 0; i--)
|
|
|
- {
|
|
|
- len = strlen(templateentry);
|
|
|
- p = templateentry + len;
|
|
|
- if (0 == strcasecmp(attrs[i], "objectclass"))
|
|
|
- {
|
|
|
- PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- PR_snprintf(p, siz - len, "%s: (template_attribute)\n", attrs[i]);
|
|
|
- }
|
|
|
- }
|
|
|
- charray_free(attrs);
|
|
|
-
|
|
|
- while ((superior = slapi_schema_get_superior_name(object)) &&
|
|
|
- (0 != strcasecmp(superior, "top")))
|
|
|
- {
|
|
|
- if (notfirst)
|
|
|
- {
|
|
|
- slapi_ch_free_string(&object);
|
|
|
- }
|
|
|
- notfirst = 1;
|
|
|
- object = superior;
|
|
|
- attrs = slapi_schema_list_objectclass_attributes(
|
|
|
- (const char *)superior, SLAPI_OC_FLAG_REQUIRED);
|
|
|
- for (i = 0; attrs && attrs[i]; i++)
|
|
|
- {
|
|
|
- if (0 == strcasecmp(attrs[i], "objectclass"))
|
|
|
- {
|
|
|
- /* <*attrp>: <object>\n\0 */
|
|
|
- siz += strlen(attrs[i]) + 4 + strlen(object);
|
|
|
- }
|
|
|
- }
|
|
|
- templateentry = (char *)slapi_ch_realloc(templateentry, siz);
|
|
|
- for (--i; i >= 0; i--)
|
|
|
- {
|
|
|
- len = strlen(templateentry);
|
|
|
- p = templateentry + len;
|
|
|
- if (0 == strcasecmp(attrs[i], "objectclass"))
|
|
|
- {
|
|
|
- PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
|
|
|
- }
|
|
|
- }
|
|
|
- charray_free(attrs);
|
|
|
- }
|
|
|
- if (notfirst)
|
|
|
- {
|
|
|
- slapi_ch_free_string(&object);
|
|
|
- }
|
|
|
- slapi_ch_free_string(&superior);
|
|
|
- siz += 18; /* objectclass: top\n\0 */
|
|
|
- len = strlen(templateentry);
|
|
|
- templateentry = (char *)slapi_ch_realloc(templateentry, siz);
|
|
|
- p = templateentry + len;
|
|
|
- PR_snprintf(p, siz - len, "objectclass: top\n");
|
|
|
-
|
|
|
- e = slapi_str2entry(templateentry, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
|
|
|
- /* set the template entry to send the result to clients */
|
|
|
- slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, e);
|
|
|
+ Slapi_Entry *e = NULL;
|
|
|
+ char **gerattrs = NULL;
|
|
|
+ char **attrs = NULL;
|
|
|
+ char **allowedattrs = NULL;
|
|
|
+ char *templateentry = NULL;
|
|
|
+ char *object = NULL;
|
|
|
+ char *superior = NULL;
|
|
|
+ char *p = NULL;
|
|
|
+ const char *dn = NULL;
|
|
|
+ Slapi_DN *sdn = NULL;
|
|
|
+ char *dntype = NULL;
|
|
|
+ int siz = 0;
|
|
|
+ int len = 0;
|
|
|
+ int i = 0;
|
|
|
+ int notfirst = 0;
|
|
|
+ int rc = LDAP_SUCCESS;
|
|
|
+
|
|
|
+ slapi_pblock_get(pb, SLAPI_SEARCH_GERATTRS, &gerattrs);
|
|
|
+ if (NULL == gerattrs) {
|
|
|
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name,
|
|
|
+ "_ger_generate_template_entry - Objectclass info is expected "
|
|
|
+ "in the attr list, e.g., \"*@person\"\n");
|
|
|
+ rc = LDAP_SUCCESS;
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ for (i = 0; gerattrs && gerattrs[i]; i++) {
|
|
|
+ object = strchr(gerattrs[i], '@');
|
|
|
+ if (NULL != object && '\0' != *(++object)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (NULL == object) {
|
|
|
+ rc = LDAP_SUCCESS; /* no objectclass info; ok to return */
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * Either @objectclass or @objectclass:dntype is accepted.
|
|
|
+ * If @objectclass, the first MUST attributetype (or the first MAY
|
|
|
+ * attributetype if MUST does not exist) is used for the attribute
|
|
|
+ * type in the leaf RDN.
|
|
|
+ * If @objectclass:dntype, dntype is used for the attribute type in the
|
|
|
+ * leaf RDN.
|
|
|
+ */
|
|
|
+ dntype = strchr(object, ':');
|
|
|
+ if (dntype) { /* @objectclasse:dntype */
|
|
|
+ *dntype++ = '\0';
|
|
|
+ }
|
|
|
+
|
|
|
+ attrs = slapi_schema_list_objectclass_attributes(
|
|
|
+ (const char *)object, SLAPI_OC_FLAG_REQUIRED);
|
|
|
+ allowedattrs = slapi_schema_list_objectclass_attributes(
|
|
|
+ (const char *)object, SLAPI_OC_FLAG_ALLOWED);
|
|
|
+ charray_merge(&attrs, allowedattrs, 0 /* no copy */);
|
|
|
+ slapi_ch_free((void **)&allowedattrs); /* free just allowedattrs */
|
|
|
+ if (NULL == attrs) {
|
|
|
+ rc = LDAP_SUCCESS; /* bogus objectclass info; ok to return */
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ for (i = 0; attrs[i]; i++) {
|
|
|
+ if (0 == strcasecmp(attrs[i], "objectclass")) {
|
|
|
+ /* <*attrp>: <object>\n\0 */
|
|
|
+ siz += strlen(attrs[i]) + 4 + strlen(object);
|
|
|
+ } else {
|
|
|
+ /* <*attrp>: (template_attribute)\n\0 */
|
|
|
+ siz += strlen(attrs[i]) + 4 + 20;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* get the target dn where the template entry is located */
|
|
|
+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
|
|
+ dn = slapi_sdn_get_dn(sdn);
|
|
|
+ if (dn) {
|
|
|
+ /* dn: <attr>=<template_name>,<dn>\n\0 */
|
|
|
+ if (dntype) {
|
|
|
+ siz += strlen(dntype) + 30 + strlen(object) + strlen(dn);
|
|
|
+ } else {
|
|
|
+ siz += strlen(attrs[0]) + 30 + strlen(object) + strlen(dn);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* dn: <attr>=<template_name>\n\0 */
|
|
|
+ if (dntype) {
|
|
|
+ siz += strlen(dntype) + 30 + strlen(object);
|
|
|
+ } else {
|
|
|
+ siz += strlen(attrs[0]) + 30 + strlen(object);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ templateentry = (char *)slapi_ch_malloc(siz);
|
|
|
+ if (NULL != dn && strlen(dn) > 0) {
|
|
|
+ PR_snprintf(templateentry, siz,
|
|
|
+ "dn: %s=template_%s_objectclass,%s\n",
|
|
|
+ dntype ? dntype : attrs[0], object, dn);
|
|
|
+ } else {
|
|
|
+ PR_snprintf(templateentry, siz,
|
|
|
+ "dn: %s=template_%s_objectclass\n",
|
|
|
+ dntype ? dntype : attrs[0], object);
|
|
|
+ }
|
|
|
+ for (--i; i >= 0; i--) {
|
|
|
+ len = strlen(templateentry);
|
|
|
+ p = templateentry + len;
|
|
|
+ if (0 == strcasecmp(attrs[i], "objectclass")) {
|
|
|
+ PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
|
|
|
+ } else {
|
|
|
+ PR_snprintf(p, siz - len, "%s: (template_attribute)\n", attrs[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ charray_free(attrs);
|
|
|
+
|
|
|
+ while ((superior = slapi_schema_get_superior_name(object)) &&
|
|
|
+ (0 != strcasecmp(superior, "top"))) {
|
|
|
+ if (notfirst) {
|
|
|
+ slapi_ch_free_string(&object);
|
|
|
+ }
|
|
|
+ notfirst = 1;
|
|
|
+ object = superior;
|
|
|
+ attrs = slapi_schema_list_objectclass_attributes(
|
|
|
+ (const char *)superior, SLAPI_OC_FLAG_REQUIRED);
|
|
|
+ for (i = 0; attrs && attrs[i]; i++) {
|
|
|
+ if (0 == strcasecmp(attrs[i], "objectclass")) {
|
|
|
+ /* <*attrp>: <object>\n\0 */
|
|
|
+ siz += strlen(attrs[i]) + 4 + strlen(object);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ templateentry = (char *)slapi_ch_realloc(templateentry, siz);
|
|
|
+ for (--i; i >= 0; i--) {
|
|
|
+ len = strlen(templateentry);
|
|
|
+ p = templateentry + len;
|
|
|
+ if (0 == strcasecmp(attrs[i], "objectclass")) {
|
|
|
+ PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ charray_free(attrs);
|
|
|
+ }
|
|
|
+ if (notfirst) {
|
|
|
+ slapi_ch_free_string(&object);
|
|
|
+ }
|
|
|
+ slapi_ch_free_string(&superior);
|
|
|
+ siz += 18; /* objectclass: top\n\0 */
|
|
|
+ len = strlen(templateentry);
|
|
|
+ templateentry = (char *)slapi_ch_realloc(templateentry, siz);
|
|
|
+ p = templateentry + len;
|
|
|
+ PR_snprintf(p, siz - len, "objectclass: top\n");
|
|
|
+
|
|
|
+ e = slapi_str2entry(templateentry, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
|
|
|
+ /* set the template entry to send the result to clients */
|
|
|
+ slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, e);
|
|
|
bailout:
|
|
|
- slapi_ch_free_string(&templateentry);
|
|
|
- return rc;
|
|
|
+ slapi_ch_free_string(&templateentry);
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
-acl_get_effective_rights (
|
|
|
- Slapi_PBlock *pb,
|
|
|
- Slapi_Entry *e, /* target entry */
|
|
|
- char **attrs, /* Attribute of the entry */
|
|
|
- struct berval *val __attribute__((unused)), /* value of attr. NOT USED */
|
|
|
- int access __attribute__((unused)), /* requested access rights */
|
|
|
- char **errbuf
|
|
|
- )
|
|
|
+acl_get_effective_rights(
|
|
|
+ Slapi_PBlock *pb,
|
|
|
+ Slapi_Entry *e, /* target entry */
|
|
|
+ char **attrs, /* Attribute of the entry */
|
|
|
+ struct berval *val __attribute__((unused)), /* value of attr. NOT USED */
|
|
|
+ int access __attribute__((unused)), /* requested access rights */
|
|
|
+ char **errbuf)
|
|
|
{
|
|
|
- Slapi_PBlock *gerpb = NULL;
|
|
|
- void *aclcb = NULL;
|
|
|
- char *subjectndn = NULL;
|
|
|
- char *gerstr = NULL;
|
|
|
- size_t gerstrsize = 0;
|
|
|
- size_t gerstrcap = 0;
|
|
|
- int iscritical = 0; /* critical may be missing or false http://tools.ietf.org/html/draft-ietf-ldapext-acl-model-08 */
|
|
|
- int rc = LDAP_SUCCESS;
|
|
|
-
|
|
|
- *errbuf = NULL;
|
|
|
-
|
|
|
- if (NULL == e) /* create a template entry from SLAPI_SEARCH_GERATTRS */
|
|
|
- {
|
|
|
- rc = _ger_generate_template_entry ( pb );
|
|
|
- slapi_pblock_get ( pb, SLAPI_SEARCH_RESULT_ENTRY, &e );
|
|
|
- if ( rc != LDAP_SUCCESS || NULL == e )
|
|
|
- {
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Get the subject
|
|
|
- */
|
|
|
- rc = _ger_parse_control (pb, &subjectndn, &iscritical, errbuf );
|
|
|
- if ( rc != LDAP_SUCCESS )
|
|
|
- {
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * The requestor should have g permission on the entry
|
|
|
- * to get the effective rights.
|
|
|
- */
|
|
|
- rc = _ger_g_permission_granted (pb, e, subjectndn, errbuf);
|
|
|
- if ( rc != LDAP_SUCCESS )
|
|
|
- {
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Construct a new pb
|
|
|
- */
|
|
|
- rc = _ger_new_gerpb ( pb, e, subjectndn, &gerpb, &aclcb, errbuf );
|
|
|
- if ( rc != LDAP_SUCCESS )
|
|
|
- {
|
|
|
- goto bailout;
|
|
|
- }
|
|
|
-
|
|
|
- /* Get entry level effective rights */
|
|
|
- _ger_get_entry_rights ( gerpb, e, subjectndn, &gerstr, &gerstrsize, &gerstrcap, errbuf );
|
|
|
-
|
|
|
- /*
|
|
|
- * Attribute level effective rights may not be NULL
|
|
|
- * even if entry level's is.
|
|
|
- */
|
|
|
- _ger_get_attrs_rights ( gerpb, e, subjectndn, attrs, &gerstr, &gerstrsize, &gerstrcap, errbuf );
|
|
|
+ Slapi_PBlock *gerpb = NULL;
|
|
|
+ void *aclcb = NULL;
|
|
|
+ char *subjectndn = NULL;
|
|
|
+ char *gerstr = NULL;
|
|
|
+ size_t gerstrsize = 0;
|
|
|
+ size_t gerstrcap = 0;
|
|
|
+ int iscritical = 0; /* critical may be missing or false http://tools.ietf.org/html/draft-ietf-ldapext-acl-model-08 */
|
|
|
+ int rc = LDAP_SUCCESS;
|
|
|
+
|
|
|
+ *errbuf = NULL;
|
|
|
+
|
|
|
+ if (NULL == e) /* create a template entry from SLAPI_SEARCH_GERATTRS */
|
|
|
+ {
|
|
|
+ rc = _ger_generate_template_entry(pb);
|
|
|
+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
|
|
|
+ if (rc != LDAP_SUCCESS || NULL == e) {
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get the subject
|
|
|
+ */
|
|
|
+ rc = _ger_parse_control(pb, &subjectndn, &iscritical, errbuf);
|
|
|
+ if (rc != LDAP_SUCCESS) {
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The requestor should have g permission on the entry
|
|
|
+ * to get the effective rights.
|
|
|
+ */
|
|
|
+ rc = _ger_g_permission_granted(pb, e, subjectndn, errbuf);
|
|
|
+ if (rc != LDAP_SUCCESS) {
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Construct a new pb
|
|
|
+ */
|
|
|
+ rc = _ger_new_gerpb(pb, e, subjectndn, &gerpb, &aclcb, errbuf);
|
|
|
+ if (rc != LDAP_SUCCESS) {
|
|
|
+ goto bailout;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Get entry level effective rights */
|
|
|
+ _ger_get_entry_rights(gerpb, e, subjectndn, &gerstr, &gerstrsize, &gerstrcap, errbuf);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Attribute level effective rights may not be NULL
|
|
|
+ * even if entry level's is.
|
|
|
+ */
|
|
|
+ _ger_get_attrs_rights(gerpb, e, subjectndn, attrs, &gerstr, &gerstrsize, &gerstrcap, errbuf);
|
|
|
|
|
|
bailout:
|
|
|
- /*
|
|
|
- * Now construct the response control
|
|
|
- */
|
|
|
- _ger_set_response_control ( pb, iscritical, rc );
|
|
|
-
|
|
|
- if ( rc != LDAP_SUCCESS )
|
|
|
- {
|
|
|
- gerstr = slapi_ch_smprintf("entryLevelRights: %d\nattributeLevelRights: *:%d", rc, rc );
|
|
|
- }
|
|
|
-
|
|
|
- slapi_log_err(SLAPI_LOG_ACLSUMMARY, plugin_name,
|
|
|
- "###### Effective Rights on Entry (%s) for Subject (%s) ######\n",
|
|
|
- e?slapi_entry_get_ndn(e):"null", subjectndn?subjectndn:"null");
|
|
|
- slapi_log_err(SLAPI_LOG_ACLSUMMARY, plugin_name, "%s\n", gerstr);
|
|
|
-
|
|
|
- /* Restore pb */
|
|
|
- _ger_release_gerpb ( &gerpb, &aclcb, pb );
|
|
|
-
|
|
|
- /*
|
|
|
- * General plugin uses SLAPI_RESULT_TEXT for error text. Here
|
|
|
- * SLAPI_PB_RESULT_TEXT is exclusively shared with add, dse and schema.
|
|
|
- * slapi_pblock_set() will free any previous data, and
|
|
|
- * pblock_done() will free SLAPI_PB_RESULT_TEXT.
|
|
|
- */
|
|
|
- slapi_pblock_set (pb, SLAPI_PB_RESULT_TEXT, gerstr);
|
|
|
-
|
|
|
- if ( !iscritical )
|
|
|
- {
|
|
|
- /*
|
|
|
- * If return code is not LDAP_SUCCESS, the server would
|
|
|
- * abort sending the data of the entry to the client.
|
|
|
- */
|
|
|
- rc = LDAP_SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
- slapi_ch_free ( (void **) &subjectndn );
|
|
|
- slapi_ch_free ( (void **) &gerstr );
|
|
|
- return rc;
|
|
|
+ /*
|
|
|
+ * Now construct the response control
|
|
|
+ */
|
|
|
+ _ger_set_response_control(pb, iscritical, rc);
|
|
|
+
|
|
|
+ if (rc != LDAP_SUCCESS) {
|
|
|
+ gerstr = slapi_ch_smprintf("entryLevelRights: %d\nattributeLevelRights: *:%d", rc, rc);
|
|
|
+ }
|
|
|
+
|
|
|
+ slapi_log_err(SLAPI_LOG_ACLSUMMARY, plugin_name,
|
|
|
+ "###### Effective Rights on Entry (%s) for Subject (%s) ######\n",
|
|
|
+ e ? slapi_entry_get_ndn(e) : "null", subjectndn ? subjectndn : "null");
|
|
|
+ slapi_log_err(SLAPI_LOG_ACLSUMMARY, plugin_name, "%s\n", gerstr);
|
|
|
+
|
|
|
+ /* Restore pb */
|
|
|
+ _ger_release_gerpb(&gerpb, &aclcb, pb);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * General plugin uses SLAPI_RESULT_TEXT for error text. Here
|
|
|
+ * SLAPI_PB_RESULT_TEXT is exclusively shared with add, dse and schema.
|
|
|
+ * slapi_pblock_set() will free any previous data, and
|
|
|
+ * pblock_done() will free SLAPI_PB_RESULT_TEXT.
|
|
|
+ */
|
|
|
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr);
|
|
|
+
|
|
|
+ if (!iscritical) {
|
|
|
+ /*
|
|
|
+ * If return code is not LDAP_SUCCESS, the server would
|
|
|
+ * abort sending the data of the entry to the client.
|
|
|
+ */
|
|
|
+ rc = LDAP_SUCCESS;
|
|
|
+ }
|
|
|
+
|
|
|
+ slapi_ch_free((void **)&subjectndn);
|
|
|
+ slapi_ch_free((void **)&gerstr);
|
|
|
+ return rc;
|
|
|
}
|