Commit cddf7e0e authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

More struct berval DN changes

decrease dependency on dn_validate/dn_normalize
parent 208a88f8
......@@ -40,13 +40,6 @@ ldap_url_parse_ext LDAP_P((
LDAP_CONST char *url,
struct ldap_url_desc **ludpp ));
LDAP_F ( int )
ldap_pvt_domain2dn LDAP_P((
LDAP_CONST char *domain,
char **dn ));
struct hostent; /* avoid pulling in <netdb.h> */
LDAP_F( char * )
ldap_pvt_ctime LDAP_P((
const time_t *tp,
......@@ -54,6 +47,8 @@ ldap_pvt_ctime LDAP_P((
LDAP_F( char *) ldap_pvt_get_fqdn LDAP_P(( char * ));
struct hostent; /* avoid pulling in <netdb.h> */
LDAP_F( int )
ldap_pvt_gethostbyname_a LDAP_P((
const char *name,
......@@ -109,26 +104,17 @@ ldap_charray2str LDAP_P((
LDAP_F (void) ldap_pvt_hex_unescape LDAP_P(( char *s ));
LDAP_F (int) ldap_pvt_unhex( int c );
/* these macros assume 'x' is an ASCII x */
#define LDAP_DNSEPARATOR(c) ((c) == ',' || (c) == ';')
#define LDAP_SEPARATOR(c) ((c) == ',' || (c) == ';' || (c) == '+')
/*
* these macros assume 'x' is an ASCII x
* and assume the "C" locale
*/
#define LDAP_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
#define LDAP_DIGIT(c) ((c) >= '0' && (c) <= '9')
#define LDAP_LOWER(c) ((c) >= 'a' && (c) <= 'z')
#define LDAP_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define LDAP_ALPHA(c) (LDAP_LOWER(c) || LDAP_UPPER(c))
#define LDAP_ALNUM(c) (LDAP_ALPHA(c) || LDAP_DIGIT(c))
#define LDAP_LOWER(c) ( (c) >= 'a' && (c) <= 'z' )
#define LDAP_UPPER(c) ( (c) >= 'A' && (c) <= 'Z' )
#define LDAP_ALPHA(c) ( LDAP_LOWER(c) || LDAP_UPPER(c) )
#define LDAP_DIGIT(c) ( (c) >= '0' && (c) <= '9' )
#define LDAP_ALNUM(c) ( LDAP_ALPHA(c) || LDAP_DIGIT(c) )
#define LDAP_LEADKEYCHAR(c) ( LDAP_ALPHA(c) )
#define LDAP_KEYCHAR(c) ( LDAP_ALNUM(c) || (c) == '-' )
#define LDAP_LEADOIDCHAR(c) ( LDAP_DIGIT(c) )
#define LDAP_OIDCHAR(c) ( LDAP_DIGIT(c) || (c) == '.' )
#define LDAP_LEADATTRCHAR(c) ( LDAP_LEADKEYCHAR(c) || LDAP_LEADOIDCHAR(c) )
#define LDAP_ATTRCHAR(c) ( LDAP_KEYCHAR(c) || LDAP_OIDCHAR(c) )
#define LDAP_NEEDSESCAPE(c) ((c) == '\\' || (c) == '"')
#ifdef HAVE_CYRUS_SASL
/* cyrus.c */
......
......@@ -15,8 +15,6 @@
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/ctype.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
......@@ -365,7 +363,11 @@ dn2dn( const char *dnin, unsigned fin, char **dnout, unsigned fout )
#define B4IA5VALUE 0x0040
#define B4BINARYVALUE 0x0050
/* Helpers (mostly from slapd.h; maybe it should be rewritten from this) */
/*
* Helpers (mostly from slap.h)
* c is assumed to Unicode in an ASCII compatible format (UTF-8)
* Macros assume "C" Locale (ASCII)
*/
#define LDAP_DN_ASCII_SPACE(c) \
( (c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' )
#define LDAP_DN_ASCII_LOWER(c) ( (c) >= 'a' && (c) <= 'z' )
......@@ -468,17 +470,23 @@ dn2dn( const char *dnin, unsigned fin, char **dnout, unsigned fout )
/* generics */
#define LDAP_DN_HEXPAIR(s) \
( LDAP_DN_ASCII_HEXDIGIT((s)[0]) && LDAP_DN_ASCII_HEXDIGIT((s)[1]) )
#define LDAP_DC_ATTR "dc"
/* better look at the AttributeDescription? */
/* FIXME: no composite rdn or non-"dc" types, right?
* (what about "dc" in OID form?) */
/* FIXME: we do not allow binary values in domain, right? */
/* NOTE: use this macro only when ABSOLUTELY SURE rdn IS VALID! */
#define LDAP_DN_IS_RDN_DC( rdn ) \
( ( rdn ) && ( rdn )[ 0 ][ 0 ] && !( rdn )[ 1 ] \
&& ( ( rdn )[ 0 ][ 0 ]->la_flags == LDAP_AVA_STRING ) \
&& ! strcasecmp( ( rdn )[ 0 ][ 0 ]->la_attr->bv_val, LDAP_DC_ATTR ) )
/* NOTE: don't use strcasecmp() as it is locale specific! */
#define LDAP_DC_ATTR "dc"
#define LDAP_DC_ATTRU "DC"
#define LDAP_DN_IS_RDN_DC( r ) \
( (r) && (r)[0][0] && !(r)[1] \
&& ((r)[0][0]->la_flags == LDAP_AVA_STRING) \
&& ((r)[0][0]->la_attr->bv_len == 2) \
&& (((r)[0][0]->la_attr->bv_val[0] == LDAP_DC_ATTR[0]) \
|| ((r)[0][0]->la_attr->bv_val[0] == LDAP_DC_ATTRU[0])) \
&& (((r)[0][0]->la_attr->bv_val[1] == LDAP_DC_ATTR[1]) \
|| ((r)[0][0]->la_attr->bv_val[1] == LDAP_DC_ATTRU[1])))
/* Composite rules */
#define LDAP_DN_ALLOW_ONE_SPACE(f) \
......
......@@ -421,7 +421,6 @@ retry: /* transaction retry */
/* Get attribute type and attribute value of our new rdn, we will
* need to add that to our new entry
*/
if ( rdn_attrs( newrdn->bv_val, &new_rdn_types, &new_rdn_vals ) ) {
Debug( LDAP_DEBUG_TRACE,
"bdb_modrdn: can't figure out type(s)/values(s) "
......
......@@ -38,7 +38,8 @@ ldbm_back_exop_passwd(
struct berval *id = NULL;
struct berval *new = NULL;
char *dn;
struct berval dn;
struct berval *ndn = NULL;
assert( reqoid != NULL );
assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, reqoid ) == 0 );
......@@ -80,32 +81,34 @@ ldbm_back_exop_passwd(
goto done;
}
dn = id ? id->bv_val : op->o_dn.bv_val;
if( id ) {
dn = *id;
} else {
dn = op->o_dn;
}
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
"ldbm_back_exop_passwd: \"%s\"%s\n",
dn, id ? " (proxy)" : "" ));
"ldbm_back_exop_passwd: \"%s\"%s\n",
dn.bv_val, id ? " (proxy)" : "" ));
#else
Debug( LDAP_DEBUG_TRACE, "passwd: \"%s\"%s\n",
dn, id ? " (proxy)" : "", 0 );
dn.bv_val, id ? " (proxy)" : "", 0 );
#endif
if( dn == NULL || dn[0] == '\0' ) {
if( dn.bv_len == 0 ) {
*text = "No password is associated with the Root DSE";
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
if( dn_normalize( dn ) == NULL ) {
rc = dnNormalize( NULL, &dn, &ndn );
if( rc != LDAP_SUCCESS ) {
*text = "Invalid DN";
rc = LDAP_INVALID_DN_SYNTAX;
goto done;
}
e = dn2entry_w( be, dn, NULL );
e = dn2entry_w( be, ndn->bv_val, NULL );
if( e == NULL ) {
*text = "could not locate authorization entry";
rc = LDAP_NO_SUCH_OBJECT;
......@@ -144,7 +147,7 @@ ldbm_back_exop_passwd(
conn, op, op->o_ndn.bv_val, &ml, e, text, textbuf,
sizeof( textbuf ) );
/* FIXME: ldbm_modify_internal may set *tex = textbuf,
/* FIXME: ldbm_modify_internal may set *text = textbuf,
* which is BAD */
if ( *text == textbuf ) {
*text = NULL;
......@@ -184,5 +187,9 @@ done:
ber_bvfree( hash );
}
if( ndn != NULL ) {
ber_bvfree( ndn );
}
return rc;
}
......@@ -784,7 +784,7 @@ is_one_level_rdn(
)
{
for ( ; len--; ) {
if ( LDAP_DNSEPARATOR( rdn[ len ] ) ) {
if ( DN_SEPARATOR( rdn[ len ] ) ) {
return 0;
}
}
......
......@@ -715,25 +715,6 @@ char * dn_rdn(
return retval;
}
/*
* return a charray of all subtrees to which the DN resides in
*/
char **dn_subtree(
Backend *be,
const char *dn )
{
char **subtree = NULL;
do {
charray_add( &subtree, dn );
dn = dn_parent( be, dn );
} while ( dn != NULL );
return subtree;
}
/*
* dn_issuffix - tells whether suffix is a suffix of dn.
* Both dn and suffix must be normalized.
......@@ -829,7 +810,6 @@ rdn_attr_value( const char * rdn )
*
* Deprecated; directly use LDAPRDN from ldap_str2rdn
*/
int
rdn_attrs( const char * rdn, char ***types, char ***values)
{
......@@ -866,14 +846,27 @@ rdn_attrs( const char * rdn, char ***types, char ***values)
}
/* rdn_validate:
/* rdnValidate:
*
* 1 if rdn is a legal rdn;
* 0 otherwise (including a sequence of rdns)
* LDAP_SUCCESS if rdn is a legal rdn;
* LDAP_INVALID_SYNTAX otherwise (including a sequence of rdns)
*/
int
rdn_validate( const char *rdn )
rdnValidate( struct berval *rdn )
{
#if 1
/* Major cheat!
* input is a pretty or normalized DN
* hence, we can just search for ','
*/
if( rdn == NULL || rdn->bv_len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
return strchr( rdn->bv_val, ',' ) == NULL
? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
#else
LDAPRDN *RDN, **DN[ 2 ] = { &RDN, NULL };
const char *p;
int rc;
......@@ -912,6 +905,7 @@ rdn_validate( const char *rdn )
* Must validate (there's a repeated parsing ...)
*/
return ( rc == LDAP_SUCCESS );
#endif
}
......
......@@ -152,11 +152,18 @@ add_limits(
case SLAP_LIMITS_SUBTREE:
case SLAP_LIMITS_CHILDREN:
lm->lm_type = type;
lm->lm_dn_pat = ber_bvstrdup( pattern );
if ( dn_normalize( lm->lm_dn_pat->bv_val ) == NULL ) {
ber_bvfree( lm->lm_dn_pat );
ch_free( lm );
return( -1 );
{
int rc;
struct berval bv;
bv.bv_val = (char *) pattern;
bv.bv_len = strlen( pattern );
lm->lm_dn_pat = NULL;
rc = dnNormalize( NULL, &bv, &lm->lm_dn_pat );
if ( rc != LDAP_SUCCESS ) {
ch_free( lm );
return( -1 );
}
}
break;
......
......@@ -265,7 +265,7 @@ do_modrdn(
goto cleanup;
}
if( !nnewrdn->bv_len || !rdn_validate( pnewrdn->bv_val ) ) {
if( rdnValidate( pnewrdn ) == LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
"do_modrdn: invalid rdn (%s).\n", pnewrdn->bv_val ));
......
......@@ -373,20 +373,21 @@ LDAP_SLAPD_F (int) dnMatch LDAP_P((
LDAP_SLAPD_F (int) dnIsSuffix LDAP_P((
const struct berval *dn, const struct berval *suffix ));
LDAP_SLAPD_F (int) rdnValidate LDAP_P(( struct berval * rdn ));
#define SLAP_DN_MIGRATION
#ifdef SLAP_DN_MIGRATION
/* These routines are deprecated!!! */
LDAP_SLAPD_F (char *) dn_validate LDAP_P(( char *dn ));
LDAP_SLAPD_F (char *) dn_normalize LDAP_P(( char *dn ));
LDAP_SLAPD_F (char *) dn_parent LDAP_P(( Backend *be, const char *dn ));
LDAP_SLAPD_F (char **) dn_subtree LDAP_P(( Backend *be, const char *dn ));
LDAP_SLAPD_F (char *) dn_rdn LDAP_P(( Backend *be, const char *dn ));
LDAP_SLAPD_F (int) dn_rdnlen LDAP_P(( Backend *be, const char *dn ));
LDAP_SLAPD_F (int) dn_issuffix LDAP_P(( const char *dn, const char *suffix ));
LDAP_SLAPD_F (int) rdn_validate LDAP_P(( const char* str ));
LDAP_SLAPD_F (char *) rdn_attr_value LDAP_P(( const char * rdn ));
LDAP_SLAPD_F (char *) rdn_attr_type LDAP_P(( const char * rdn ));
LDAP_SLAPD_F (int) rdn_attrs LDAP_P(( const char * rdn, char ***ptypes, char ***pvals ));
LDAP_SLAPD_F (int) rdn_attrs LDAP_P(( const char * rdn,
char ***ptypes, char ***pvals ));
LDAP_SLAPD_F (void) build_new_dn LDAP_P(( struct berval * new_dn,
struct berval * parent_dn,
......
......@@ -201,7 +201,9 @@ int slap_sasl_getdn( Connection *conn, char *id, char **dnptr, int flags )
}
/* DN strings that are a cn=auth identity to run through regexp */
if( !strncasecmp( dn, "dn:", 3) && ( ( flags & FLAG_GETDN_FINAL ) == 0 ) ) {
if( !strncasecmp( dn, "dn:", 3) &&
( ( flags & FLAG_GETDN_FINAL ) == 0 ) )
{
c1 = slap_sasl2dn( dn + 3 );
if( c1 ) {
ch_free( dn );
......@@ -216,9 +218,10 @@ int slap_sasl_getdn( Connection *conn, char *id, char **dnptr, int flags )
#ifdef NEW_LOGGING
LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
"slap_sasl_getdn: dn:id converted to %s.\n", dn ));
"slap_sasl_getdn: dn:id converted to %s.\n", dn ));
#else
Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n", dn,0,0 );
Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
dn, 0, 0 );
#endif
}
}
......
......@@ -300,9 +300,6 @@ char *slap_sasl_regexp( char *saslname )
}
/*
* Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
* return the LDAP DN to which it matches. The SASL regexp rules in the config
......@@ -314,8 +311,10 @@ char *slap_sasl_regexp( char *saslname )
char *slap_sasl2dn( char *saslname )
{
char *uri=NULL, *DN=NULL;
char *uri=NULL;
struct berval searchbase = {0, NULL};
struct berval dn = {0, NULL};
struct berval *ndn = NULL;
int rc, scope;
Backend *be;
Filter *filter=NULL;
......@@ -323,28 +322,27 @@ char *slap_sasl2dn( char *saslname )
LDAP *client=NULL;
LDAPMessage *res=NULL, *msg;
#ifdef NEW_LOGGING
LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
"slap_sasl2dn: converting SASL name %s to DN.\n", saslname ));
"slap_sasl2dn: converting SASL name %s to DN.\n", saslname ));
#else
Debug( LDAP_DEBUG_TRACE,
"==>slap_sasl2dn: Converting SASL name %s to a DN\n", saslname, 0,0 );
"==>slap_sasl2dn: Converting SASL name %s to a DN\n", saslname, 0,0 );
#endif
/* Convert the SASL name into an LDAP URI */
uri = slap_sasl_regexp( saslname );
if( uri == NULL )
goto FINISHED;
rc = slap_parseURI( uri, &searchbase, &scope, &filter );
if( rc )
if( rc ) {
goto FINISHED;
}
/* Massive shortcut: search scope == base */
if( scope == LDAP_SCOPE_BASE ) {
DN = searchbase.bv_val;
dn = searchbase;
searchbase.bv_len = 0;
searchbase.bv_val = NULL;
goto FINISHED;
......@@ -396,8 +394,19 @@ char *slap_sasl2dn( char *saslname )
goto FINISHED;
msg = ldap_first_entry( client, res );
DN = ldap_get_dn( client, msg );
if( DN ) dn_normalize( DN );
dn.bv_val = ldap_get_dn( client, msg );
dn.bv_len = dn.bv_val ? strlen( dn.bv_val ) : 0;
if( dn.bv_val ) {
rc = dnNormalize( NULL, &dn, &ndn );
ldap_memfree( dn.bv_val );
if( rc != LDAP_SUCCESS ) {
dn.bv_val = NULL;
dn.bv_len = 0;
goto FINISHED;
}
dn = *ndn;
free( ndn );
}
FINISHED:
if( searchbase.bv_len ) ch_free( searchbase.bv_val );
......@@ -406,21 +415,20 @@ FINISHED:
if( conn ) connection_internal_close( conn );
if( res ) ldap_msgfree( res );
if( client ) ldap_unbind( client );
#ifdef NEW_LOGGING
LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
"slap_sasl2dn: Converted SASL name to %s\n", DN ? DN : "<nothing>" ));
"slap_sasl2dn: Converted SASL name to %s\n",
dn.bv_len ? dn.bv_val : "<nothing>" ));
#else
Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
DN ? DN : "<nothing>", 0, 0 );
dn.bv_len ? dn.bv_val : "<nothing>", 0, 0 );
#endif
return( DN );
return( dn.bv_val );
}
/*
* Map a SASL regexp rule to a DN. If the rule is just a DN or a scope=base
* URI, just strcmp the rule (or its searchbase) to the *assertDN. Otherwise,
......@@ -433,7 +441,6 @@ FINISHED:
static
int slap_sasl_match( char *rule, char *assertDN, char *authc )
{
char *dn=NULL;
struct berval searchbase = {0, NULL};
int rc, scope;
Backend *be;
......@@ -443,23 +450,22 @@ int slap_sasl_match( char *rule, char *assertDN, char *authc )
LDAPMessage *res=NULL, *msg;
regex_t reg;
#ifdef NEW_LOGGING
LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
"slap_sasl_match: comparing DN %s to rule %s\n", assertDN, rule ));
"slap_sasl_match: comparing DN %s to rule %s\n", assertDN, rule ));
#else
Debug( LDAP_DEBUG_TRACE,
"===>slap_sasl_match: comparing DN %s to rule %s\n", assertDN, rule, 0 );
#endif
rc = slap_parseURI( rule, &searchbase, &scope, &filter );
if( rc != LDAP_SUCCESS )
goto CONCLUDED;
/* Massive shortcut: search scope == base */
if( scope == LDAP_SCOPE_BASE ) {
rc = regcomp(&reg, searchbase.bv_val, REG_EXTENDED|REG_ICASE|REG_NOSUB);
rc = regcomp(&reg, searchbase.bv_val,
REG_EXTENDED|REG_ICASE|REG_NOSUB);
if ( rc == 0 ) {
rc = regexec(&reg, assertDN, 0, NULL, 0);
regfree( &reg );
......@@ -475,15 +481,14 @@ int slap_sasl_match( char *rule, char *assertDN, char *authc )
#ifdef NEW_LOGGING
LDAP_LOG(( "sasl", LDAP_LEVEL_DETAIL1,
"slap_sasl_match: performing internal search (base=%s, scope=%d)\n",
searchbase.bv_val, scope ));
"slap_sasl_match: performing internal search (base=%s, scope=%d)\n",
searchbase.bv_val, scope ));
#else
Debug( LDAP_DEBUG_TRACE,
"slap_sasl_match: performing internal search (base=%s, scope=%d)\n",
searchbase.bv_val, scope, 0 );
#endif
be = select_backend( &searchbase, 0, 1 );
if(( be == NULL ) || ( be->be_search == NULL)) {
rc = LDAP_INAPPROPRIATE_AUTH;
......@@ -500,7 +505,6 @@ int slap_sasl_match( char *rule, char *assertDN, char *authc )
scope, /*deref=*/1, /*sizelimit=*/0, /*time=*/0, filter, /*fstr=*/NULL,
/*attrs=*/NULL, /*attrsonly=*/0 );
/* On the client side of the internal search, read the results. Check
if the assertDN matches any of the DN's returned by the search */
rc = ldap_result( client, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
......@@ -509,14 +513,25 @@ int slap_sasl_match( char *rule, char *assertDN, char *authc )
for( msg=ldap_first_entry( client, res );
msg;
msg=ldap_next_entry( client, msg ) ) {
dn = ldap_get_dn( client, msg );
dn_normalize( dn );
rc = strcmp( dn, assertDN );
ch_free( dn );
if( rc == 0 ) {
rc = LDAP_SUCCESS;
goto CONCLUDED;
msg=ldap_next_entry( client, msg ) )
{
struct berval dn;
dn.bv_val = ldap_get_dn( client, msg );
if( dn.bv_val ) {
struct berval *ndn = NULL;
dn.bv_len = strlen( dn.bv_val );
rc = dnNormalize( NULL, &dn, &ndn );
ldap_memfree( dn.bv_val );
if( rc != LDAP_SUCCESS ) {
goto CONCLUDED;
}
rc = strcmp( ndn->bv_val, assertDN );
ber_bvfree( ndn );
if( rc == 0 ) {
rc = LDAP_SUCCESS;
goto CONCLUDED;
}
}
}
rc = LDAP_INAPPROPRIATE_AUTH;
......
......@@ -26,7 +26,6 @@
#define ldap_debug slap_debug
#endif
#include "ldap_log.h"
#include <ldap.h>
......@@ -114,7 +113,7 @@ LDAP_BEGIN_DECL
/* must match in schema_init.c */
#define SLAPD_DN_SYNTAX "1.3.6.1.4.1.1466.115.121.1.12"
#define SLAPD_NAMEUID_SYNTAX "1.3.6.1.4.1.1466.115.121.1.34"
#define SLAPD_NAMEUID_SYNTAX "1.3.6.1.4.1.1466.115.121.1.34"
#define SLAPD_GROUP_ATTR "member"
#define SLAPD_GROUP_CLASS "groupOfNames"
#define SLAPD_ROLE_ATTR "roleOccupant"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment