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,
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,
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 */
#include <stdio.h>
#include <ac/stdlib.h>
-
-#include <ac/ctype.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
#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' )
/* 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) \
/* 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) "
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 );
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;
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;
ber_bvfree( hash );
}
+ if( ndn != NULL ) {
+ ber_bvfree( ndn );
+ }
+
return rc;
}
)
{
for ( ; len--; ) {
- if ( LDAP_DNSEPARATOR( rdn[ len ] ) ) {
+ if ( DN_SEPARATOR( rdn[ len ] ) ) {
return 0;
}
}
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.
*
* Deprecated; directly use LDAPRDN from ldap_str2rdn
*/
-
int
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;
* Must validate (there's a repeated parsing ...)
*/
return ( rc == LDAP_SUCCESS );
+#endif
}
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;
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 ));
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,
}
/* 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 );
#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
}
}
}
-
-
-
/*
* 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
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;
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;
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 );
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,
static
int slap_sasl_match( char *rule, char *assertDN, char *authc )
{
- char *dn=NULL;
struct berval searchbase = {0, NULL};
int rc, scope;
Backend *be;
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(®, searchbase.bv_val, REG_EXTENDED|REG_ICASE|REG_NOSUB);
+ rc = regcomp(®, searchbase.bv_val,
+ REG_EXTENDED|REG_ICASE|REG_NOSUB);
if ( rc == 0 ) {
rc = regexec(®, assertDN, 0, NULL, 0);
regfree( ® );
#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;
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 );
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;
#define ldap_debug slap_debug
#endif
-
#include "ldap_log.h"
#include <ldap.h>
/* 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"