bin.c 11 KB

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