to validate input dn's BEFORE sending dn's to server.
Also fixed getfilter to use REG_EXTENDED|REG_NOSUB. (and fixed one
case where REG_BASIC was still used).
s/strdup/LDAP_STRDUP/
Added ldap_pvt_str2lower/upper
#define FIVEMINS ( 5 * 60 )
#define TGT "krbtgt"
-static void
-str2upper( char *s )
-{
- char *p;
-
- for ( p = s; *p != '\0'; ++p ) {
- *p = TOUPPER( (unsigned char) *p );
- }
-}
-
-
static int
valid_tgt( char **names )
{
/*
* realm must be uppercase for krb_ routines
*/
- str2upper( realm );
+ ldap_pvt_str2upper( realm );
#endif /* HAVE_AFS_KERBEROS */
/*
/*
* realm must be uppercase for krb_ routines
*/
- str2upper( realm );
+ ldap_pvt_str2upper( realm );
#endif /* HAVE_AFS_KERBEROS */
rc = krb_get_in_tkt( name, inst, realm, TGT, realm,
void ldap_pvt_hex_unescape LDAP_P(( char *s ));
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) == '+')
+#define LDAP_SPACE(c) ((c) == ' ' || (c) == '\n')
+
+#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)) || (c) == '.' )
+
+#define LDAP_NEEDSESCAPE(c) ((c) == '\\' || (c) == '"')
+
+/* string.c */
+LDAP_F( char * )
+ldap_pvt_str2upper LDAP_P(( char *str ));
+
+LDAP_F( char * )
+ldap_pvt_str2lower LDAP_P(( char *str ));
+
LDAP_END_DECL
#endif
--- /dev/null
+/* dn.c - routines for dealing with distinguished names */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+#define B4LEADTYPE 0
+#define B4TYPE 1
+#define INOIDTYPE 2
+#define INKEYTYPE 3
+#define B4EQUAL 4
+#define B4VALUE 5
+#define INVALUE 6
+#define INQUOTEDVALUE 7
+#define B4SEPARATOR 8
+
+/*
+ * ldap_dn_normalize - put dn into a canonical format
+ * and return it.
+ */
+
+char *
+ldap_dn_normalize( const char *dn )
+{
+ char *d, *s;
+ int state, gotesc;
+ char *ndn;
+
+ if( dn == NULL ) {
+ return NULL;
+ }
+
+ ndn = LDAP_STRDUP( dn );
+
+ if( ndn == NULL ) {
+ return NULL;
+ }
+
+ gotesc = 0;
+ state = B4LEADTYPE;
+ for ( d = s = ndn; *s; s++ ) {
+ switch ( state ) {
+ case B4LEADTYPE:
+ case B4TYPE:
+ if ( LDAP_LEADOIDCHAR(*s) ) {
+ state = INOIDTYPE;
+ *d++ = *s;
+ } else if ( LDAP_LEADKEYCHAR(*s) ) {
+ state = INKEYTYPE;
+ *d++ = *s;
+ } else if ( ! LDAP_SPACE( *s ) ) {
+ dn = NULL;
+ state = INKEYTYPE;
+ *d++ = *s;
+ }
+ break;
+
+ case INOIDTYPE:
+ if ( LDAP_OIDCHAR(*s) ) {
+ *d++ = *s;
+ } else if ( *s == '=' ) {
+ state = B4VALUE;
+ *d++ = *s;
+ } else if ( LDAP_SPACE( *s ) ) {
+ state = B4EQUAL;
+ } else {
+ dn = NULL;
+ *d++ = *s;
+ }
+ break;
+
+ case INKEYTYPE:
+ if ( LDAP_KEYCHAR(*s) ) {
+ *d++ = *s;
+ } else if ( *s == '=' ) {
+ state = B4VALUE;
+ *d++ = *s;
+ } else if ( LDAP_SPACE( *s ) ) {
+ state = B4EQUAL;
+ } else {
+ dn = NULL;
+ *d++ = *s;
+ }
+ break;
+
+ case B4EQUAL:
+ if ( *s == '=' ) {
+ state = B4VALUE;
+ *d++ = *s;
+ } else if ( ! LDAP_SPACE( *s ) ) {
+ /* not a valid dn - but what can we do here? */
+ *d++ = *s;
+ dn = NULL;
+ }
+ break;
+
+ case B4VALUE:
+ if ( *s == '"' ) {
+ state = INQUOTEDVALUE;
+ *d++ = *s;
+ } else if ( ! LDAP_SPACE( *s ) ) {
+ state = INVALUE;
+ *d++ = *s;
+ }
+ break;
+
+ case INVALUE:
+ if ( !gotesc && LDAP_SEPARATOR( *s ) ) {
+ while ( LDAP_SPACE( *(d - 1) ) )
+ d--;
+ state = B4TYPE;
+ if ( *s == '+' ) {
+ *d++ = *s;
+ } else {
+ *d++ = ',';
+ }
+ } else if ( gotesc && !LDAP_NEEDSESCAPE( *s ) &&
+ !LDAP_SEPARATOR( *s ) ) {
+ *--d = *s;
+ d++;
+ } else {
+ *d++ = *s;
+ }
+ break;
+
+ case INQUOTEDVALUE:
+ if ( !gotesc && *s == '"' ) {
+ state = B4SEPARATOR;
+ *d++ = *s;
+ } else if ( gotesc && !LDAP_NEEDSESCAPE( *s ) ) {
+ *--d = *s;
+ d++;
+ } else {
+ *d++ = *s;
+ }
+ break;
+ case B4SEPARATOR:
+ if ( LDAP_SEPARATOR( *s ) ) {
+ state = B4TYPE;
+ *d++ = *s;
+ }
+ break;
+ default:
+ dn = NULL;
+ Debug( LDAP_DEBUG_ANY,
+ "dn_normalize - unknown state %d\n", state, 0, 0 );
+ break;
+ }
+ if ( *s == '\\' ) {
+ gotesc = 1;
+ } else {
+ gotesc = 0;
+ }
+ }
+ *d = '\0';
+
+ if( gotesc ) {
+ /* shouldn't be left in escape */
+ dn = NULL;
+ }
+
+ /* check end state */
+ switch( state ) {
+ case B4LEADTYPE: /* looking for first type */
+ case B4SEPARATOR: /* looking for separator */
+ case INVALUE: /* inside value */
+ break;
+ default:
+ dn = NULL;
+ }
+
+ if( dn == NULL ) {
+ return( ndn );
+ ndn = NULL;
+ }
+
+ return( ndn );
+}
+
+/*
+ * ldap_dn_parent - return a copy of the dn of dn's parent
+ */
+
+char *
+ldap_dn_parent(
+ const char *dn
+)
+{
+ const char *s;
+ int inquote;
+
+ if( dn == NULL ) {
+ return NULL;
+ }
+
+ while(*dn && LDAP_SPACE(*dn)) {
+ dn++;
+ }
+
+ if( *dn == '\0' ) {
+ return( NULL );
+ }
+
+ /*
+ * no =, assume it is a dns name, like blah@some.domain.name
+ * if the blah@ part is there, return some.domain.name. if
+ * it's just some.domain.name, return domain.name.
+ */
+ if ( strchr( dn, '=' ) == NULL ) {
+ if ( (s = strchr( dn, '@' )) == NULL ) {
+ if ( (s = strchr( dn, '.' )) == NULL ) {
+ return( NULL );
+ }
+ }
+ if ( *(s + 1) == '\0' ) {
+ return( NULL );
+ } else {
+ return( LDAP_STRDUP( &s[1] ) );
+ }
+ }
+
+ /*
+ * else assume it is an X.500-style name, which looks like
+ * foo=bar,sha=baz,...
+ */
+
+ inquote = 0;
+ for ( s = dn; *s; s++ ) {
+ if ( *s == '\\' ) {
+ if ( *(s + 1) ) {
+ s++;
+ }
+ continue;
+ }
+ if ( inquote ) {
+ if ( *s == '"' ) {
+ inquote = 0;
+ }
+ } else {
+ if ( *s == '"' ) {
+ inquote = 1;
+ } else if ( LDAP_DNSEPARATOR( *s ) ) {
+ return( LDAP_STRDUP( &s[1] ) );
+ }
+ }
+ }
+
+ return( LDAP_STRDUP( "" ) );
+}
+
+char * ldap_dn_rdn(
+ const char *dn )
+{
+ char *s;
+ char *rdn;
+ int inquote;
+
+ if( dn == NULL ) {
+ return NULL;
+ }
+
+ while(*dn && LDAP_SPACE(*dn)) {
+ dn++;
+ }
+
+ if( *dn == '\0' ) {
+ return( NULL );
+ }
+
+ rdn = LDAP_STRDUP( dn );
+
+ if( rdn == NULL ) {
+ return NULL;
+ }
+
+#ifdef DNS_DN
+ /*
+ * no =, assume it is a dns name, like blah@some.domain.name
+ * if the blah@ part is there, return some.domain.name. if
+ * it's just some.domain.name, return domain.name.
+ */
+ if ( strchr( rdn, '=' ) == NULL ) {
+ if ( (s = strchr( rdn, '@' )) == NULL ) {
+ if ( (s = strchr( rdn, '.' )) == NULL ) {
+ return( rdn );
+ }
+ }
+ *s = '\0';
+ return( rdn );
+ }
+#endif
+
+ /*
+ * else assume it is an X.500-style name, which looks like
+ * foo=bar,sha=baz,...
+ */
+
+ inquote = 0;
+
+ for ( s = rdn; *s; s++ ) {
+ if ( *s == '\\' ) {
+ if ( *(s + 1) ) {
+ s++;
+ }
+ continue;
+ }
+ if ( inquote ) {
+ if ( *s == '"' ) {
+ inquote = 0;
+ }
+ } else {
+ if ( *s == '"' ) {
+ inquote = 1;
+ } else if ( LDAP_DNSEPARATOR( *s ) ) {
+ *s = '\0';
+ return( rdn );
+ }
+ }
+ }
+
+ return( rdn );
+}
Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
- if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL )
+ if( dn == NULL ) {
+ return NULL;
+ }
+
+ if ( ldap_is_dns_dn( dn ) ) {
return( LDAP_STRDUP( dn ) );
+ }
ufn = LDAP_STRDUP( ++p );
int
ldap_is_dns_dn( LDAP_CONST char *dn )
{
- return( dn[ 0 ] != '\0' && strchr( dn, '=' ) == NULL &&
- strchr( dn, ',' ) == NULL );
+ return( dn[ 0 ] != '\0'
+ && strchr( dn, '=' ) == NULL
+ && strchr( dn, ',' ) == NULL
+ && strchr( dn, ';' ) == NULL );
}
for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
/* compile tagpat, continue if we fail */
- if (regcomp(&re, tagpat, 0) != 0)
+ if (regcomp(&re, tagpat, REG_EXTENDED|REG_NOSUB) != 0)
continue;
- /* match tagpatern and tag, continue if we fail */
+ /* match tagpattern and tag, continue if we fail */
rc = regexec(&re, flp->lfl_tag, 0, NULL, 0);
regfree(&re);
if (rc != 0)
continue;
/* compile flp->ifl_pattern, continue if we fail */
- if (regcomp(&re, flp->lfl_pattern, REG_EXTENDED) != 0)
+ if (regcomp(&re, flp->lfl_pattern, REG_EXTENDED|REG_NOSUB) != 0)
continue;
/* match ifl_pattern and lfd_curval, continue if we fail */
# End Source File
# Begin Source File
+SOURCE=.\dn.c
+# End Source File
+# Begin Source File
+
SOURCE=.\dsparse.c
# End Source File
# Begin Source File
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/time.h>
+#include <ac/ctype.h>
#include "ldap-int.h"
memcpy( p, s, len );
return( p );
}
+
+char *
+ldap_pvt_str2upper( char *str )
+{
+ char *s;
+
+ /* to upper */
+ for ( s = str; *s; s++ ) {
+ *s = TOUPPER( (unsigned char) *s );
+ }
+
+ return( str );
+}
+
+char *
+ldap_pvt_str2lower( char *str )
+{
+ char *s;
+
+ /* to lower */
+ for ( s = str; *s; s++ ) {
+ *s = TOLOWER( (unsigned char) *s );
+ }
+
+ return( str );
+}
break;
case LDAP_OPT_X_TLS_CACERTFILE:
*(char **)arg = tls_opt_cacertfile ?
- strdup( tls_opt_cacertfile ) : NULL;
+ LDAP_STRDUP( tls_opt_cacertfile ) : NULL;
break;
case LDAP_OPT_X_TLS_CACERTDIR:
*(char **)arg = tls_opt_cacertdir ?
- strdup( tls_opt_cacertdir ) : NULL;
+ LDAP_STRDUP( tls_opt_cacertdir ) : NULL;
break;
case LDAP_OPT_X_TLS_CERTFILE:
*(char **)arg = tls_opt_certfile ?
- strdup( tls_opt_certfile ) : NULL;
+ LDAP_STRDUP( tls_opt_certfile ) : NULL;
break;
case LDAP_OPT_X_TLS_KEYFILE:
*(char **)arg = tls_opt_keyfile ?
- strdup( tls_opt_keyfile ) : NULL;
+ LDAP_STRDUP( tls_opt_keyfile ) : NULL;
break;
case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(int *)arg = tls_opt_require_cert;
switch( option ) {
case LDAP_OPT_X_TLS_CACERTFILE:
if ( tls_opt_cacertfile ) free( tls_opt_cacertfile );
- tls_opt_cacertfile = arg ? strdup( (char *) arg ) : NULL;
+ tls_opt_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
case LDAP_OPT_X_TLS_CACERTDIR:
if ( tls_opt_cacertdir ) free( tls_opt_cacertdir );
- tls_opt_cacertdir = arg ? strdup( (char *) arg ) : NULL;
+ tls_opt_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
case LDAP_OPT_X_TLS_CERTFILE:
if ( tls_opt_certfile ) free( tls_opt_certfile );
- tls_opt_certfile = arg ? strdup( (char *) arg ) : NULL;
+ tls_opt_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
case LDAP_OPT_X_TLS_KEYFILE:
if ( tls_opt_keyfile ) free( tls_opt_keyfile );
- tls_opt_keyfile = arg ? strdup( (char *) arg ) : NULL;
+ tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
case LDAP_OPT_X_TLS_REQUIRE_CERT:
tls_opt_require_cert = * (int *) arg;
break;
case LDAP_OPT_X_TLS_CIPHER_SUITE:
if ( tls_opt_ciphersuite ) free( tls_opt_ciphersuite );
- tls_opt_ciphersuite = arg ? strdup( (char *) arg ) : NULL;
+ tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
default:
return -1;
#include <sys/param.h>
#endif
+#include "ldap_pvt.h"
#include "ldap_defaults.h"
#include "slap.h"
{
assert( s != NULL );
- return( str2lower( s ) );
+ return( ldap_pvt_str2lower( s ) );
}
/*
#include <ac/ctype.h>
#include <ac/socket.h>
+#include "ldap_pvt.h"
#include "ldap_defaults.h"
#include "slap.h"
char *dn = ch_strdup( cargv[1] );
(void) dn_normalize( dn );
charray_add( &be->be_suffix, dn );
- (void) str2upper( dn );
+ (void) ldap_pvt_str2upper( dn );
charray_add( &be->be_nsuffix, dn );
free( dn );
}
#include <ac/time.h>
#include <ac/unistd.h>
+#include "ldap_pvt.h"
#include "ldap_defaults.h"
#include "slap.h"
sizeof(from.sin_addr.s_addr), AF_INET );
if(hp) {
- dnsname = str2lower( hp->h_name );
+ dnsname = ldap_pvt_str2lower( hp->h_name );
} else {
dnsname = NULL;
#include <ac/string.h>
#include <ac/time.h>
+#include "ldap_pvt.h"
+
#include "slap.h"
#define B4LEADTYPE 0
char *
dn_normalize_case( char *dn )
{
- str2upper( dn );
+ ldap_pvt_str2upper( dn );
/* normalize format */
dn = dn_normalize( dn );
return( NULL );
}
+#ifdef DNS_DN
/*
* no =, assume it is a dns name, like blah@some.domain.name
* if the blah@ part is there, return some.domain.name. if
return( ch_strdup( &s[1] ) );
}
}
+#endif
/*
* else assume it is an X.500-style name, which looks like
}
#endif
-char *
-str2upper( char *str )
-{
- char *s;
-
- /* normalize case */
- for ( s = str; *s; s++ ) {
- *s = TOUPPER( (unsigned char) *s );
- }
-
- return( str );
-}
-
-char *
-str2lower( char *str )
-{
- char *s;
-
- /* normalize case */
- for ( s = str; *s; s++ ) {
- *s = TOLOWER( (unsigned char) *s );
- }
-
- return( str );
-}
-
-
/*
* get_next_substring(), rdn_attr_type(), rdn_attr_value(), and
* build_new_dn().
/* table to compute syslog-options to integer */
static STRDISP syslog_types[] = {
- { "LOCAL0", 6, LOG_LOCAL0 },
- { "LOCAL1", 6, LOG_LOCAL1 },
- { "LOCAL2", 6, LOG_LOCAL2 },
- { "LOCAL3", 6, LOG_LOCAL3 },
- { "LOCAL4", 6, LOG_LOCAL4 },
- { "LOCAL5", 6, LOG_LOCAL5 },
- { "LOCAL6", 6, LOG_LOCAL6 },
- { "LOCAL7", 6, LOG_LOCAL7 },
- { NULL }
+ { "LOCAL0", sizeof("LOCAL0"), LOG_LOCAL0 },
+ { "LOCAL1", sizeof("LOCAL1"), LOG_LOCAL1 },
+ { "LOCAL2", sizeof("LOCAL2"), LOG_LOCAL2 },
+ { "LOCAL3", sizeof("LOCAL3"), LOG_LOCAL3 },
+ { "LOCAL4", sizeof("LOCAL4"), LOG_LOCAL4 },
+ { "LOCAL5", sizeof("LOCAL5"), LOG_LOCAL5 },
+ { "LOCAL6", sizeof("LOCAL6"), LOG_LOCAL6 },
+ { "LOCAL7", sizeof("LOCAL7"), LOG_LOCAL7 },
+ { NULL }
};
static int cnvt_str2int( char *, STRDISP_P, int );
#ifdef DNS_DN
int dn_type LDAP_P(( char *dn ));
#endif
-char * str2upper LDAP_P(( char *str ));
-char * str2lower LDAP_P(( char *str ));
int rdn_validate LDAP_P(( const char* str ));
char * rdn_attr_value LDAP_P(( char * rdn ));
char * rdn_attr_type LDAP_P(( char * rdn ));