1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/** BEGIN COPYRIGHT BLOCK
* Copyright 2001 Sun Microsystems, Inc.
* Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/* ava.c - routines for dealing with attribute value assertions */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#endif
#include "slap.h"
static void strcpy_special_undo();
int
get_ava(
BerElement *ber,
struct ava *ava
)
{
char *type;
if ( ber_scanf( ber, "{ao}", &type, &ava->ava_value )
== LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY, " get_ava ber_scanf\n", 0, 0, 0 );
return( LDAP_PROTOCOL_ERROR );
}
ava->ava_type = slapi_attr_syntax_normalize(type);
free( type );
return( 0 );
}
void
ava_done(
struct ava *ava
)
{
slapi_ch_free( (void**)&(ava->ava_type) );
slapi_ch_free( (void**)&(ava->ava_value.bv_val) );
}
int
rdn2ava(
char *rdn,
struct ava *ava
)
{
char *s;
if ( (s = strchr( rdn, '=' )) == NULL ) {
return( -1 );
}
*s++ = '\0';
ava->ava_type = rdn;
strcpy_special_undo( s, s );
ava->ava_value.bv_val = s;
ava->ava_value.bv_len = strlen( s );
return( 0 );
}
/*
** This function takes a quoted attribute value of the form "abc",
** and strips off the enclosing quotes. It also deals with quoted
** characters by removing the preceeding '\' character.
**
*/
static void
strcpy_special_undo( char *d, const char *s )
{
const char *end = s + strlen(s);
for ( ; *s; s++ )
{
switch ( *s )
{
case '"':
break;
case '\\':
{
/*
* The '\' could be escaping a single character, ie \"
* or could be escaping a hex byte, ie \01
*/
int singlecharacter= 1;
if ( s+2 < end )
{
int n = hexchar2int( s[1] );
if ( n >= 0 )
{
int n2 = hexchar2int( s[2] );
if ( n2 >= 0 )
{
singlecharacter= 0;
n = (n << 4) + n2;
if (n == 0)
{
/* don't change \00 */
*d++ = *++s;
*d++ = *++s;
}
else
{
/* change \xx to a single char */
++s;
*(unsigned char*)(s+1) = n;
}
}
}
}
if(singlecharacter)
{
s++;
*d++ = *s;
}
break;
}
default:
*d++ = *s;
break;
}
}
*d = '\0';
}
|