X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblutil%2Fldif.c;h=2af75fb73236caec40a64534769da10db1b26c6e;hb=c3e28a5488a8011ef0352f48fca85c48679205ba;hp=e0412b2ae903be75121a7a7deed3ee4d413065bf;hpb=67583f45eb2fafd9a5455a3c69aedf7ec7cbb26a;p=openldap diff --git a/libraries/liblutil/ldif.c b/libraries/liblutil/ldif.c index e0412b2ae9..2af75fb732 100644 --- a/libraries/liblutil/ldif.c +++ b/libraries/liblutil/ldif.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -147,7 +147,7 @@ ldif_parse_line2( if ( s == NULL ) { ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, _("ldif_parse_line: missing ':' after %s\n"), - type ); + type->bv_val ); if ( !freeval ) ber_memfree( line ); return( -1 ); } @@ -190,7 +190,8 @@ ldif_parse_line2( if ( *s == '\0' ) { /* no value is present, error out */ ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, - _("ldif_parse_line: %s missing base64 value\n"), type ); + _("ldif_parse_line: %s missing base64 value\n"), + type->bv_val ); if ( !freeval ) ber_memfree( line ); return( -1 ); } @@ -205,7 +206,7 @@ ldif_parse_line2( ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, _("ldif_parse_line: %s: invalid base64 encoding" " char (%c) 0x%x\n"), - type, p[i], p[i] ); + type->bv_val, p[i], p[i] ); if ( !freeval ) ber_memfree( line ); return( -1 ); } @@ -242,7 +243,8 @@ ldif_parse_line2( if ( *s == '\0' ) { /* no value is present, error out */ ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, - _("ldif_parse_line: %s missing URL value\n"), type ); + _("ldif_parse_line: %s missing URL value\n"), + type->bv_val ); if ( !freeval ) ber_memfree( line ); return( -1 ); } @@ -250,7 +252,7 @@ ldif_parse_line2( if( ldif_fetch_url( s, &value->bv_val, &value->bv_len ) ) { ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, _("ldif_parse_line: %s: URL \"%s\" fetch failed\n"), - type, s ); + type->bv_val, s ); if ( !freeval ) ber_memfree( line ); return( -1 ); } @@ -359,6 +361,131 @@ ldif_getline( char **next ) return( line ); } +/* + * name and OID of attributeTypes that must be base64 encoded in any case + */ +typedef struct must_b64_encode_s { + struct berval name; + struct berval oid; +} must_b64_encode_s; + +static must_b64_encode_s default_must_b64_encode[] = { + { BER_BVC( "userPassword" ), BER_BVC( "2.5.4.35" ) }, + { BER_BVNULL, BER_BVNULL } +}; + +static must_b64_encode_s *must_b64_encode = default_must_b64_encode; + +/* + * register name and OID of attributeTypes that must always be base64 + * encoded + * + * NOTE: this routine mallocs memory in a static struct which must + * be explicitly freed when no longer required + */ +int +ldif_must_b64_encode_register( LDAP_CONST char *name, LDAP_CONST char *oid ) +{ + int i; + ber_len_t len; + + assert( must_b64_encode != NULL ); + assert( name != NULL ); + assert( oid != NULL ); + + len = strlen( name ); + + for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) { + if ( len != must_b64_encode[i].name.bv_len ) { + continue; + } + + if ( strcasecmp( name, must_b64_encode[i].name.bv_val ) == 0 ) { + break; + } + } + + if ( !BER_BVISNULL( &must_b64_encode[i].name ) ) { + return 1; + } + + for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) + /* just count */ ; + + if ( must_b64_encode == default_must_b64_encode ) { + must_b64_encode = ber_memalloc( sizeof( must_b64_encode_s ) * ( i + 2 ) ); + + for ( i = 0; !BER_BVISNULL( &default_must_b64_encode[i].name ); i++ ) { + ber_dupbv( &must_b64_encode[i].name, &default_must_b64_encode[i].name ); + ber_dupbv( &must_b64_encode[i].oid, &default_must_b64_encode[i].oid ); + } + + } else { + must_b64_encode_s *tmp; + + tmp = ber_memrealloc( must_b64_encode, + sizeof( must_b64_encode_s ) * ( i + 2 ) ); + if ( tmp == NULL ) { + return 1; + } + must_b64_encode = tmp; + } + + ber_str2bv( name, len, 1, &must_b64_encode[i].name ); + ber_str2bv( oid, 0, 1, &must_b64_encode[i].oid ); + + BER_BVZERO( &must_b64_encode[i + 1].name ); + + return 0; +} + +void +ldif_must_b64_encode_release( void ) +{ + int i; + + assert( must_b64_encode != NULL ); + + if ( must_b64_encode == default_must_b64_encode ) { + return; + } + + for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) { + ber_memfree( must_b64_encode[i].name.bv_val ); + ber_memfree( must_b64_encode[i].oid.bv_val ); + } + + ber_memfree( must_b64_encode ); + + must_b64_encode = default_must_b64_encode; +} + +/* + * returns 1 iff the string corresponds to the name or the OID of any + * of the attributeTypes listed in must_b64_encode + */ +static int +ldif_must_b64_encode( LDAP_CONST char *s ) +{ + int i; + struct berval bv; + + assert( must_b64_encode != NULL ); + assert( s != NULL ); + + ber_str2bv( s, 0, 0, &bv ); + + for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) { + if ( ber_bvstrcasecmp( &must_b64_encode[i].name, &bv ) == 0 + || ber_bvcmp( &must_b64_encode[i].oid, &bv ) == 0 ) + { + return 1; + } + } + + return 0; +} + /* compatibility with U-Mich off by one bug */ #define LDIF_KLUDGE 1 @@ -479,10 +606,7 @@ ldif_sput( && strstr( name, ";binary" ) == NULL #endif #ifndef LDAP_PASSWD_DEBUG - && (namelen != (sizeof("userPassword")-1) - || strcasecmp( name, "userPassword" ) != 0) /* encode userPassword */ - && (namelen != (sizeof("2.5.4.35")-1) - || strcasecmp( name, "2.5.4.35" ) != 0) /* encode userPassword */ + && !ldif_must_b64_encode( name ) #endif ) { int b64 = 0; @@ -610,7 +734,7 @@ int ldif_is_not_printable( ber_len_t i; for ( i = 0; val[i]; i++ ) { - if ( !isascii( val[i] ) || !isprint( val[i] ) ) { + if ( !isascii( val[i] ) || !isprint( (unsigned char) val[i] ) ) { return 1; } } @@ -621,25 +745,76 @@ int ldif_is_not_printable( return 1; } +LDIFFP * +ldif_open( + LDAP_CONST char *file, + LDAP_CONST char *mode +) +{ + FILE *fp = fopen( file, mode ); + LDIFFP *lfp = NULL; + + if ( fp ) { + lfp = ber_memalloc( sizeof( LDIFFP )); + lfp->fp = fp; + lfp->prev = NULL; + } + return lfp; +} + +void +ldif_close( + LDIFFP *lfp +) +{ + LDIFFP *prev; + + while ( lfp ) { + fclose( lfp->fp ); + prev = lfp->prev; + ber_memfree( lfp ); + lfp = prev; + } +} + +#define LDIF_MAXLINE 4096 + /* - * slap_read_ldif - read an ldif record. Return 1 for success, 0 for EOF. + * ldif_read_record - read an ldif record. Return 1 for success, 0 for EOF. */ int ldif_read_record( - FILE *fp, + LDIFFP *lfp, int *lno, /* ptr to line number counter */ char **bufp, /* ptr to malloced output buffer */ int *buflenp ) /* ptr to length of *bufp */ { - char linebuf[BUFSIZ], *line, *nbufp; + char linebuf[LDIF_MAXLINE], *line, *nbufp; ber_len_t lcur = 0, len, linesize; int last_ch = '\n', found_entry = 0, stop, top_comment = 0; line = linebuf; linesize = sizeof( linebuf ); - for ( stop = feof( fp ); !stop; last_ch = line[len-1] ) { - if ( fgets( line, linesize, fp ) == NULL ) { + for ( stop = 0; !stop; last_ch = line[len-1] ) { + /* If we're at the end of this file, see if we should pop + * back to a previous file. (return from an include) + */ + while ( feof( lfp->fp )) { + if ( lfp->prev ) { + LDIFFP *tmp = lfp->prev; + fclose( lfp->fp ); + *lfp = *tmp; + ber_memfree( tmp ); + } else { + stop = 1; + break; + } + } + if ( stop ) + break; + + if ( fgets( line, linesize, lfp->fp ) == NULL ) { stop = 1; /* Add \n in case the file does not end with newline */ line = "\n"; @@ -649,7 +824,8 @@ ldif_read_record( if ( last_ch == '\n' ) { (*lno)++; - if ( line[0] == '\n' ) { + if ( line[0] == '\n' || + ( line[0] == '\r' && line[1] == '\n' )) { if ( !found_entry ) { lcur = 0; top_comment = 0; @@ -669,12 +845,46 @@ ldif_read_record( /* skip index */ continue; } + if ( !strncasecmp( line, "include:", + STRLENOF("include:"))) { + FILE *fp2; + char *ptr; + found_entry = 0; + + if ( line[len-1] == '\n' ) { + len--; + line[len] = '\0'; + } + if ( line[len-1] == '\r' ) { + len--; + line[len] = '\0'; + } + + ptr = line + STRLENOF("include:"); + while (isspace((unsigned char) *ptr)) ptr++; + fp2 = ldif_open_url( ptr ); + if ( fp2 ) { + LDIFFP *lnew = ber_memalloc( sizeof( LDIFFP )); + lnew->prev = lfp->prev; + lnew->fp = lfp->fp; + lfp->prev = lnew; + lfp->fp = fp2; + line[len] = '\n'; + len++; + continue; + } else { + /* We failed to open the file, this should + * be reported as an error somehow. + */ + break; + } + } } } } if ( *buflenp - lcur <= len ) { - *buflenp += len + BUFSIZ; + *buflenp += len + LDIF_MAXLINE; nbufp = ber_memrealloc( *bufp, *buflenp ); if( nbufp == NULL ) { return 0;