2 * Copyright (c) 1995 Regents of the University of Michigan.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of Michigan at Ann Arbor. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
18 #include <ac/string.h>
20 #include <quipu/commonarg.h>
21 #include <quipu/attrvalue.h>
22 #include <quipu/ds_error.h>
23 #include <quipu/ds_search.h>
24 /* #include <quipu/dap2.h> */
25 #include <quipu/dua.h>
30 #include "ldapsyntax.h"
33 short ldap_password_syntax;
34 short ldap_photo_syntax;
35 short ldap_jpeg_syntax;
36 short ldap_audio_syntax;
38 static int dn2ldif( PS ps, DN dn );
39 static int jpeg2ldif( PS ps, AttributeValue av );
40 static int audio2ldif( PS ps, AttributeValue av );
41 static int photo2ldif( PS ps, AttributeValue av );
42 static int fileattr2ldif( PS ps, AttributeValue av );
43 static void de_t61( char *s, int t61mark );
44 static void de_crypt( char *s );
46 extern char *progname;
48 #define SEPARATOR(c) ((c) == ',' || (c) == ';')
49 #define SPACE(c) ((c) == ' ' || (c) == '\n')
55 if (( ldap_dn_syntax = str2syntax( "DN" )) == 0 ) {
56 return( -1 ); /* must have this syntax handler */
58 ldap_password_syntax = str2syntax( "password" );
59 ldap_photo_syntax = str2syntax( "photo" );
60 ldap_jpeg_syntax = str2syntax( "jpeg" );
61 ldap_audio_syntax = str2syntax( "audio" );
68 * av2ldif: convert attribute value contained in "av" to ldif format
69 * and write to "outfp". If "dn" is not NULL, convert it instead of "av".
72 av2ldif( FILE *outfp, AV_Sequence av, DN dn, short syntax, char *attrname,
77 struct file_syntax *fsyntax;
80 fsyntax = (struct file_syntax *) av->avseq_av.av_struct;
83 rc = 0; /* optimistic */
84 str_ps->ps_ptr = str_ps->ps_base; /* reset string PS */
86 if ( dn != NULL || syntax == ldap_dn_syntax ) { /* DNs */
87 rc = dn2ldif( str_ps, ( dn != NULLDN ) ? dn :
88 (DN)(av->avseq_av.av_struct));
90 } else if ( syntax == ldap_jpeg_syntax || ( syntax > AV_WRITE_FILE &&
91 fsyntax->fs_real_syntax == ldap_jpeg_syntax )) {
92 rc = jpeg2ldif( str_ps, &av->avseq_av );
94 } else if ( syntax == ldap_photo_syntax || ( syntax > AV_WRITE_FILE &&
95 fsyntax->fs_real_syntax == ldap_photo_syntax )) {
96 rc = photo2ldif( str_ps, &av->avseq_av );
98 } else if ( syntax == ldap_audio_syntax || ( syntax > AV_WRITE_FILE &&
99 fsyntax->fs_real_syntax == ldap_audio_syntax )) {
100 rc = audio2ldif( str_ps, &av->avseq_av );
102 } else if ( syntax > AV_WRITE_FILE ) {
103 rc = fileattr2ldif( str_ps, &av->avseq_av );
106 AttrV_print( str_ps, &av->avseq_av, EDBOUT );
107 *str_ps->ps_ptr = '\0';
108 de_t61( str_ps->ps_base, 0 );
110 if ( syntax == ldap_password_syntax ) {
111 de_crypt( str_ps->ps_base );
114 str_ps->ps_ptr = str_ps->ps_base + strlen( str_ps->ps_base );
117 if ( rc == 0 && str_ps->ps_ptr > str_ps->ps_base ) {
118 *str_ps->ps_ptr = '\0';
119 if (( buf = ldif_type_and_value( attrname, str_ps->ps_base,
120 str_ps->ps_ptr - str_ps->ps_base )) == NULL ) {
123 if ( fputs( buf, outfp ) == EOF ) {
131 if ( syntax > AV_WRITE_FILE ) {
133 "%s: attribute file '%s' not found (skipping value)\n",
134 progname, fsyntax->fs_name );
136 rc = 0; /* treat as "soft" error -- keep going */
144 dn2ldif( PS ps, DN dn )
151 if ( dn == NULLDN ) {
155 if ( dn->dn_parent != NULLDN ) {
156 if (( rc = dn2ldif( ps, dn->dn_parent )) != 0 ) {
159 ps_print( ps, ", " );
162 if ( (rps = ps_alloc( str_open )) == NULLPS ||
163 str_setup( rps, NULLCP, 0, 0 ) == NOTOK ) {
168 for ( rdn = dn->dn_rdn; rdn != NULLRDN; rdn = rdn->rdn_next ) {
172 ps_print( ps, " + " );
175 AttrT_print( ps, rdn->rdn_at, EDBOUT );
178 if ( rdn->rdn_at->oa_syntax == ldap_dn_syntax ) {
179 if (( rc = dn2ldif( rps, (DN) rdn->rdn_av.av_struct )) != 0 ) {
183 value = rps->ps_base;
185 AttrV_print( rps, &rdn->rdn_av, EDBOUT );
187 value = rps->ps_base;
192 * ,+="\\\n all go in quotes. " and \\ need to
193 * be preceeded by \\.
196 if ( strpbrk( value, ",+=\"\\\n" ) != NULL || SPACE( value[0] )
197 || SPACE( value[max( strlen(value) - 1, 0 )] ) ) {
201 ps_print( ps, "\"" );
204 for ( p = value; *p != '\0'; p++ ) {
205 if ( *p == '"' || *p == '\\' ) {
209 if ( specialcount > 0 ) {
210 tmp = smalloc( strlen( value ) + specialcount + 1 );
211 for ( p = value, t = tmp; *p != '\0'; p++ ) {
225 ps_print( ps, value );
228 ps_print( ps, "\"" );
230 ps_print( ps, value );
233 rps->ps_ptr = rps->ps_base;
256 if ( strncasecmp( s, T61, T61LEN) == 0 ) {
275 else if ( c >= 'A' && c <= 'F' )
277 else if ( c >= 'a' && c <= 'f' )
287 else if ( c >= 'A' && c <= 'F' )
289 else if ( c >= 'a' && c <= 'f' )
310 #define CRYPT_MASK 0x23
317 if ( strncmp( s, "{CRYPT}", 7 ) == 0 ) {
318 SAFEMEMCPY( s, s + 7, strlen( s + 7 ) + 1 ); /* strip off "{CRYPT}" */
320 for ( p = s; *p != '\0'; ++p) { /* "decrypt" each byte */
321 if ( *p != CRYPT_MASK ) {
330 jpeg2ldif( PS ps, AttributeValue av )
335 if (( pe = grab_pe( av )) == NULLPE || pe->pe_id == PE_PRIM_NULL ) {
336 return( -2 ); /* signal soft error */
339 if (( pe->pe_class != PE_CLASS_UNIV && pe->pe_class != PE_CLASS_CONT )
340 || pe->pe_form != PE_FORM_PRIM || pe->pe_id != PE_PRIM_OCTS ) {
344 if ( pe_pullup( pe ) == NOTOK ) {
348 len = ps_get_abs( pe );
350 if ( ps_write( ps, (PElementData)pe->pe_prim, len ) == NOTOK ) {
359 audio2ldif( PS ps, AttributeValue av )
366 return( 0 ); /* for now */
368 if (( pe = grab_pe( av )) == NULLPE || pe->pe_id == PE_PRIM_NULL ) {
369 return( -2 ); /* signal soft error */
372 qb = (struct qbuf *)pe;
375 for ( p = qb->qb_forw; p != qb; p = p->qb_forw ) {
379 if (( buf = (char *) malloc( len )) == NULL ) {
384 for ( p = qb->qb_forw; p != qb; p = p->qb_forw ) {
385 SAFEMEMCPY( buf + len, p->qb_data, p->qb_len );
389 if ( ps_write( ps, (PElementData)buf, len ) == NOTOK ) {
402 photo2ldif( PS ps, AttributeValue av )
406 char *faxparamset = "\000\300\000\000";
409 if (( pe = grab_pe( av )) == NULLPE || pe->pe_id == PE_PRIM_NULL ) {
410 return( -2 ); /* signal soft error */
413 /* old bit string-like format - only handle this for now */
414 if ( pe->pe_class == PE_CLASS_UNIV && pe->pe_form == PE_FORM_PRIM
415 && pe->pe_id == PE_PRIM_BITS ) {
416 len = ps_get_abs( pe );
417 if (( phber = der_alloc()) == NULLBER ) {
420 if ( ber_printf( phber, "t{[tB]{B}}",
421 (ber_tag_t) 0xA3, (ber_tag_t) 0x81, faxparamset, (ber_len_t) 31,
422 (char *)pe->pe_prim, (ber_len_t) (len * 8) ) == -1 )
424 ber_free( phber, 1 );
427 if ( ps_write( ps, (PElementData)phber->ber_buf,
428 phber->ber_ptr - phber->ber_buf ) == NOTOK ) {
429 ber_free( phber, 1 );
432 ber_free( phber, 1 );
435 * try just writing this into a PS and sending it along
437 if ( pe2ps( ps, pe ) == NOTOK ) {
447 fileattr2ldif( PS ps, AttributeValue av )
451 if (( pe = grab_pe( av )) == NULLPE || pe->pe_id == PE_PRIM_NULL ) {
452 return( -2 ); /* signal soft error */
456 * try just writing this into a PS and sending it along
458 if ( pe2ps( ps, pe ) == NOTOK ) {