summaryrefslogtreecommitdiffstats
path: root/ldap/servers/plugins/acl
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-04-26 11:03:52 -0700
committerNoriko Hosoi <nhosoi@redhat.com>2010-04-26 11:03:52 -0700
commit78c50664d6421cc5d0836bb03820680dc2cb7acf (patch)
tree20fcfadad9057617daa0b159216f0a92006969f5 /ldap/servers/plugins/acl
parent4754291972668c37559a8f68d75ac6f8c477efb8 (diff)
downloadds-78c50664d6421cc5d0836bb03820680dc2cb7acf.tar.gz
ds-78c50664d6421cc5d0836bb03820680dc2cb7acf.tar.xz
ds-78c50664d6421cc5d0836bb03820680dc2cb7acf.zip
Update to New DN Format
Fix Description: . adding slapi_dn_normalize_ext and its siblings to normalize/validate invalid DNs; deprecating slapi_dn_normalize and its siblings. (dn.c) . replacing slapi_dn_normalize with new corresponding functions. . normalizing hardcoded DNs (e.g., removing spaces around ',') . setting correct DN syntax to nsslapd-suffix, nsslapd-ldapiautodnsuffix, costemplatedn, nsslapd-changelogsuffix, nsBaseDN, nsBindDN . if nsslapd-dn-validate-strict is enabled, incoming DN is examined and rejected if it is invalid. Once approved, the DN is normalized. . fixing compiler warnings and typos. See also: http://directory.fedoraproject.org/wiki/Upgrade_to_New_DN_Format Related bugs: Bug 199923 - subtree search fails to find items under a db containing special characters Bug 567968 - subtree/user level password policy created using 389-ds-console doesn't work. Bug 570107 - The import of LDIFs with base-64 encoded DNs fails, modrdn with non-ASCII new rdn incorrect Bug 570962 - ns-inactivate.pl does not work Bug 572785 - DN syntax: old style of DN <type>="<DN>",<the_rest> is not correctly normalized Bug 573060 - DN normalizer: ESC HEX HEX is not normalized Bug 574167 - An escaped space at the end of the RDN value is not handled correctly
Diffstat (limited to 'ldap/servers/plugins/acl')
-rw-r--r--ldap/servers/plugins/acl/acl.c56
-rw-r--r--ldap/servers/plugins/acl/acl.h7
-rw-r--r--ldap/servers/plugins/acl/acl_ext.c2
-rw-r--r--ldap/servers/plugins/acl/aclanom.c1
-rw-r--r--ldap/servers/plugins/acl/acleffectiverights.c47
-rw-r--r--ldap/servers/plugins/acl/acllas.c201
-rw-r--r--ldap/servers/plugins/acl/aclparse.c386
-rw-r--r--ldap/servers/plugins/acl/aclproxy.c17
-rw-r--r--ldap/servers/plugins/acl/aclutil.c66
9 files changed, 516 insertions, 267 deletions
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index aa22d566..715ad1ea 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -358,8 +358,8 @@ acl_access_allowed(
if (oid && ((strcasecmp(oid, DN_SYNTAX_OID) == 0) ||
(strcasecmp(oid, NAMEANDOPTIONALUID_SYNTAX_OID) == 0))) {
/* should use slapi_sdn_compare() but that'a an extra malloc/free */
- char *dn_val_to_write = slapi_dn_normalize(slapi_ch_strdup(val->bv_val));
- if ( aclpb->aclpb_authorization_sdn &&
+ char *dn_val_to_write = slapi_create_dn_string("%s", val->bv_val);
+ if ( dn_val_to_write && aclpb->aclpb_authorization_sdn &&
slapi_utf8casecmp((ACLUCHP)dn_val_to_write, (ACLUCHP)
slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)) == 0) {
access |= SLAPI_ACL_SELF;
@@ -754,9 +754,10 @@ static void print_access_control_summary( char *source, int ret_val, char *clien
if ( aclpb->aclpb_authorization_sdn != NULL ) {
- proxy_user = (char *)(aclpb->aclpb_authorization_sdn->ndn ?
- aclpb->aclpb_authorization_sdn->ndn:
- null_user);
+ proxy_user =
+ (char *)(slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)?
+ slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn):
+ null_user);
slapi_log_error(loglevel, plugin_name,
"conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
@@ -1764,8 +1765,7 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
if (parent_DN == NULL) {
new_DN = new_RDN;
} else {
- new_DN = slapi_ch_smprintf("%s,%s", new_RDN, parent_DN);
- slapi_dn_normalize (new_DN);
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
}
/* Change the acls */
@@ -2028,8 +2028,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
** We have a single ACI which we need to find if it applies to
** the resource or not.
*/
- if ((aci->aci_type & ACI_TARGET_DN) &&
- (aclpb->aclpb_curr_entry_sdn)) {
+ if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) {
char *avaType;
struct berval *avaValue;
@@ -2246,10 +2245,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*
*/
- if ((aclpb->aclpb_access & SLAPI_ACL_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS )||
- (aclpb->aclpb_access & SLAPI_ACL_DELETE &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ if (((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) )||
+ ((aclpb->aclpb_access & SLAPI_ACL_DELETE) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) ) ) {
Targetattrfilter **attrFilterArray;
@@ -2367,10 +2366,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
goto acl__resource_match_aci_EXIT;
}
- } else if ( (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) ||
- (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ } else if ( ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
+ ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) ) {
/*
@@ -2381,28 +2380,28 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
* match that filter.
*
*
- */
+ */
Targetattrfilter **attrFilterArray = NULL;
Targetattrfilter *attrFilter;
int found = 0;
- if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) {
+ if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) {
- attrFilterArray = aci->targetAttrAddFilters;
+ attrFilterArray = aci->targetAttrAddFilters;
- } else if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) {
+ } else if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) {
- attrFilterArray = aci->targetAttrDelFilters;
+ attrFilterArray = aci->targetAttrDelFilters;
}
/*
* Scan this filter list for an applicable filter.
- */
+ */
found = 0;
num_attrs = 0;
@@ -2435,7 +2434,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
attr_matched= acl__test_filter(aclpb->aclpb_filter_test_entry,
attrFilter->filter,
1 /* Do filter sense evaluation below */
- );
+ );
slapi_entry_free( aclpb->aclpb_filter_test_entry );
}
@@ -2452,8 +2451,6 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*/
attr_matched_in_targetattrfilters = 1;
-
-
}
} /* targetvaluefilters */
@@ -3233,9 +3230,6 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
realval = tmp;
}
- slapi_dn_normalize (realval);
-
-
/* What we have built is a regular pattaren expression.
** Now we will compile the pattern and compare wth the string to
** see if the input string matches with the patteren or not.
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 36bdd43c..3f4b4e62 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -119,7 +119,11 @@ static char* const aci_targetattr = "targetattr";
static char* const aci_targetattrfilters = "targattrfilters";
static char* const aci_targetfilter = "targetfilter";
+static char* const LDAP_URL_prefix_core = "ldap://";
+static char* const LDAPS_URL_prefix_core = "ldaps://";
+
static char* const LDAP_URL_prefix = "ldap:///";
+static char* const LDAPS_URL_prefix = "ldaps:///";
static char* const access_str_compare = "compare";
static char* const access_str_search = "search";
@@ -827,7 +831,7 @@ int acl_skip_access_check ( Slapi_PBlock *pb, Slapi_Entry *e );
int aclext_alloc_lockarray ();
-int aclutil_str_appened(char **str1, const char *str2);
+int aclutil_str_append(char **str1, const char *str2);
void aclutil_print_err (int rv , const Slapi_DN *sdn,
const struct berval* val, char **errbuf);
void aclutil_print_aci (aci_t *aci_item, char *type);
@@ -911,6 +915,7 @@ acl_replace_str(char * s, char *substr, char* replace_with);
int acl_strstr(char * s, char *substr);
int aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
acl_eval_types evalType );
+int aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen);
/* acl hash table functions */
void acl_ht_add_and_freeOld(acl_ht_t * acl_ht, PLHashNumber key,char *value);
diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c
index 5e1d360b..d9494ec3 100644
--- a/ldap/servers/plugins/acl/acl_ext.c
+++ b/ldap/servers/plugins/acl/acl_ext.c
@@ -791,7 +791,7 @@ acl__done_aclpb ( struct acl_pblock *aclpb )
*/
/* Nothing needs to be cleaned up in this case */
- if ( !aclpb->aclpb_state & ACLPB_INITIALIZED)
+ if (!(aclpb->aclpb_state & ACLPB_INITIALIZED))
return;
/* Check the state */
diff --git a/ldap/servers/plugins/acl/aclanom.c b/ldap/servers/plugins/acl/aclanom.c
index 773dad2f..b1d15ca1 100644
--- a/ldap/servers/plugins/acl/aclanom.c
+++ b/ldap/servers/plugins/acl/aclanom.c
@@ -205,6 +205,7 @@ aclanom_gen_anomProfile (acl_lock_flag_t lock_flag)
/* see if this is a monitor acl */
if (( strcasecmp ( dn, "cn=monitor") == 0 ) ||
+ /* cn=monitor,cn=ldbm: No such object */
( strcasecmp ( dn, "cn=monitor,cn=ldbm") == 0 )) {
aci = acllist_get_next_aci ( NULL, aci, &cookie);
continue;
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index 9afac079..acf856cc 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -170,7 +170,7 @@ _ger_g_permission_granted (
goto bailout;
}
- aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
+ aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
"_ger_g_permission_granted: %s\n", *errbuf);
rc = LDAP_INSUFFICIENT_ACCESS;
@@ -195,7 +195,10 @@ _ger_parse_control (
LDAPControl **requestcontrols;
struct berval *subjectber;
BerElement *ber;
- int subjectndnlen = 0;
+ size_t subjectndnlen = 0;
+ char *orig = NULL;
+ char *normed = NULL;
+ int rc = 0;
if (NULL == subjectndn)
{
@@ -215,7 +218,7 @@ _ger_parse_control (
if ( subjectber == NULL || subjectber->bv_val == NULL ||
subjectber->bv_len == 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: missing subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: missing subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_INVALID_SYNTAX;
}
@@ -227,23 +230,23 @@ _ger_parse_control (
* or base64 encoding string. Hence users using -J option in
* ldapsearch don't have to do BER encoding for the subject.
*/
- *subjectndn = slapi_ch_malloc ( subjectber->bv_len + 1 );
- strncpy ( *subjectndn, subjectber->bv_val, subjectber->bv_len );
- *(*subjectndn + subjectber->bv_len) = '\0';
+ 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_appened ( errbuf, "get-effective-rights: ber_init failed for the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: ber_init failed for the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_OPERATIONS_ERROR;
}
/* "a" means to allocate storage as needed for octet string */
- if ( ber_scanf (ber, "a", subjectndn) == LBER_ERROR )
+ if ( ber_scanf (ber, "a", orig) == LBER_ERROR )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
ber_free ( ber, 1 );
return LDAP_INVALID_SYNTAX;
@@ -256,18 +259,32 @@ _ger_parse_control (
* (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 = strlen(*subjectndn);
- if ( NULL == *subjectndn || subjectndnlen < 3 ||
- strncasecmp ( "dn:", *subjectndn, 3 ) != 0 )
+ subjectndnlen = strlen(orig);
+ if ( NULL == orig || subjectndnlen < 3 || strncasecmp ( "dn:", orig, 3 ) != 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
+ aclutil_str_append ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
return LDAP_INVALID_SYNTAX;
}
/* memmove is safe for overlapping copy */
- memmove ( *subjectndn, *subjectndn + 3, subjectndnlen - 2);/* 1 for '\0' */
- slapi_dn_normalize ( *subjectndn );
+ rc = slapi_dn_normalize_ext(orig + 3, 0, &normed, &subjectndnlen);
+ if (rc < 0) {
+ aclutil_str_append ( errbuf, "get-effective-rights: failed to normalize dn: ");
+ aclutil_str_append ( errbuf, orig);
+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
+ return LDAP_INVALID_SYNTAX;
+ }
+ if (rc == 0) { /* orig+3 is passed in; not terminated */
+ *(normed + subjectndnlen) = '\0';
+ *subjectndn = slapi_ch_strdup(normed);
+ slapi_ch_free_string(&orig);
+ } else {
+ slapi_ch_free_string(&orig);
+ *subjectndn = normed;
+ }
return LDAP_SUCCESS;
}
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 9a57d7c8..9fbd25bb 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -480,6 +480,7 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
int rc;
short len;
const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix);
lasInfo lasinfo;
int got_undefined = 0;
@@ -530,15 +531,15 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
** userdn = "ldap:///DN1 || ldap:///DN2"
*/
-
/* The DN is now "ldap:///DN"
** remove the "ldap:///" part
*/
- if (strncasecmp (user, LDAP_URL_prefix,
- LDAP_URL_prefix_len) == 0) {
+ if (strncasecmp (user, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
s_user = user;
user += LDAP_URL_prefix_len;
-
+ } else if (strncasecmp (user, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ s_user = user;
+ user += LDAPS_URL_prefix_len;
} else {
char ebuf[ BUFSIZ ];
slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
@@ -677,8 +678,19 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
slapi_filter_free(f,1);
} else {
/* Must be a simple dn then */
- if (slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn,
- (ACLUCHP)slapi_dn_normalize(user)) == 0) {
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(user, 0, &normed, &dnlen);
+ if (rc == 0) { /* user passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else if (rc < 0) { /* normalization failed, user the original */
+ normed = user;
+ }
+ rc = slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn, (ACLUCHP)normed);
+ if (normed != user) {
+ slapi_ch_free_string(&normed);
+ }
+ if (0 == rc) {
matched = ACL_TRUE;
break;
}
@@ -1274,8 +1286,14 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
while ( j != -1 ) {
attrVal = slapi_value_get_berval ( sval );
/* Here if atleast 1 value matches then we are done.*/
- val = slapi_dn_normalize (
- slapi_ch_strdup( attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASUserDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void**) &s_attrName);
+ return LAS_EVAL_FAIL;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)lasinfo.clientDn ) == 0) {
char ebuf [ BUFSIZ ];
@@ -2380,7 +2398,13 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
while ( i != -1 ) {
struct member_info *groupMember = NULL;
attrVal = slapi_value_get_berval ( sval );
- n_dn = slapi_dn_normalize ( slapi_ch_strdup( attrVal->bv_val ));
+ n_dn = slapi_create_dn_string( attrVal->bv_val );
+ if (NULL == n_dn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
n = ++info->lu_idx;
if (n < 0) {
slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
@@ -2433,7 +2457,14 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
*/
if (strncasecmp( attrVal->bv_val, "ldap://",7) == 0 ||
strncasecmp( attrVal->bv_val, "ldaps://",8) == 0) {
- savURL = memberURL = slapi_ch_strdup ( attrVal->bv_val);
+ savURL = memberURL =
+ slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == savURL) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
"ACL Group Eval:MemberURL:%s\n", memberURL);
info->result = acllas__client_match_URL (
@@ -2656,8 +2687,13 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
attr_i= slapi_attr_first_value ( attr,&sval );
while ( attr_i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- n_groupdn = slapi_dn_normalize(
- slapi_ch_strdup( attrVal->bv_val));
+ n_groupdn = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_groupdn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASGroupDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
matched = acllas__user_ismember_of_group (
lasinfo.aclpb, n_groupdn, lasinfo.clientDn,
ACLLAS_CACHE_MEMBER_GROUPS,
@@ -2855,6 +2891,7 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
char *curMemberDn;
int Done = 0;
int ngr, tt;
+ char *normed = NULL;
/* Add the scope to the list of scopes */
if (aclpb->aclpb_numof_bases >= (aclpb->aclpb_grpsearchbase_size-1)) {
@@ -2866,9 +2903,15 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
sizeof (char *));
aclpb->aclpb_grpsearchbase_size += ACLPB_INCR_BASES;
}
- aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] =
- slapi_dn_normalize(slapi_ch_strdup(base));
-
+ normed = slapi_create_dn_string("%s", base);
+ if (NULL == normed) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ base );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
+ aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] = normed;
/* Set up info to do a search */
attrs[0] = type_member;
attrs[1] = type_uniquemember;
@@ -2991,8 +3034,14 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
while ( k != -1 ) {
char *n_attrval;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
/* We support: The attribute value can be a USER or a GROUP.
** Let's compare with the client, thi might be just an user. If it is not
@@ -3147,7 +3196,13 @@ acllas__verify_client (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- val = slapi_dn_normalize(slapi_ch_strdup(attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__verify_client: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)info->clientdn ) == 0) {
info->result = 1;
@@ -3235,7 +3290,12 @@ acllas__get_members (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal =slapi_value_get_berval ( sval );
- info->member[i] = slapi_dn_normalize ( slapi_ch_strdup(attrVal->bv_val));
+ info->member[i] = slapi_create_dn_string ("%s", attrVal->bv_val);
+ if (NULL == info->member[i]) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__get_members: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ }
i = slapi_attr_next_value ( attr, i, &sval );
}
return 0;
@@ -3426,7 +3486,17 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
LDAPURLDesc *ludp;
int rc;
Slapi_Filter *f = NULL;
-
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ char *p = NULL;
+ char *normed = NULL;
+ /* ldap(s)://host:port/suffix?attrs?scope?filter */
+ const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix_core);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix_core);
+ size_t prefix_len = 0;
+ char Q = '?';
+ char *hostport = NULL;
/* Get the client's entry if we don't have already */
if ( aclpb && ( NULL == aclpb->aclpb_client_entry )) {
@@ -3459,23 +3529,83 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
}
if ( NULL == aclpb->aclpb_client_entry ) {
- slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
- "DS_LASUserAttrEval: Unable to get client's entry\n");
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: Unable to get client's entry\n");
return ACL_FALSE;
}
- if (( rc = ldap_url_parse( url, &ludp)) != 0 ) {
+ /* DN potion of URL must be normalized before calling ldap_url_parse.
+ * lud_dn is pointing at the middle of lud_string.
+ * lud_dn won't be freed in ldap_free_urldesc.
+ */
+ /* remove the "ldap{s}:///" part */
+ if (strncasecmp (url, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
+ prefix_len = LDAP_URL_prefix_len;
+ } else if (strncasecmp (url, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ prefix_len = LDAPS_URL_prefix_len;
+ } else {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ rawdn = url + prefix_len; /* ldap(s)://host:port/... or ldap(s):///... */
+ /* rawdn at ^ or ^ */
+ /* let rawdn point the suffix */
+ if ('/' == *(rawdn+1)) { /* ldap(s):/// */
+ rawdn += 2;
+ hostport = "/";
+ } else {
+ char *tmpp = rawdn;
+ rawdn = strchr(tmpp, '/');
+ size_t hostport_len = 0;
+ if (NULL == rawdn) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include correct ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ hostport_len = ++rawdn - tmpp; /* ldap(s)://host:port/... */
+ /* <--------> */
+ hostport = (char *)slapi_ch_malloc(hostport_len + 1);
+ memcpy(hostport, tmpp, hostport_len);
+ *(hostport+hostport_len) = '\0';
+ }
+ p = strchr(rawdn, Q);
+ if (p) {
+ /* url has scope and/or filter: ldap(s):///suffix?attr?scope?filter */
+ *p = '\0';
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__client_match_URL: Invalid syntax: %s\n", url);
+ return ACL_FALSE;
+ } else if (rc == 0) { /* url is passed in and not terminated with NULL*/
+ *(dn + dnlen) = '\0';
+ }
+ if (p) {
+ *p = Q;
+ }
+ normed = slapi_ch_smprintf("%s%s%s%s",
+ (prefix_len==LDAP_URL_prefix_len)?
+ LDAP_URL_prefix_core:LDAPS_URL_prefix_core,
+ hostport, dn, p?p:"");
+ if (rc > 0) {
+ /* dn was allocated in slapi_dn_normalize_ext */
+ slapi_ch_free_string(&dn);
+ }
+ if ('/' != *hostport) {
+ slapi_ch_free_string(&hostport);
+ }
+ rc = ldap_url_parse(normed, &ludp);
+ slapi_ch_free_string(&normed);
+ if (rc) {
return ACL_FALSE;
-
}
if ( ( NULL == ludp->lud_dn) || ( NULL == ludp->lud_filter) ) {
ldap_free_urldesc( ludp );
return ACL_FALSE;
}
- /* Normalize in place the dn */
- slapi_dn_normalize ( ludp->lud_dn );
-
/* Check the scope */
if ( ludp->lud_scope == LDAP_SCOPE_SUBTREE ) {
if (!slapi_dn_issuffix(n_clientdn, ludp->lud_dn)) {
@@ -3777,8 +3907,13 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
Slapi_DN *roleDN;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASRoleDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return LAS_EVAL_FAIL;
+ }
roleDN = slapi_sdn_new_dn_byval(n_attrval);
/* We support: The attribute value can be a USER or a GROUP.
@@ -3831,14 +3966,12 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
* returns: ACL_TRUE for matched,
* ACL_FALSE for matched.
* ACL_DONT_KNOW otherwise.
- *
- *
-*/
+ */
int
aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
- acl_eval_types evalType ) {
-
+ acl_eval_types evalType )
+{
int matched = 0;
aci_t *aci;
char *matched_val = NULL;
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 8d4a21a0..0c8d0fa3 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -50,7 +50,6 @@ static int __aclp__sanity_check_acltxt(aci_t *aci_item, char *str);
static char * __aclp__normalize_acltxt (aci_t *aci_item, char *str);
static char * __aclp__getNextLASRule(aci_t *aci_item, char *str,
char **endOfCurrRule);
-static char * __aclp__dn_normalize( char *dn , char *end);
static int __aclp__get_aci_right ( char *str);
static int __aclp__init_targetattr (aci_t *aci, char *attr_val);
static int __acl__init_targetattrfilters( aci_t *aci_item, char *str);
@@ -239,10 +238,10 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/*
- * The targetattrfilters bit looks like this:
- * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
- * del= attr1:F1 && attr2:F2... && attrn:Fn")
- */
+ * The targetattrfilters bit looks like this:
+ * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
+ * del= attr1:F1 && attr2:F2... && attrn:Fn")
+ */
if ( 0 != (rv= __acl__init_targetattrfilters(
aci_item, str))) {
return rv;
@@ -256,15 +255,14 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
}
/* Get individual components of the targetattr.
* (targetattr = "cn || u* || phone ||tel:add:(tel=1234)
- * || sn:del:(gn=5678)")
- * If it contains a value filter, the type will also be
- * ACI_TARGET_VALUE_ATTR.
- */
- if ( 0 != (rv= __aclp__init_targetattr(
- aci_item, str))) {
+ * || sn:del:(gn=5678)")
+ * If it contains a value filter, the type will also be
+ * ACI_TARGET_VALUE_ATTR.
+ */
+ if (0 != (rv = __aclp__init_targetattr(aci_item, str))) {
return rv;
}
- } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
+ } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
if ( aci_item->targetFilter)
return ACL_SYNTAX_ERR;
@@ -311,8 +309,8 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
} else if (strncmp(str, aci_targetdn, targetdnlen) == 0) {
char *tstr = NULL;
- const size_t LDAP_URL_prefix_len = strlen (LDAP_URL_prefix);
- char *tt;
+ size_t LDAP_URL_prefix_len = 0;
+ size_t tmplen = 0;
type = ACI_TARGET_DN;
/* Keep a copy of the target attr */
if (aci_item->target) {
@@ -322,30 +320,40 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
type |= ACI_TARGET_NOT;
strncpy(s, " ", 1);
}
-
- /* Convert it to lower as slapi_dn_normalize() does not */
- for (tt = str; *tt; tt++) *tt = TOLOWER ( *tt );
-
if ( (s = strchr( str, '=' )) != NULL ) {
value = s + 1;
- slapi_dn_normalize(value);
+ __acl_strip_leading_space(&value);
len = strlen ( value );
- if (*value == '"' && value[len-1] == '"'){
+ /* strip double quotes */
+ if (*value == '"' && value[len-1] == '"') {
value[len-1] = '\0';
value++;
}
__acl_strip_leading_space(&value);
- } else {
+ } else {
return ( ACL_SYNTAX_ERR );
}
-
- if ( strncasecmp ( value, LDAP_URL_prefix , LDAP_URL_prefix_len) )
+ if (0 ==
+ strncasecmp(value, LDAP_URL_prefix, strlen(LDAP_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ } else if (0 == strncasecmp(value, LDAPS_URL_prefix,
+ strlen(LDAPS_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAPS_URL_prefix);
+ } else {
return ( ACL_SYNTAX_ERR );
+ }
value += LDAP_URL_prefix_len;
- len = strlen ( value );
- tstr = (char *) slapi_ch_malloc ( targetdnlen + len + 4 );
- sprintf ( tstr, "(target=%s)", value);
+ rv = slapi_dn_normalize_case_ext(value, 0, &tmpstr, &tmplen);
+ if (rv < 0) {
+ return ACL_SYNTAX_ERR;
+ } else if (rv == 0) { /* value passed in; not null terminated */
+ *(tmpstr + tmplen) = '\0';
+ }
+ tstr = slapi_ch_smprintf("(target=%s)", tmpstr);
+ if (rv > 0) {
+ slapi_ch_free_string(&tmpstr);
+ }
if ( (rv = acl_check_for_target_macro( aci_item, value)) == -1) {
slapi_ch_free ( (void **) &tstr );
return(ACL_SYNTAX_ERR);
@@ -356,7 +364,7 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/* it's a normal target with no macros inside */
f = slapi_str2filter ( tstr );
}
- slapi_ch_free ( (void **) &tstr );
+ slapi_ch_free_string ( &tstr );
} else {
/* did start with a 't' but was not a recognsied keyword */
return(ACL_SYNTAX_ERR);
@@ -492,20 +500,86 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
slapi_log_error(SLAPI_LOG_ACL, plugin_name, "Normalized String:%s\n", newstr);
/* check for acl syntax error */
- if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp,
- newstr)) == NULL) {
+ if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp, newstr)) == NULL) {
acl_print_acllib_err(&errp, str);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return ACL_SYNTAX_ERR;
} else {
/* get the rights and the aci type */
aci_item->aci_handle = handle;
nserrDispose(&errp);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return 0;
}
}
+
+/*
+ * If the src includes "ldap(s):///<dn>", normalize <dn> and copy
+ * the string starting from start to *dest.
+ * If isstrict is non-zero, if ldap(s):/// is not included in the src
+ * string, it returns an error (-1).
+ * If isstrict is zero, the string is copied as is.
+ *
+ * return value: 0 or positive: success
+ * negative: failure
+ */
+int
+__aclp__copy_normalized_str (char *src, char *endsrc, char *start,
+ char **dest, size_t *destlen, int isstrict)
+{
+ char *p = NULL;
+ int rc = -1;
+ char *dn = NULL;
+ size_t dnlen = 0;
+
+ p = PL_strnstr(src, LDAP_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAP_URL_prefix);
+ } else {
+ p = PL_strnstr(src, LDAPS_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAPS_URL_prefix);
+ }
+ }
+
+ if (isstrict && ((NULL == p) || 0 == strlen(p))) {
+ return rc; /* error */
+ }
+
+ rc = 0;
+ if (p && strlen(p) > 0) {
+ size_t len = 0;
+ /* strip the string starting from ? */
+ char *q = PL_strnchr(p, '?', endsrc - p);
+ if (q) {
+ len = q - p;
+ } else {
+ len = endsrc - p;
+ }
+ /* Normalize the value of userdn and append it to ret_str */
+ rc = slapi_dn_normalize_ext(p, len, &dn, &dnlen);
+ if (rc < 0) {
+ return rc;
+ }
+ /* append up to ldap(s):/// */
+ aclutil_str_append_ext(dest, destlen, start, p - start);
+ /* append the DN part */
+ aclutil_str_append_ext(dest, destlen, dn, dnlen);
+ if (rc > 0) { /* if rc == 0, p is passed in */
+ slapi_ch_free_string(&dn);
+ }
+ if (q) {
+ /* append the rest from '?' */
+ aclutil_str_append_ext(dest, destlen, q, endsrc - q);
+ }
+ } else {
+ aclutil_str_append_ext(dest, destlen, start, endsrc - start);
+ }
+
+ return rc;
+}
+
/******************************************************************************
*
* acl__normalize_acltxt
@@ -534,23 +608,25 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
char *s, *p;
char *end;
char *aclstr, *s_aclstr;
+ char *prevend = NULL;
char *ret_str = NULL;
+ size_t retstr_len = 0;
int len;
- char *ptr, *aclName;
+ char *aclName;
char *nextACE;
char *tmp_str = NULL;
char *acestr = NULL;
char *s_acestr = NULL;
int aci_rights_val = 0; /* bug 389975 */
+ int rc = 0;
/* make a copy first */
s_aclstr = aclstr = slapi_ch_strdup ( str );
/* The rules are like this version 3.0; acl "xyz"; rule1; rule2; */
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = ++s;
@@ -564,9 +640,8 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
aclName = s+3;
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = s;
@@ -576,8 +651,10 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
/* Here aclName is the acl description string */
aci_item->aclName = slapi_ch_strdup ( aclName );
- aclutil_str_appened (&ret_str, s_aclstr);
- aclutil_str_appened (&ret_str, ";");
+ retstr_len = strlen(str) * 3;
+ ret_str = (char *)slapi_ch_calloc(sizeof(char), retstr_len);
+ aclutil_str_append_ext (&ret_str, &retstr_len, s_aclstr, strlen(s_aclstr));
+ aclutil_str_append_ext (&ret_str, &retstr_len, ";", 1);
/* start with the string */
acestr = aclstr;
@@ -586,37 +663,34 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
* Here acestr is something like:
*
* " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";)"
- *
- *
- */
+ */
normalize_nextACERule:
/* now we are in the rule part */
tmp_str = acestr;
s = strchr (tmp_str, ';');
- if ( s == NULL) {
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (s == NULL) {
+ goto error;
}
+
nextACE = s;
LDAP_UTF8INC(nextACE);
*s = '\0';
- /* acestr now will hold copy of the ACE. Also add
+ /* acestr now will hold copy of the ACE. Also add
** some more space in case we need to add "absolute"
- ** for deny rule. We will never need more 2 times
- ** the len.
+ ** for deny rule. We will never need more 3 times
+ ** the len (even if all the chars are escaped).
*/
__acl_strip_leading_space(&tmp_str);
len = strlen (tmp_str);
- s_acestr = acestr = slapi_ch_calloc ( 1, 2 * len);
+ s_acestr = acestr = slapi_ch_calloc (1, 3 * len);
/*
* Now it's something like:
* allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";
- */
+ */
if (strncasecmp(tmp_str, "allow", 5) == 0) {
memcpy(acestr, tmp_str, len);
tmp_str += 5;
@@ -624,6 +698,14 @@ normalize_nextACERule:
aci_rights_val = __aclp__get_aci_right (tmp_str);/* bug 389975 */
aci_item->aci_type |= ACI_HAS_ALLOW_RULE;
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "allow(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else if (strncasecmp(tmp_str, "deny", 4) == 0) {
char *d_rule ="deny absolute";
/* Then we have to add "absolute" to the deny rule
@@ -652,6 +734,15 @@ normalize_nextACERule:
len = strlen ( d_rule );
memcpy (acestr, d_rule, len );
memcpy (acestr+len, tmp_str, strlen (tmp_str) );
+
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "deny(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else {
/* wrong syntax */
aci_rights_val = -1 ;
@@ -659,32 +750,32 @@ normalize_nextACERule:
if (aci_rights_val == -1 )
{
/* wrong syntax */
- slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_acestr );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ goto error;
} else
- aci_item->aci_access |= aci_rights_val;
+ aci_item->aci_access |= aci_rights_val;
-
- /* Normalize all the DNs in the userdn rule */
-
+ /* Normalize all the DNs in the userdn, groupdn, roledn rules */
/*
*
* Here acestr starts like this:
- * " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP"
- */
-
+ * " allow (all) groupdn = "ldap:///cn=Domain Administrators,o=$dn.o,o=ISP"
+ */
s = __aclp__getNextLASRule(aci_item, acestr, &end);
while ( s ) {
- if ( 0 == strncmp ( s, DS_LAS_USERDNATTR, 10) ||
- ( 0 == strncmp ( s, DS_LAS_USERATTR, 8))) {
+ if ( (0 == strncmp(s, DS_LAS_USERDNATTR, 10)) ||
+ (0 == strncmp(s, DS_LAS_USERATTR, 8)) ) {
/*
** For userdnattr/userattr rule, the resources changes and hence
** we cannot cache the result. See above for more comments.
*/
aci_item->aci_elevel = ACI_ELEVEL_USERDNATTR;
- } else if ( 0== strncmp ( s, DS_LAS_USERDN, 6)) {
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
+ } else if ( 0 == strncmp ( s, DS_LAS_USERDN, 6)) {
p = strstr ( s, "=");
p--;
if ( strncmp (p, "!=", 2) == 0)
@@ -699,22 +790,12 @@ normalize_nextACERule:
* which would ensure that acl info is not cached from
* one resource entry to the next. (bug 558519)
*/
- p = strstr ( p, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8; /* for ldap:/// */
- if( __aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
-
+
/* we have a rule like userdn = "ldap:///blah". s points to blah now.
** let's find if we have a SELF rule like userdn = "ldap:///self".
** Since the resource changes on entry basis, we can't cache the
@@ -750,6 +831,12 @@ normalize_nextACERule:
aci_item->aci_elevel = ACI_ELEVEL_GROUPDNATTR;
}
aci_item->aci_ruleType |= ACI_GROUPDNATTR_RULE;
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
} else if ( 0 == strncmp ( s, DS_LAS_GROUPDN, 7)) {
p = strstr ( s, "=");
@@ -757,21 +844,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_GROUPDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -786,21 +864,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_ROLEDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -808,40 +877,47 @@ normalize_nextACERule:
if ( aci_item->aci_elevel > ACI_ELEVEL_GROUPDN )
aci_item->aci_elevel = ACI_ELEVEL_GROUPDN;*/
aci_item->aci_ruleType |= ACI_ROLEDN_RULE;
+ } else {
+ /* adding the string no need to be processed
+ * (e.g., dns="lab.example.com)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, end - prevend);
}
+ prevend = end;
s = ++end;
s = __aclp__getNextLASRule(aci_item, s, &end);
- }/* while */
+ if (NULL == s) {
+ /* adding the rest of the string, e.g. '\"' */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, strlen(prevend));
+ }
+ } /* while */
- /* get the head of the string */
- acestr = s_acestr;
- len = strlen( acestr);
- ptr = acestr +len-1;
- while (*ptr && *ptr != '\"' && *ptr != ')' ) *ptr-- = ' ';
- ptr++;
- *ptr = ';';
-
- aclutil_str_appened (&ret_str, acestr);
- if (s_acestr) {
- slapi_ch_free ( (void **) &s_acestr );
- }
- s_acestr = NULL;
+ slapi_ch_free_string (&s_acestr);
+ __acl_strip_trailing_space(ret_str);
+ aclutil_str_append_ext(&ret_str, &retstr_len, ";", 1);
if (nextACE) {
s = strstr (nextACE, "allow");
if (s == NULL) s = strstr (nextACE, "deny");
if (s == NULL) {
if (nextACE && *nextACE != '\0')
- aclutil_str_appened (&ret_str, nextACE);
- slapi_ch_free ( (void **) &s_aclstr );
+ aclutil_str_append (&ret_str, nextACE);
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
}
acestr = nextACE;
goto normalize_nextACERule;
}
- slapi_ch_free ( (void **) &s_aclstr );
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
+
+error:
+ slapi_ch_free_string (&ret_str);
+ slapi_ch_free_string (&s_aclstr);
+ slapi_ch_free_string (&s_acestr);
+ return NULL;
}
/*
*
@@ -857,7 +933,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
{
char *newstr, *word, *next, *start, *end;
char *ruleStart = NULL;
- int len, ruleLen;
+ int len, ruleLen = 0;
int in_dn_expr = 0;
*endOfCurrRule = NULL;
@@ -1029,43 +1105,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
return ( ruleStart );
}
-/******************************************************************************
-*
-* __aclp__dn_normalize
-*
-* Normalize the DN INPLACE. This routine is similar to slapi_dn_normalize()
-* except various small stuff at the end.
-* Normalize until the "end" and not to the end of string.
-*
-******************************************************************************/
-static char *
-__aclp__dn_normalize( char *dn , char *end)
-{
- char *d;
-
- if ((end - dn) < 0) {
- return(NULL);
- }
- d = slapi_dn_normalize_to_end ( dn, end );
-
- /* Do I have the quotes already */
- if (*d != '\"' ) {
- /*
- ** We are taking care of this situation
- ** " ") ". We need to remove the space
- ** infront and tack it after the quote like this.
- ** "" ) ".
- */
-
- *d = '\"';
- d++;
- while (*d && *d != '\"') *d++ = ' ';
- *d = ' ';
- }
-
- return( dn );
-}
/***************************************************************************
* acl__get_aci_right
*
@@ -1263,6 +1303,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
}
while (str != 0 && *str != 0) {
+ int lenstr = 0;
__acl_strip_leading_space(&str);
@@ -1292,23 +1333,28 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
attr = (Targetattr *) slapi_ch_malloc (sizeof (Targetattr));
memset (attr, 0, sizeof(Targetattr));
- if (strchr(str, '*')) {
-
+ /* strip double quotes */
+ lenstr = strlen(str);
+ if (*str == '"' && *(str + lenstr - 1) == '"') {
+ *(str + lenstr - 1) = '\0';
+ str++;
+ }
+ if (strchr(str, '*')) {
+
/* It contains a * so it's something like * or cn* */
if (strcmp(str, "*" ) != 0) {
char line[100];
char *lineptr = &line[0];
char *newline = NULL;
- int lenstr = 0;
struct slapi_filter *f = NULL;
- if ((lenstr = strlen(str)) > 91) { /* 100 - 8 for "(attr =%s)" */
- newline = slapi_ch_malloc(lenstr + 9);
+ if (lenstr > 92) { /* 100 - 8 for "(attr=%s)\0" */
+ newline = slapi_ch_malloc(lenstr + 8);
lineptr = newline;
}
attr->attr_type = ACL_ATTR_FILTER;
- sprintf (lineptr, "(attr =%s)", str);
+ sprintf (lineptr, "(attr=%s)", str);
f = slapi_str2filter (lineptr);
if (f == NULL) {
@@ -1320,7 +1366,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
if (newline) slapi_ch_free((void **) &newline);
} else {
- attr->attr_type = ACL_ATTR_STAR;
+ attr->attr_type = ACL_ATTR_STAR;
attr->u.attr_str = slapi_ch_strdup (str);
}
diff --git a/ldap/servers/plugins/acl/aclproxy.c b/ldap/servers/plugins/acl/aclproxy.c
index d40f543f..9b28489a 100644
--- a/ldap/servers/plugins/acl/aclproxy.c
+++ b/ldap/servers/plugins/acl/aclproxy.c
@@ -87,7 +87,9 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
LDAPProxyAuth *spec = NULL;
BerElement *ber = NULL;
char *errstring = "unable to parse proxied authorization control";
-
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
BEGIN
ber_tag_t tag;
@@ -132,11 +134,20 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
errstring = "proxied authorization id must be a DN (dn:...)";
break;
}
- strcpy( spec->auth_dn, spec->auth_dn + 3 );
+ /* memmove is safe for overlapping copy */
+ memmove ( spec->auth_dn, spec->auth_dn + 3, strlen(spec->auth_dn) - 2);/* 1 for '\0' */
}
- slapi_dn_normalize(spec->auth_dn);
lderr = LDAP_SUCCESS; /* got it! */
+ rc = slapi_dn_normalize_ext(spec->auth_dn, 0, &normed, &dnlen);
+ if (rc < 0) {
+ lderr = LDAP_INVALID_SYNTAX;
+ } else if (rc == 0) { /* spec->auth_dn is passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&spec->auth_dn);
+ spec->auth_dn = normed;
+ }
END
/* Cleanup */
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index 4aebd477..c0b8f579 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -65,7 +65,7 @@ static PRIntn acl_ht_display_entry(PLHashEntry *he, PRIntn i, void *arg);
/* UTILITY FUNCTIONS */
/***************************************************************************/
int
-aclutil_str_appened(char **str1, const char *str2)
+aclutil_str_append(char **str1, const char *str2)
{
int new_len;
@@ -87,6 +87,43 @@ aclutil_str_appened(char **str1, const char *str2)
return(0);
}
+/*
+ * dlen: the length of the buffer *dest (not the string length in *dest)
+ */
+int
+aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen)
+{
+ char *ptr = NULL;
+ int rc = 0;
+
+ if ( dest == NULL || src == NULL ) {
+ return rc;
+ }
+
+ if (0 == slen) {
+ slen = strlen(src);
+ }
+ if (*dest && dlen > 0) {
+ size_t dest_strlen = strlen(*dest);
+ size_t new_len = dest_strlen + slen + 1;
+ if (new_len > *dlen) {
+ *dest = (char *)slapi_ch_realloc(*dest, new_len);
+ *dlen = new_len;
+ ptr = *dest + dest_strlen;
+ } else {
+ ptr = *dest + dest_strlen;
+ }
+ } else {
+ *dlen = slen + 1;
+ *dest = (char *)slapi_ch_malloc(*dlen);
+ ptr = *dest;
+ }
+ memcpy(ptr, src, slen);
+ *(ptr + slen) = '\0';
+
+ return rc;
+}
+
/***************************************************************************/
/* Print routines */
/***************************************************************************/
@@ -104,9 +141,14 @@ acl_print_acllib_err (NSErr_t *errp , char * str)
aclErrorFmt(errp, msgbuf, ACLUTIL_ACLLIB_MSGBUF_LEN, 1);
msgbuf[ACLUTIL_ACLLIB_MSGBUF_LEN-1] = '\0';
- if (msgbuf)
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
- msgbuf, str ? str: "NULL");
+ if (strlen(msgbuf) > 0) {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
+ msgbuf, str ? str: "NULL");
+ } else {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)\n",
+ str ? str: "NULL");
+ }
+
}
void
aclutil_print_aci (aci_t *aci_item, char *type)
@@ -240,7 +282,7 @@ aclutil_print_err (int rv , const Slapi_DN *sdn, const struct berval* val,
if (errbuf) {
/* If a buffer is provided, then copy the error */
- aclutil_str_appened(errbuf, lineptr );
+ aclutil_str_append(errbuf, lineptr );
}
slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "%s", lineptr);
@@ -436,7 +478,7 @@ acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf)
line = PR_smprintf(
"Insufficient 'delete' privilege to delete the entry '%s'.\n",edn);
}
- aclutil_str_appened(errbuf, line );
+ aclutil_str_append(errbuf, line );
if (line) {
PR_smprintf_free(line);
@@ -540,7 +582,7 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
goto cleanup;
}
*p = '\0';
- aclutil_str_appened ( &buf,a_dns[i]);
+ aclutil_str_append ( &buf,a_dns[i]);
if ( type == 1 ) {
/* xyz = $dn.o */
@@ -573,15 +615,15 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
kk= slapi_attr_next_value( attr, kk, &sval );
if ( kk != -1 ) /* can't handle multiple --error */
goto cleanup;
+ attrValue = slapi_value_get_berval ( t_sval );
+ attrVal = attrValue->bv_val;
}
- attrValue = slapi_value_get_berval ( t_sval );
- attrVal = attrValue->bv_val;
}
} else {
attrVal = a_dns[i];
}
- aclutil_str_appened ( &buf, attrVal);
- aclutil_str_appened ( &buf, ",");
+ aclutil_str_append ( &buf, attrVal);
+ aclutil_str_append ( &buf, ",");
}
rc = 0; /* everything is okay*/
/* remove the last comma */
@@ -607,7 +649,7 @@ __aclutil_extract_dn_component ( char **e_dns, int position, char *attrName )
int i, matched, len;
char *s;
- int matchedPosition;
+ int matchedPosition = 0;
len = strlen ( attrName );