/* * Copyright (c) 1990 Regents of the University of Michigan. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of Michigan at Ann Arbor. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. */ #include #include #include #include #include #include #include #include #include #include #include #include "lber.h" #include "ldap.h" #include "common.h" short ldap_photo_syntax; short ldap_jpeg_syntax; short ldap_jpeg_nonfile_syntax; short ldap_audio_syntax; short ldap_dn_syntax; short ldap_postaladdress_syntax; short ldap_acl_syntax; short ldap_mtai_syntax; short ldap_rts_cred_syntax; short ldap_rtl_syntax; short ldap_mailbox_syntax; short ldap_caseignorelist_syntax; short ldap_caseexactstring_syntax; short ldap_certif_syntax; short ldap_iattr_syntax; short ldap_telex_syntax; short ldap_octetstring_syntax; short ldap_deliverymethod_syntax; short ldap_facsimileTelephoneNumber_syntax; short ldap_presentationAddress_syntax; short ldap_teletexTerminalIdentifier_syntax; short ldap_searchGuide_syntax; short ldap_dLSubmitPermission_syntax; static void de_t61( char *s, int t61mark ); static int syntax_is_string( short syntax ); static get_one_syntax( char *attrib, int required ) { oid_table_attr *p, *name2attr(); if ( (p = name2attr( attrib )) != (oid_table_attr *) 0 ) return( p->oa_syntax ); if ( !required ) return( -1 ); Debug( LDAP_DEBUG_ANY, "name2attr (%s) failed - exiting\n", attrib, 0, 0 ); log_and_exit( 1 ); } void get_syntaxes() { oid_table_attr *name2attr(); Debug( LDAP_DEBUG_TRACE, "get_syntaxes\n", 0, 0, 0 ); ldap_photo_syntax = get_one_syntax( "photo", 0 ); ldap_jpeg_syntax = get_one_syntax( "jpegPhoto", 0 ); ldap_jpeg_nonfile_syntax = str2syntax( "jpeg" ); ldap_audio_syntax = get_one_syntax( "audio", 0 ); ldap_postaladdress_syntax = get_one_syntax( "postaladdress", 0 ); ldap_dn_syntax = get_one_syntax( "aliasedObjectName", 1 ); ldap_acl_syntax = get_one_syntax( "acl", 0 ); ldap_mtai_syntax = get_one_syntax( "mTAInfo", 0 ); ldap_rts_cred_syntax= get_one_syntax( "initiatingRTSCredentials", 0 ); ldap_rtl_syntax= get_one_syntax( "routingTreeList", 0 ); ldap_mailbox_syntax = get_one_syntax( "otherMailbox", 0 ); ldap_caseignorelist_syntax = str2syntax( "CaseIgnoreList" ); ldap_caseexactstring_syntax = str2syntax( "caseexactstring" ); ldap_octetstring_syntax = str2syntax( "OctetString" ); ldap_deliverymethod_syntax = str2syntax( "DeliveryMethod" ); ldap_iattr_syntax = get_one_syntax( "inheritedAttribute", 0 ); ldap_certif_syntax = get_one_syntax( "userCertificate", 0 ); ldap_telex_syntax = get_one_syntax( "telexNumber", 0 ); ldap_facsimileTelephoneNumber_syntax = get_one_syntax( "facsimileTelephoneNumber", 0 ); ldap_presentationAddress_syntax = get_one_syntax( "presentationAddress", 0 ); ldap_teletexTerminalIdentifier_syntax = get_one_syntax( "teletexTerminalIdentifier", 0 ); ldap_searchGuide_syntax = get_one_syntax( "searchGuide", 0 ); ldap_dLSubmitPermission_syntax = get_one_syntax( "mhsDLSubmitPermissions", 0 ); certif_init(); /* initialize certificate syntax handler */ } /* * From RFC 1779 "A String Representation of Distinguished Names" * * Key Attribute (X.520 keys) * ------------------------------ * CN CommonName * L LocalityName * ST StateOrProvinceName * O OrganizationName * OU OrganizationalUnitName * C CountryName * STREET StreetAddress * * * Table 1: Standardised Keywords * * There is an escape mechanism from the normal user oriented form, so * that this syntax may be used to print any valid distinguished name. * * 1. Attributes types are represented in a (big-endian) dotted * notation. (e.g., OID.2.6.53). * */ static void attr_key_rfc1779 ( AttributeType at, char *key /* return key, caller allocated */ ) { char *x; x = attr2name_aux ( at ); if ( x == NULL ) { x = "?"; } else if ( isdigit ( *x ) ) { sprintf ( key, "OID.%s", x ); return; } else if (strcasecmp(x,"commonName")==0) { x = "CN"; } else if (strcasecmp(x,"localityName")==0) { x = "l"; } else if (strcasecmp(x,"stateOrProvinceName")==0) { x = "st"; } else if (strcasecmp(x,"organizationName")==0) { x = "o"; } else if (strcasecmp(x,"organizationalUnitName")==0) { x = "ou"; } else if (strcasecmp(x,"countryName")==0) { x = "c"; } else if (strcasecmp(x,"streetAddress")==0) { x = "street"; } strcpy ( key, x ); } #define SEPARATOR(c) (c == ',' || c == ';') #define SPACE(c) (c == ' ' || c == '\n') int dn_print_real( PS ps, DN dn, int format ) { RDN rdn; int firstrdn; char *value; PS rps; void ldap_dn_print(); char key[512]; if ( dn == NULLDN ) return( 0 ); if ( dn->dn_parent != NULLDN ) { dn_print_real( ps, dn->dn_parent, format ); ps_print( ps, ", " ); } if ( (rps = ps_alloc( str_open )) == NULLPS ) return( -1 ); if ( str_setup( rps, NULLCP, 0, 0 ) == NOTOK ) return( -1 ); firstrdn = 1; for ( rdn = dn->dn_rdn; rdn != NULLRDN; rdn = rdn->rdn_next ) { if ( firstrdn ) firstrdn = 0; else ps_print( ps, " + " ); attr_key_rfc1779 ( rdn->rdn_at, key ); ps_print ( ps, key ); ps_print( ps, "=" ); if ( rdn->rdn_at->oa_syntax == ldap_dn_syntax ) { dn_print_real( rps, (DN) rdn->rdn_av.av_struct, format ); *rps->ps_ptr = '\0'; value = rps->ps_base; } else { AttrV_print( rps, &rdn->rdn_av, EDBOUT ); *rps->ps_ptr = '\0'; if ( rps->ps_ptr - rps->ps_base >= 5 && strncmp( rps->ps_base, "{ASN}", 5 ) == 0 ) { *rps->ps_base = '#'; SAFEMEMCPY( rps->ps_base + 1, rps->ps_base + 5, rps->ps_ptr - rps->ps_base - 4 ); } value = rps->ps_base; de_t61( value, 0 ); } /* * ,+="\\\n all go in quotes. " and \\ need to * be preceeded by \\. */ if ( strpbrk( value, ",+=\"\\\n" ) != NULL || SPACE( value[0] ) || SPACE( value[max( strlen(value) - 1, (size_t) 0 )] ) ) { char *p, *t, *tmp; int specialcount; ps_print( ps, "\"" ); specialcount = 0; for ( p = value; *p != '\0'; p++ ) { if ( *p == '"' || *p == '\\' ) { specialcount++; } } if ( specialcount > 0 ) { tmp = smalloc( strlen( value ) + specialcount + 1 ); for ( p = value, t = tmp; *p != '\0'; p++ ) { switch ( *p ) { case '"': case '\\': *t++ = '\\'; /* FALL THROUGH */ default: *t++ = *p; } } *t = '\0'; ps_print( ps, tmp ); free( tmp ); } else { ps_print( ps, value ); } ps_print( ps, "\"" ); } else { ps_print( ps, value ); } rps->ps_ptr = rps->ps_base; } ps_free( rps ); return( 0 ); } void ldap_dn_print( PS ps, DN dn, DN base, /* if non-NULL, subsitute '*' for base (for CLDAP) */ int format ) { DN tmpdn; int addstar; Debug( LDAP_DEBUG_TRACE, "ldap_dn_print\n", 0, 0, 0 ); addstar = 0; if ( base != NULLDN && dn != NULL ) { for ( tmpdn = dn; base != NULLDN && tmpdn != NULLDN; base = base->dn_parent, tmpdn = tmpdn->dn_parent ) { if ( dn_comp_cmp( base, tmpdn ) == NOTOK ) { break; } } if (( addstar = ( base == NULLDN && tmpdn != NULL ))) { dn = tmpdn; } } dn_print_real( ps, dn, format ); if ( addstar ) { ps_print( ps, ", *" ); } } int encode_dn( BerElement *ber, DN dn, DN base /* if non-NULL, subsitute '*' for base (for CLDAP) */ ) { PS ps; int rc; Debug( LDAP_DEBUG_TRACE, "encode_dn\n", 0, 0, 0 ); if ( (ps = ps_alloc( str_open )) == NULLPS ) return( -1 ); if ( str_setup( ps, NULLCP, 0, 0 ) == NOTOK ) return( -1 ); ldap_dn_print( ps, dn, base, EDBOUT ); *ps->ps_ptr = '\0'; rc = ber_printf( ber, "s", ps->ps_base ); ps_free( ps ); return( rc ); } static put_jpeg_value( BerElement *ber, AttributeValue av ) { PE pe; int len; Debug( LDAP_DEBUG_TRACE, "put_jpeg_value\n", 0, 0, 0 ); if (av->av_syntax == AV_FILE) pe = (PE) (((struct file_syntax *) av->av_struct)-> fs_attr->av_struct); else pe = (PE) av->av_struct; Debug( LDAP_DEBUG_ARGS, "put_jpeg_value: pe_class %x, pe_form %x, pe_id %x\n", pe->pe_class, pe->pe_form, pe->pe_id ); if ( (pe->pe_class != PE_CLASS_UNIV && pe->pe_class != PE_CLASS_CONT) || pe->pe_form != PE_FORM_PRIM || pe->pe_id != PE_PRIM_OCTS ) { Debug( LDAP_DEBUG_ANY, "put_jpeg_value: unknown type\n", 0, 0, 0 ); return( -1 ); } if ( pe_pullup( pe ) == NOTOK ) { Debug( LDAP_DEBUG_ANY, "put_jpeg_value: cannot pullup\n", 0, 0, 0 ); return( -1 ); } len = ps_get_abs( pe ); Debug( LDAP_DEBUG_ARGS, "put_jeg_value: ber_printf %d bytes\n", len, 0, 0 ); if ( ber_printf( ber, "o", (char *) pe->pe_prim, len ) == -1 ) { Debug( LDAP_DEBUG_ANY, "put_jpeg_value: ber_printf failed\n", 0, 0, 0 ); return( -1 ); } return( 0 ); } static put_audio_value( BerElement *ber, AttributeValue av ) { struct qbuf *qb, *p; int rc, len; char *buf; Debug( LDAP_DEBUG_TRACE, "put_audio_value\n", 0, 0, 0 ); qb = (struct qbuf *) (((struct file_syntax *) av->av_struct)->fs_attr->av_struct); len = 0; for ( p = qb->qb_forw; p != qb; p = p->qb_forw ) { len += p->qb_len; } if ( (buf = (char *) malloc( len )) == NULL ) return( -1 ); len = 0; for ( p = qb->qb_forw; p != qb; p = p->qb_forw ) { SAFEMEMCPY( buf + len, p->qb_data, p->qb_len ); len += p->qb_len; } Debug( LDAP_DEBUG_ARGS, "put_audio_value: ber_printf %d bytes\n", len, 0, 0 ); if ( (rc = ber_printf( ber, "o", buf, len )) == -1 ) Debug( LDAP_DEBUG_ANY, "put_audio_value: ber_printf failed\n", 0, 0, 0 ); free( buf ); return( rc ); } static put_photo_value( BerElement *ber, AttributeValue av ) { PE pe; PS ps; int len; char *faxparamset = "\000\300\000\000"; BerElement *phber; Debug( LDAP_DEBUG_TRACE, "put_photo_value\n", 0, 0, 0 ); pe = (PE) (((struct file_syntax *) av->av_struct)->fs_attr->av_struct); /* old bit string-like format - only handle this for now */ if ( pe->pe_class == PE_CLASS_UNIV && pe->pe_form == PE_FORM_PRIM && pe->pe_id == PE_PRIM_BITS ) { len = ps_get_abs( pe ); Debug( LDAP_DEBUG_ARGS, "put_photo_val: ber_printf %d bytes\n", len, 0, 0 ); if (( phber = der_alloc()) == NULLBER ) { Debug( LDAP_DEBUG_ANY, "der_alloc failed\n", 0, 0, 0 ); return( -1 ); } if ( ber_printf( phber, "t{[tB]{B}}", 0xA3, 0x81, faxparamset, 31, (char *)pe->pe_prim, len * 8 ) == -1 ) { Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); ber_free( phber, 1 ); return( -1 ); } if ( ber_printf( ber, "o", phber->ber_buf, phber->ber_ptr - phber->ber_buf ) == -1 ) { Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); ber_free( phber, 1 ); return( -1 ); } ber_free( phber, 1 ); } else { /* * try just writing this into a PS and sending it along */ ps_len_strategy = PS_LEN_LONG; if ( (ps = ps_alloc( str_open )) == NULLPS ) return( -1 ); if ( str_setup( ps, NULLCP, 0, 0 ) == NOTOK || pe2ps( ps, pe ) == NOTOK ) { ps_free( ps ); return( -1 ); } len = ps->ps_ptr - ps->ps_base; Debug( LDAP_DEBUG_ARGS, "put_photo_val: ber_printf %d bytes\n", len, 0, 0 ); if ( ber_printf( ber, "o", (char *) ps->ps_base, len ) == -1 ) { Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); ps_free( ps ); return( -1 ); } ps_free( ps ); } return( 0 ); } static put_values( BerElement *ber, PS ps, short syntax, AV_Sequence vals ) { AV_Sequence av; char *strvalue; Debug( LDAP_DEBUG_TRACE, "put_values\n", 0, 0, 0 ); for ( av = vals; av != NULLAV; av = av->avseq_next ) { if ( syntax == ldap_jpeg_syntax || syntax == ldap_jpeg_nonfile_syntax ) { if ( put_jpeg_value( ber, &av->avseq_av ) == -1 ) return( -1 ); } else if ( syntax == ldap_photo_syntax ) { if ( put_photo_value( ber, &av->avseq_av ) == -1 ) return( -1 ); } else if ( syntax == ldap_audio_syntax ) { if ( put_audio_value( ber, &av->avseq_av ) == -1 ) return( -1 ); } else if ( syntax == ldap_dn_syntax ) { if ( encode_dn( ber, (DN) av->avseq_av.av_struct, NULLDN ) == -1 ) return( -1 ); } else if ( syntax > AV_WRITE_FILE ) { struct file_syntax *fsyntax; fsyntax = (struct file_syntax *) av->avseq_av.av_struct; ps->ps_ptr = ps->ps_base; AttrV_print( ps, fsyntax->fs_attr, EDBOUT ); *ps->ps_ptr = '\0'; if ( ber_printf( ber, "o", ps->ps_base, ps->ps_ptr - ps->ps_base ) == -1 ) return( -1 ); } else { ps->ps_ptr = ps->ps_base; AttrV_print( ps, &av->avseq_av, EDBOUT ); *ps->ps_ptr = '\0'; de_t61( ps->ps_base, 0 ); if ( syntax_is_string( av->avseq_av.av_syntax ) && *ps->ps_base == '\0' ) { /* * If this is a zero-length string, make it * a single blank (this is gross, but it works * around a dsap library bug). */ Debug( LDAP_DEBUG_ANY, "put_values: replaced zero-length string with single blank\n", 0, 0, 0 ); strvalue = " "; } else { strvalue = ps->ps_base; } if ( ber_printf( ber, "s", strvalue ) == -1 ) return( -1 ); } } return( 0 ); } int encode_attrs( BerElement *ber, Attr_Sequence as ) { PS ps; #ifdef COMPAT20 extern int ldap_compat; #endif Debug( LDAP_DEBUG_TRACE, "encode_attrs\n", 0, 0, 0 ); if ( (ps = ps_alloc( str_open )) == NULLPS ) return( -1 ); if ( str_setup( ps, NULLCP, 0, 0 ) == NOTOK ) return( -1 ); #ifdef COMPAT20 if ( ber_printf( ber, "t{", ldap_compat == 20 ? OLD_LBER_SEQUENCE : LBER_SEQUENCE ) == -1 ) { #else if ( ber_printf( ber, "{" ) == -1 ) { #endif ps_free( ps ); return( -1 ); } while ( as != NULLATTR ) { ps->ps_ptr = ps->ps_base; AttrT_print( ps, as->attr_type, EDBOUT ); *ps->ps_ptr = '\0'; #ifdef COMPAT20 if ( ber_printf( ber, "t{st[", ldap_compat == 20 ? OLD_LBER_SEQUENCE : LBER_SEQUENCE, ps->ps_base, ldap_compat == 20 ? OLD_LBER_SET : LBER_SET ) == -1 ) { #else if ( ber_printf( ber, "{s[", ps->ps_base ) == -1 ) { #endif ps_free( ps ); return( -1 ); } put_values( ber, ps, as->attr_type->oa_syntax, as->attr_value ); if ( ber_printf( ber, "]}" ) == -1 ) { ps_free( ps ); return( -1 ); } as = as->attr_link; } ps_free( ps ); if ( ber_printf( ber, "}" ) == -1 ) return( -1 ); return( 0 ); } static void trim_trailing_spaces( char *s ) { char *t; t = s + strlen( s ); while ( --t > s ) { if ( SPACE( *t ) ) { *t = '\0'; } else { break; } } } DN ldap_str2dn( char *str ) { DN dn, save; RDN rdn, newrdn, tmprdn; AttributeType at; AttributeValue av; char *type, *value, *savestr; int morerdncomps; Debug( LDAP_DEBUG_TRACE, "ldap_str2dn\n", 0, 0, 0 ); savestr = str = strdup( str ); dn = NULLDN; do { char *r; int state; rdn = NULLRDN; morerdncomps = 1; do { /* get the type */ while ( *str == ' ' || *str == '\n' ) str++; type = str; while ( *str != '\0' && *str != '=' ) str++; if ( *str == '\0' ) { free( savestr ); Debug( LDAP_DEBUG_ARGS, "no =\n", 0, 0, 0 ); return( NULLDN ); } *str++ = '\0'; if ( strncmp( type, "OID.", 4 ) == 0 ) type += 4; #define BEGINVALUE 1 #define INVALUE 2 #define INQUOTE 3 #define ENDVALUE 4 if ( *str == '#' ) { ++str; } r = value = str; state = BEGINVALUE; /* break or return out */ while ( state != ENDVALUE ) { switch ( *str ) { case '"': if ( state == BEGINVALUE ) { state = INQUOTE; str++; } else if ( state == INQUOTE ) { state = ENDVALUE; str++; } else { free( savestr ); Debug( LDAP_DEBUG_ARGS, "quote state %d\n", state, 0, 0 ); return( NULLDN ); } break; case ',': case ';': case '+': if ( state == INVALUE ) { state = ENDVALUE; } else if ( state == INQUOTE ) { *r++ = *str++; } else { free( savestr ); Debug( LDAP_DEBUG_ARGS, "comma state %d\n", state, 0, 0 ); return( NULLDN ); } break; case ' ': case '\n': if ( state == BEGINVALUE ) { str++; } else { *r++ = *str++; } break; case '\\': str++; *r++ = *str++; break; case '\0': state = ENDVALUE; break; default: if ( state == BEGINVALUE ) state = INVALUE; *r++ = *str++; break; } } while ( SPACE( *str ) ) str++; if ( *str == '+' ) { morerdncomps = 1; str++; } else { morerdncomps = 0; if ( SEPARATOR( *str ) ) str++; } *r = '\0'; /* type */ trim_trailing_spaces( type ); if ( (at = str2AttrT( type )) == NULLAttrT ) { dn_free( dn ); free( savestr ); Debug( LDAP_DEBUG_ARGS, "bad type (%s)\n", type, 0, 0 ); return( NULLDN ); /* LDAP_UNDEFINED_TYPE */ } /* value */ if ( (av = ldap_str2AttrV( value, at->oa_syntax )) == NULLAttrV ) { dn_free( dn ); free( savestr ); Debug( LDAP_DEBUG_ARGS, "bad val\n", 0, 0, 0 ); return( NULLDN ); /* LDAP_INVALID_SYNTAX */ } /* make the rdn */ newrdn = rdn_comp_new( at, av ); /* add it to the list */ for ( tmprdn = rdn; tmprdn != NULLRDN && tmprdn->rdn_next != NULLRDN; tmprdn = tmprdn->rdn_next ) ; /* NULL */ if ( tmprdn != NULLRDN ) tmprdn->rdn_next = newrdn; else rdn = newrdn; AttrV_free( av ); } while ( morerdncomps ); save = dn; dn = dn_comp_new( rdn ); dn->dn_parent = save; } while ( str != NULL && *str != '\0' ); free( savestr ); Debug( LDAP_DEBUG_TRACE, "ldap_str2dn OK\n", 0, 0, 0 ); return( dn ); } #define T61 "{T.61}" #define T61LEN 6 static void de_t61( char *s, int t61mark ) { char *next = s; int c, hex; while ( *s ) { switch ( *s ) { case '{' : if ( strncasecmp( s, T61, T61LEN) == 0 ) { s += T61LEN; if ( t61mark ) *next++ = '@'; } else { *next++ = *s++; } break; case '\\': c = *(s + 1); if ( c == '\n' ) { s += 2; if ( *s == '\t' ) s++; break; } if ( c == '\\' ) { /* reverse solidus character itself */ s += 2; *next++ = c; break; } if ( isdigit( c ) ) hex = c - '0'; else if ( c >= 'A' && c <= 'F' ) hex = c - 'A' + 10; else if ( c >= 'a' && c <= 'f' ) hex = c - 'a' + 10; else { *next++ = *s++; break; } hex <<= 4; c = *(s + 2); if ( isdigit( c ) ) hex += c - '0'; else if ( c >= 'A' && c <= 'F' ) hex += c - 'A' + 10; else if ( c >= 'a' && c <= 'f' ) hex += c - 'a' + 10; else { *next++ = *s++; *next++ = *s++; break; } *next++ = hex; s += 3; break; default: *next++ = *s++; break; } } *next = '\0'; } static PE bv_asn2pe( struct berval *bv ) { PS ps; PE pe; if (( ps = ps_alloc(str_open)) == NULLPS || str_setup( ps, bv->bv_val, bv->bv_len, 0 ) == NOTOK ) { Debug( LDAP_DEBUG_TRACE, "bv_asn2pe: ps_alloc failed\n", 0, 0, 0 ); return( NULLPE ); } pe = ps2pe( ps ); if ( ps->ps_errno != PS_ERR_NONE ) { Debug( LDAP_DEBUG_TRACE, "bv_asn2pe: ps2pe failed %s\n", ps_error(ps->ps_errno), 0, 0 ); if ( pe != NULLPE ) { pe_free( pe ); } return( NULLPE ); } return( pe ); } AttributeValue bv_octet2AttrV( struct berval *bv ) { AttributeValue av; av = AttrV_alloc(); if ( av == NULLAttrV ) { return( NULLAttrV ); } if (( av->av_struct = (caddr_t) str2prim( bv->bv_val, bv->bv_len, PE_CLASS_UNIV, PE_PRIM_OCTS )) == NULL ) { free((char *)av ); return( NULLAttrV ); } av->av_syntax = 0; return( av ); } AttributeValue bv_asn2AttrV( struct berval *bv ) { AttributeValue av; av = AttrV_alloc(); if ( av == NULLAttrV ) { return( NULLAttrV ); } if (( av->av_struct = (caddr_t) bv_asn2pe( bv )) == NULL ) { free((char *)av ); return( NULLAttrV ); } av->av_syntax = 0; return( av ); } AttributeValue ldap_strdn2AttrV( char *dnstr ) { DN dn; AttributeValue av; if (( dn = ldap_str2dn( dnstr )) == NULL ) { return( NULLAttrV ); } av = AttrV_alloc(); if ( av == NULLAttrV ) { dn_free( dn ); return( NULLAttrV ); } av->av_struct = (caddr_t)dn; av->av_syntax = ldap_dn_syntax; return( av ); } RDN ldap_str2rdn( char *rdnstr ) { DN dn; RDN rdn; if ( (dn = ldap_str2dn( rdnstr )) == NULL ) { return( NULL ); } if ( (rdn = rdn_cpy( dn->dn_rdn )) == NULL ) { return( NULL ); } dn_free( dn ); return( rdn ); } AttributeValue ldap_str_at2AttrV( char *str, AttributeType type ) { char *s, *res, *r; AttributeValue str_at2AttrV(); Debug( LDAP_DEBUG_TRACE, "ldap_str_at2AttrV str (%s) type (%s)\n", str, type->oa_ot.ot_name, 0 ); if ( type->oa_syntax == ldap_rts_cred_syntax || type->oa_syntax == ldap_mtai_syntax || type->oa_syntax == ldap_acl_syntax || type->oa_syntax == ldap_mailbox_syntax || type->oa_syntax == ldap_caseignorelist_syntax || type->oa_syntax == ldap_certif_syntax || type->oa_syntax == ldap_iattr_syntax || type->oa_syntax == ldap_telex_syntax || type->oa_syntax == ldap_deliverymethod_syntax || type->oa_syntax == ldap_facsimileTelephoneNumber_syntax || type->oa_syntax == ldap_presentationAddress_syntax || type->oa_syntax == ldap_teletexTerminalIdentifier_syntax || type->oa_syntax == ldap_searchGuide_syntax || type->oa_syntax == ldap_dLSubmitPermission_syntax || type->oa_syntax == ldap_rtl_syntax ) { res = str; } else { res = (char *) malloc( max( 2 * strlen( str ), (size_t) 10 ) ); r = res; for ( s = str; *s; s++ ) { switch ( *s ) { case '&': case '#': case '$': case '%': case '@': case '\\': sprintf( r, "\\%02x", *s & 0xff ); r += 3; break; default: *r++ = *s; } } *r = '\0'; } Debug( LDAP_DEBUG_TRACE, "ldap_str_at2AttrV returning (%s)\n", res, 0, 0 ); return( str_at2AttrV( res, type ) ); } AttributeValue ldap_str2AttrV( char *value, short syntax ) { if ( syntax == ldap_dn_syntax ) { return( ldap_strdn2AttrV( value ) ); } else { return( str2AttrV( value, syntax ) ); } } static int syntax_is_string( short syntax ) { /* * this code depends on the order and nunber of strings that are in * the ISODE file lib/syntax/x500/string.c */ return ( syntax >= ldap_caseexactstring_syntax && syntax <= ldap_caseexactstring_syntax + 8 ); }