1
0

bin.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  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.
  5. *
  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.
  9. *
  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.
  13. *
  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
  31. * exception.
  32. *
  33. *
  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 **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* bin.c - bin syntax routines */
  42. /*
  43. * This file actually implements four syntax plugins: OctetString, JPEG,
  44. * Fax, and Binary.
  45. */
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <sys/types.h>
  49. #include "syntax.h"
  50. #define CERTIFICATE_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.8"
  51. #define CERTIFICATELIST_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.9"
  52. #define CERTIFICATEPAIR_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.10"
  53. #define SUPPORTEDALGORITHM_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.49"
  54. static int bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
  55. Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
  56. static int bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
  57. Slapi_Value ***ivals, int ftype );
  58. static int bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
  59. Slapi_Value ***ivals, int ftype );
  60. static int bin_compare(struct berval *v1, struct berval *v2);
  61. /*
  62. * Attribute syntaxes. We treat all of these the same since the
  63. * LDAP-specific encoding for all of them are simply strings of octets
  64. * with no real content restrictions (even though the content is supposed
  65. * to represent something specific). For this reason, we do no
  66. * validation of the values for these syntaxes.
  67. */
  68. static char *bin_names[] = { "Binary", "bin", BINARY_SYNTAX_OID, 0 };
  69. static char *octetstring_names[] = { "OctetString", OCTETSTRING_SYNTAX_OID, 0 };
  70. static char *jpeg_names[] = { "JPEG", JPEG_SYNTAX_OID, 0 };
  71. static char *fax_names[] = { "FAX", FAX_SYNTAX_OID, 0 };
  72. /* This syntax has "gone away" in RFC 4517, however we still use it for
  73. * a number of attributes in our default schema. We should try to eliminate
  74. * it's use and remove support for it. */
  75. static Slapi_PluginDesc bin_pdesc = {
  76. "bin-syntax", VENDOR, DS_PACKAGE_VERSION,
  77. "binary attribute syntax plugin"
  78. };
  79. static Slapi_PluginDesc octetstring_pdesc = {
  80. "octetstring-syntax", VENDOR, DS_PACKAGE_VERSION,
  81. "octet string attribute syntax plugin"
  82. };
  83. static Slapi_PluginDesc jpeg_pdesc = {
  84. "jpeg-syntax", VENDOR, DS_PACKAGE_VERSION,
  85. "JPEG attribute syntax plugin"
  86. };
  87. static Slapi_PluginDesc fax_pdesc = {
  88. "fax-syntax", VENDOR, DS_PACKAGE_VERSION,
  89. "Fax attribute syntax plugin"
  90. };
  91. static const char *octetStringMatch_names[] = {"octetStringMatch", "2.5.13.17", NULL};
  92. static const char *octetStringOrderingMatch_names[] = {"octetStringOrderingMatch", "2.5.13.18", NULL};
  93. 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};
  94. static struct mr_plugin_def mr_plugin_table[] = {
  95. {{"2.5.13.17", NULL, "octetStringMatch", "The octetStringMatch rule compares an assertion value of the Octet "
  96. "String syntax to an attribute value of a syntax (e.g., the Octet "
  97. "String or JPEG syntax) whose corresponding ASN.1 type is the OCTET "
  98. "STRING ASN.1 type. "
  99. "The rule evaluates to TRUE if and only if the attribute value and the "
  100. "assertion value are the same length and corresponding octets (by "
  101. "position) are the same.", OCTETSTRING_SYNTAX_OID, 0, octetStringCompat_syntaxes}, /* matching rule desc */
  102. {"octetStringMatch-mr", VENDOR, DS_PACKAGE_VERSION, "octetStringMatch matching rule plugin"}, /* plugin desc */
  103. octetStringMatch_names, /* matching rule name/oid/aliases */
  104. NULL, NULL, bin_filter_ava, NULL, bin_values2keys,
  105. bin_assertion2keys_ava, NULL, bin_compare},
  106. {{"2.5.13.18", NULL, "octetStringOrderingMatch", "The octetStringOrderingMatch rule compares an assertion value of the "
  107. "Octet String syntax to an attribute value of a syntax (e.g., the "
  108. "Octet String or JPEG syntax) whose corresponding ASN.1 type is the "
  109. "OCTET STRING ASN.1 type. "
  110. "The rule evaluates to TRUE if and only if the attribute value appears "
  111. "earlier in the collation order than the assertion value. The rule "
  112. "compares octet strings from the first octet to the last octet, and "
  113. "from the most significant bit to the least significant bit within the "
  114. "octet. The first occurrence of a different bit determines the "
  115. "ordering of the strings. A zero bit precedes a one bit. If the "
  116. "strings contain different numbers of octets but the longer string is "
  117. "identical to the shorter string up to the length of the shorter "
  118. "string, then the shorter string precedes the longer string.",
  119. OCTETSTRING_SYNTAX_OID, 0, octetStringCompat_syntaxes}, /* matching rule desc */
  120. {"octetStringOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "octetStringOrderingMatch matching rule plugin"}, /* plugin desc */
  121. octetStringOrderingMatch_names, /* matching rule name/oid/aliases */
  122. NULL, NULL, bin_filter_ava, NULL, bin_values2keys,
  123. bin_assertion2keys_ava, NULL, bin_compare}
  124. };
  125. /*
  126. certificateExactMatch
  127. certificateListExactMatch
  128. certificatePairExactMatch
  129. algorithmIdentifierMatch
  130. certificateMatch
  131. certificatePairMatch
  132. certificateListMatch
  133. */
  134. static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
  135. static int
  136. matching_rule_plugin_init(Slapi_PBlock *pb)
  137. {
  138. return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
  139. }
  140. static int
  141. register_matching_rule_plugins()
  142. {
  143. return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
  144. }
  145. /*
  146. * register_bin_like_plugin(): register all items for a bin-like plugin.
  147. */
  148. static int
  149. register_bin_like_plugin( Slapi_PBlock *pb, Slapi_PluginDesc *pdescp,
  150. char **names, char *oid )
  151. {
  152. int rc;
  153. rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  154. (void *) SLAPI_PLUGIN_VERSION_01 );
  155. rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
  156. (void *)pdescp );
  157. rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
  158. (void *) bin_filter_ava );
  159. rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
  160. (void *) bin_values2keys );
  161. rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
  162. (void *) bin_assertion2keys_ava );
  163. rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
  164. (void *) names );
  165. rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
  166. (void *) oid );
  167. return( rc );
  168. }
  169. int
  170. bin_init( Slapi_PBlock *pb )
  171. {
  172. int rc;
  173. LDAPDebug( LDAP_DEBUG_PLUGIN, "=> bin_init\n", 0, 0, 0 );
  174. rc = register_bin_like_plugin( pb, &bin_pdesc, bin_names,
  175. BINARY_SYNTAX_OID );
  176. rc |= register_matching_rule_plugins();
  177. LDAPDebug( LDAP_DEBUG_PLUGIN, "<= bin_init %d\n", rc, 0, 0 );
  178. return( rc );
  179. }
  180. int
  181. octetstring_init( Slapi_PBlock *pb )
  182. {
  183. int rc;
  184. LDAPDebug( LDAP_DEBUG_PLUGIN, "=> octetstring_init\n", 0, 0, 0 );
  185. rc = register_bin_like_plugin( pb, &octetstring_pdesc, octetstring_names,
  186. OCTETSTRING_SYNTAX_OID );
  187. LDAPDebug( LDAP_DEBUG_PLUGIN, "<= octetstring_init %d\n", rc, 0, 0 );
  188. return( rc );
  189. }
  190. int
  191. jpeg_init( Slapi_PBlock *pb )
  192. {
  193. int rc;
  194. LDAPDebug( LDAP_DEBUG_PLUGIN, "=> jpeg_init\n", 0, 0, 0 );
  195. rc = register_bin_like_plugin( pb, &jpeg_pdesc, jpeg_names,
  196. JPEG_SYNTAX_OID );
  197. LDAPDebug( LDAP_DEBUG_PLUGIN, "<= jpeg_init %d\n", rc, 0, 0 );
  198. return( rc );
  199. }
  200. int
  201. fax_init( Slapi_PBlock *pb )
  202. {
  203. int rc;
  204. LDAPDebug( LDAP_DEBUG_PLUGIN, "=> fax_init\n", 0, 0, 0 );
  205. rc = register_bin_like_plugin( pb, &fax_pdesc, fax_names,
  206. FAX_SYNTAX_OID );
  207. LDAPDebug( LDAP_DEBUG_PLUGIN, "<= fax_init %d\n", rc, 0, 0 );
  208. return( rc );
  209. }
  210. static int
  211. bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
  212. Slapi_Value **bvals, int ftype, Slapi_Value **retVal )
  213. {
  214. int i;
  215. for ( i = 0; (bvals != NULL) && (bvals[i] != NULL); i++ ) {
  216. const struct berval *bv = slapi_value_get_berval(bvals[i]);
  217. int rc = slapi_berval_cmp(bv, bvfilter);
  218. switch ( ftype ) {
  219. case LDAP_FILTER_GE:
  220. if ( rc >= 0 ) {
  221. if(retVal) {
  222. *retVal = bvals[i];
  223. }
  224. return( 0 );
  225. }
  226. break;
  227. case LDAP_FILTER_LE:
  228. if ( rc <= 0 ) {
  229. if(retVal) {
  230. *retVal = bvals[i];
  231. }
  232. return( 0 );
  233. }
  234. break;
  235. case LDAP_FILTER_EQUALITY:
  236. if ( rc == 0 ) {
  237. if(retVal) {
  238. *retVal = bvals[i];
  239. }
  240. return( 0 );
  241. }
  242. break;
  243. }
  244. }
  245. if(retVal!=NULL)
  246. {
  247. *retVal= NULL;
  248. }
  249. return( -1 );
  250. }
  251. static int
  252. bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
  253. Slapi_Value ***ivals, int ftype )
  254. {
  255. int i;
  256. if (NULL == ivals) {
  257. return 1;
  258. }
  259. *ivals = NULL;
  260. if (NULL == bvals) {
  261. return 1;
  262. }
  263. if ( ftype != LDAP_FILTER_EQUALITY ) {
  264. return( LDAP_PROTOCOL_ERROR );
  265. }
  266. for ( i = 0; bvals[i] != NULL; i++ ) {
  267. /* NULL */
  268. }
  269. (*ivals) = (Slapi_Value **) slapi_ch_malloc(( i + 1 ) *
  270. sizeof(Slapi_Value *) );
  271. for ( i = 0; bvals[i] != NULL; i++ )
  272. {
  273. (*ivals)[i] = slapi_value_dup(bvals[i]);
  274. }
  275. (*ivals)[i] = NULL;
  276. return( 0 );
  277. }
  278. static int
  279. bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
  280. Slapi_Value ***ivals, int ftype )
  281. {
  282. Slapi_Value *tmpval=NULL;
  283. size_t len;
  284. if (( ftype != LDAP_FILTER_EQUALITY ) &&
  285. ( ftype != LDAP_FILTER_EQUALITY_FAST))
  286. {
  287. return( LDAP_PROTOCOL_ERROR );
  288. }
  289. if(ftype == LDAP_FILTER_EQUALITY_FAST) {
  290. /* With the fast option, we are trying to avoid creating and freeing
  291. * a bunch of structures - we just do one malloc here - see
  292. * ava_candidates in filterentry.c
  293. */
  294. len=slapi_value_get_length(bval);
  295. tmpval=(*ivals)[0];
  296. if (len > tmpval->bv.bv_len) {
  297. tmpval->bv.bv_val=(char *)slapi_ch_malloc(len);
  298. }
  299. tmpval->bv.bv_len=len;
  300. memcpy(tmpval->bv.bv_val,slapi_value_get_string(bval),len);
  301. } else {
  302. (*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
  303. (*ivals)[0] = slapi_value_dup( bval );
  304. (*ivals)[1] = NULL;
  305. }
  306. return( 0 );
  307. }
  308. #define BV_EMPTY(bv) ((!bv || !bv->bv_len || !bv->bv_val))
  309. static int
  310. bin_compare(
  311. struct berval *v1,
  312. struct berval *v2
  313. )
  314. {
  315. int rc = 0;
  316. if (BV_EMPTY(v1) && BV_EMPTY(v2)) {
  317. rc = 0; /* empty == empty */
  318. } else if (BV_EMPTY(v1) && !BV_EMPTY(v2)) {
  319. rc = 1; /* something in v2 always greater than empty v1 */
  320. } else if (!BV_EMPTY(v1) && BV_EMPTY(v2)) {
  321. rc = -1; /* something in v1 always greater than empty v2 */
  322. } else { /* both have actual data */
  323. rc = slapi_berval_cmp(v1, v2);
  324. }
  325. return rc;
  326. }