1
/** BEGIN COPYRIGHT BLOCK
2
* This Program is free software; you can redistribute it and/or modify it under
3
* the terms of the GNU General Public License as published by the Free Software
4
* Foundation; version 2 of the License.
6
* This Program is distributed in the hope that it will be useful, but WITHOUT
7
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10
* You should have received a copy of the GNU General Public License along with
11
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
12
* Place, Suite 330, Boston, MA 02111-1307 USA.
14
* In addition, as a special exception, Red Hat, Inc. gives You the additional
15
* right to link the code of this Program with code not covered under the GNU
16
* General Public License ("Non-GPL Code") and to distribute linked combinations
17
* including the two, subject to the limitations in this paragraph. Non-GPL Code
18
* permitted under this exception must only link to the code of this Program
19
* through those well defined interfaces identified in the file named EXCEPTION
20
* found in the source code files (the "Approved Interfaces"). The files of
21
* Non-GPL Code may instantiate templates or use macros or inline functions from
22
* the Approved Interfaces without causing the resulting work to be covered by
23
* the GNU General Public License. Only Red Hat, Inc. may make changes or
24
* additions to the list of Approved Interfaces. You must obey the GNU General
25
* Public License in all respects for all of the Program code and other code used
26
* in conjunction with the Program except the Non-GPL Code covered by this
27
* exception. If you modify this file, you may extend this exception to your
28
* version of the file, but you are not obligated to do so. If you do not wish to
29
* provide this exception without modification, you must delete this exception
30
* statement from your version and license this file solely under the GPL without
34
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
35
* Copyright (C) 2005 Red Hat, Inc.
36
* All rights reserved.
37
* END COPYRIGHT BLOCK **/
43
/* bin.c - bin syntax routines */
46
* This file actually implements four syntax plugins: OctetString, JPEG,
52
#include <sys/types.h>
55
#define CERTIFICATE_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.8"
56
#define CERTIFICATELIST_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.9"
57
#define CERTIFICATEPAIR_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.10"
58
#define SUPPORTEDALGORITHM_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.49"
60
static int bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
61
Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
62
static int bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
63
Slapi_Value ***ivals, int ftype );
64
static int bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
65
Slapi_Value ***ivals, int ftype );
66
static int bin_compare(struct berval *v1, struct berval *v2);
69
* Attribute syntaxes. We treat all of these the same since the
70
* LDAP-specific encoding for all of them are simply strings of octets
71
* with no real content restrictions (even though the content is supposed
72
* to represent something specific). For this reason, we do no
73
* validation of the values for these syntaxes.
75
static char *bin_names[] = { "Binary", "bin", BINARY_SYNTAX_OID, 0 };
77
static char *octetstring_names[] = { "OctetString", OCTETSTRING_SYNTAX_OID, 0 };
79
static char *jpeg_names[] = { "JPEG", JPEG_SYNTAX_OID, 0 };
81
static char *fax_names[] = { "FAX", FAX_SYNTAX_OID, 0 };
84
/* This syntax has "gone away" in RFC 4517, however we still use it for
85
* a number of attributes in our default schema. We should try to eliminate
86
* it's use and remove support for it. */
87
static Slapi_PluginDesc bin_pdesc = {
88
"bin-syntax", VENDOR, DS_PACKAGE_VERSION,
89
"binary attribute syntax plugin"
92
static Slapi_PluginDesc octetstring_pdesc = {
93
"octetstring-syntax", VENDOR, DS_PACKAGE_VERSION,
94
"octet string attribute syntax plugin"
97
static Slapi_PluginDesc jpeg_pdesc = {
98
"jpeg-syntax", VENDOR, DS_PACKAGE_VERSION,
99
"JPEG attribute syntax plugin"
102
static Slapi_PluginDesc fax_pdesc = {
103
"fax-syntax", VENDOR, DS_PACKAGE_VERSION,
104
"Fax attribute syntax plugin"
107
static const char *octetStringMatch_names[] = {"octetStringMatch", "2.5.13.17", NULL};
108
static const char *octetStringOrderingMatch_names[] = {"octetStringOrderingMatch", "2.5.13.18", NULL};
110
static char *octetStringCompat_syntaxes[] = {BINARY_SYNTAX_OID, JPEG_SYNTAX_OID, FAX_SYNTAX_OID, CERTIFICATE_SYNTAX_OID, CERTIFICATELIST_SYNTAX_OID, CERTIFICATEPAIR_SYNTAX_OID, SUPPORTEDALGORITHM_SYNTAX_OID, NULL};
112
static struct mr_plugin_def mr_plugin_table[] = {
113
{{"2.5.13.17", NULL, "octetStringMatch", "The octetStringMatch rule compares an assertion value of the Octet "
114
"String syntax to an attribute value of a syntax (e.g., the Octet "
115
"String or JPEG syntax) whose corresponding ASN.1 type is the OCTET "
116
"STRING ASN.1 type. "
117
"The rule evaluates to TRUE if and only if the attribute value and the "
118
"assertion value are the same length and corresponding octets (by "
119
"position) are the same.", OCTETSTRING_SYNTAX_OID, 0, octetStringCompat_syntaxes}, /* matching rule desc */
120
{"octetStringMatch-mr", VENDOR, DS_PACKAGE_VERSION, "octetStringMatch matching rule plugin"}, /* plugin desc */
121
octetStringMatch_names, /* matching rule name/oid/aliases */
122
NULL, NULL, bin_filter_ava, NULL, bin_values2keys,
123
bin_assertion2keys_ava, NULL, bin_compare},
124
{{"2.5.13.18", NULL, "octetStringOrderingMatch", "The octetStringOrderingMatch rule compares an assertion value of the "
125
"Octet String syntax to an attribute value of a syntax (e.g., the "
126
"Octet String or JPEG syntax) whose corresponding ASN.1 type is the "
127
"OCTET STRING ASN.1 type. "
128
"The rule evaluates to TRUE if and only if the attribute value appears "
129
"earlier in the collation order than the assertion value. The rule "
130
"compares octet strings from the first octet to the last octet, and "
131
"from the most significant bit to the least significant bit within the "
132
"octet. The first occurrence of a different bit determines the "
133
"ordering of the strings. A zero bit precedes a one bit. If the "
134
"strings contain different numbers of octets but the longer string is "
135
"identical to the shorter string up to the length of the shorter "
136
"string, then the shorter string precedes the longer string.",
137
OCTETSTRING_SYNTAX_OID, 0, octetStringCompat_syntaxes}, /* matching rule desc */
138
{"octetStringOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "octetStringOrderingMatch matching rule plugin"}, /* plugin desc */
139
octetStringOrderingMatch_names, /* matching rule name/oid/aliases */
140
NULL, NULL, bin_filter_ava, NULL, bin_values2keys,
141
bin_assertion2keys_ava, NULL, bin_compare}
144
certificateExactMatch
145
certificateListExactMatch
146
certificatePairExactMatch
147
algorithmIdentifierMatch
153
static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
156
matching_rule_plugin_init(Slapi_PBlock *pb)
158
return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
162
register_matching_rule_plugins()
164
return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
168
* register_bin_like_plugin(): register all items for a bin-like plugin.
171
register_bin_like_plugin( Slapi_PBlock *pb, Slapi_PluginDesc *pdescp,
172
char **names, char *oid )
176
rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
177
(void *) SLAPI_PLUGIN_VERSION_01 );
178
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
180
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
181
(void *) bin_filter_ava );
182
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
183
(void *) bin_values2keys );
184
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
185
(void *) bin_assertion2keys_ava );
186
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
188
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
196
bin_init( Slapi_PBlock *pb )
200
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> bin_init\n", 0, 0, 0 );
201
rc = register_bin_like_plugin( pb, &bin_pdesc, bin_names,
203
rc |= register_matching_rule_plugins();
204
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= bin_init %d\n", rc, 0, 0 );
210
octetstring_init( Slapi_PBlock *pb )
214
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> octetstring_init\n", 0, 0, 0 );
215
rc = register_bin_like_plugin( pb, &octetstring_pdesc, octetstring_names,
216
OCTETSTRING_SYNTAX_OID );
217
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= octetstring_init %d\n", rc, 0, 0 );
223
jpeg_init( Slapi_PBlock *pb )
227
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> jpeg_init\n", 0, 0, 0 );
228
rc = register_bin_like_plugin( pb, &jpeg_pdesc, jpeg_names,
230
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= jpeg_init %d\n", rc, 0, 0 );
236
fax_init( Slapi_PBlock *pb )
240
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> fax_init\n", 0, 0, 0 );
241
rc = register_bin_like_plugin( pb, &fax_pdesc, fax_names,
243
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= fax_init %d\n", rc, 0, 0 );
249
bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
250
Slapi_Value **bvals, int ftype, Slapi_Value **retVal )
254
for ( i = 0; (bvals != NULL) && (bvals[i] != NULL); i++ ) {
255
const struct berval *bv = slapi_value_get_berval(bvals[i]);
256
int rc = slapi_berval_cmp(bv, bvfilter);
275
case LDAP_FILTER_EQUALITY:
293
bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
294
Slapi_Value ***ivals, int ftype )
306
if ( ftype != LDAP_FILTER_EQUALITY ) {
307
return( LDAP_PROTOCOL_ERROR );
310
for ( i = 0; bvals[i] != NULL; i++ ) {
313
(*ivals) = (Slapi_Value **) slapi_ch_malloc(( i + 1 ) *
314
sizeof(Slapi_Value *) );
316
for ( i = 0; bvals[i] != NULL; i++ )
318
(*ivals)[i] = slapi_value_dup(bvals[i]);
326
bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
327
Slapi_Value ***ivals, int ftype )
329
Slapi_Value *tmpval=NULL;
332
if (( ftype != LDAP_FILTER_EQUALITY ) &&
333
( ftype != LDAP_FILTER_EQUALITY_FAST))
335
return( LDAP_PROTOCOL_ERROR );
337
if(ftype == LDAP_FILTER_EQUALITY_FAST) {
338
/* With the fast option, we are trying to avoid creating and freeing
339
* a bunch of structures - we just do one malloc here - see
340
* ava_candidates in filterentry.c
342
len=slapi_value_get_length(bval);
344
if (len > tmpval->bv.bv_len) {
345
tmpval->bv.bv_val=(char *)slapi_ch_malloc(len);
347
tmpval->bv.bv_len=len;
348
memcpy(tmpval->bv.bv_val,slapi_value_get_string(bval),len);
350
(*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
351
(*ivals)[0] = slapi_value_dup( bval );
357
#define BV_EMPTY(bv) ((!bv || !bv->bv_len || !bv->bv_val))
367
if (BV_EMPTY(v1) && BV_EMPTY(v2)) {
368
rc = 0; /* empty == empty */
369
} else if (BV_EMPTY(v1) && !BV_EMPTY(v2)) {
370
rc = 1; /* something in v2 always greater than empty v1 */
371
} else if (!BV_EMPTY(v1) && BV_EMPTY(v2)) {
372
rc = -1; /* something in v1 always greater than empty v2 */
373
} else { /* both have actual data */
374
rc = slapi_berval_cmp(v1, v2);