int.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. /* int.c - integer syntax routines */
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include "syntax.h"
  17. static int int_filter_ava(Slapi_PBlock *pb, struct berval *bvfilter, Slapi_Value **bvals, int ftype, Slapi_Value **retVal);
  18. static int int_values2keys(Slapi_PBlock *pb, Slapi_Value **val, Slapi_Value ***ivals, int ftype);
  19. static int int_assertion2keys(Slapi_PBlock *pb, Slapi_Value *val, Slapi_Value ***ivals, int ftype);
  20. static int int_compare(struct berval *v1, struct berval *v2);
  21. static int int_validate(struct berval *val);
  22. static void int_normalize(
  23. Slapi_PBlock *pb,
  24. char *s,
  25. int trim_spaces,
  26. char **alt);
  27. /* the first name is the official one from RFC 2252 */
  28. static char *names[] = {"INTEGER", "int", INTEGER_SYNTAX_OID, 0};
  29. #define INTEGERMATCH_OID "2.5.13.14"
  30. #define INTEGERORDERINGMATCH_OID "2.5.13.15"
  31. static Slapi_PluginDesc pdesc = {"int-syntax", VENDOR,
  32. DS_PACKAGE_VERSION, "integer attribute syntax plugin"};
  33. static const char *integerMatch_names[] = {"integerMatch", INTEGERMATCH_OID, NULL};
  34. static const char *integerOrderingMatch_names[] = {"integerOrderingMatch", INTEGERORDERINGMATCH_OID, NULL};
  35. static const char *integerFirstComponentMatch_names[] = {"integerFirstComponentMatch", "2.5.13.29", NULL};
  36. /* hack for now until we can support all of the rfc4517 syntaxes */
  37. static char *integerFirstComponentMatch_syntaxes[] = {DIRSTRING_SYNTAX_OID, NULL};
  38. static struct mr_plugin_def mr_plugin_table[] = {
  39. {
  40. {
  41. INTEGERMATCH_OID,
  42. NULL /* no alias? */,
  43. "integerMatch",
  44. "The rule evaluates to TRUE if and only if the attribute value and the assertion value are the same integer value.",
  45. INTEGER_SYNTAX_OID,
  46. 0 /* not obsolete */,
  47. NULL /* no other compatible syntaxes */
  48. },
  49. {"integerMatch-mr",
  50. VENDOR,
  51. DS_PACKAGE_VERSION,
  52. "integerMatch matching rule plugin"},
  53. integerMatch_names, /* matching rule name/oid/aliases */
  54. NULL,
  55. NULL,
  56. int_filter_ava,
  57. NULL,
  58. int_values2keys,
  59. int_assertion2keys,
  60. NULL,
  61. int_compare,
  62. NULL /* mr_normalise */
  63. },
  64. {
  65. {
  66. INTEGERORDERINGMATCH_OID,
  67. NULL /* no alias? */,
  68. "integerOrderingMatch",
  69. "The rule evaluates to TRUE if and only if the integer value of the attribute value is less than the integer value of the assertion value.",
  70. INTEGER_SYNTAX_OID,
  71. 0 /* not obsolete */,
  72. NULL /* no other compatible syntaxes */
  73. },
  74. {"integerOrderingMatch-mr",
  75. VENDOR,
  76. DS_PACKAGE_VERSION,
  77. "integerOrderingMatch matching rule plugin"},
  78. integerOrderingMatch_names, /* matching rule name/oid/aliases */
  79. NULL,
  80. NULL,
  81. int_filter_ava,
  82. NULL,
  83. int_values2keys,
  84. int_assertion2keys,
  85. NULL,
  86. int_compare,
  87. NULL /* mr_normalise */
  88. },
  89. /* NOTE: THIS IS BROKEN - WE DON'T SUPPORT THE FIRSTCOMPONENT match */
  90. {
  91. {"2.5.13.29",
  92. NULL,
  93. "integerFirstComponentMatch",
  94. "The integerFirstComponentMatch rule compares an assertion value of "
  95. "the Integer syntax to an attribute value of a syntax (e.g., the DIT "
  96. "Structure Rule Description syntax) whose corresponding ASN.1 type is "
  97. "a SEQUENCE with a mandatory first component of the INTEGER ASN.1 "
  98. "type. "
  99. "Note that the assertion syntax of this matching rule differs from the "
  100. "attribute syntax of attributes for which this is the equality "
  101. "matching rule. "
  102. "The rule evaluates to TRUE if and only if the assertion value and the "
  103. "first component of the attribute value are the same integer value.",
  104. INTEGER_SYNTAX_OID,
  105. 0,
  106. integerFirstComponentMatch_syntaxes}, /* matching rule desc */
  107. {
  108. "integerFirstComponentMatch-mr",
  109. VENDOR,
  110. DS_PACKAGE_VERSION,
  111. "integerFirstComponentMatch matching rule plugin"}, /* plugin desc */
  112. integerFirstComponentMatch_names, /* matching rule name/oid/aliases */
  113. NULL,
  114. NULL,
  115. int_filter_ava,
  116. NULL,
  117. int_values2keys,
  118. int_assertion2keys,
  119. NULL,
  120. int_compare,
  121. NULL /* mr_normalise */
  122. },
  123. };
  124. static size_t mr_plugin_table_size = sizeof(mr_plugin_table) / sizeof(mr_plugin_table[0]);
  125. static int
  126. matching_rule_plugin_init(Slapi_PBlock *pb)
  127. {
  128. return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
  129. }
  130. static int
  131. register_matching_rule_plugins(void)
  132. {
  133. return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
  134. }
  135. int
  136. int_init(Slapi_PBlock *pb)
  137. {
  138. int rc, flags;
  139. slapi_log_err(SLAPI_LOG_PLUGIN, SYNTAX_PLUGIN_SUBSYSTEM, "=> int_init\n");
  140. rc = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  141. (void *)SLAPI_PLUGIN_VERSION_01);
  142. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
  143. (void *)&pdesc);
  144. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
  145. (void *)int_filter_ava);
  146. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
  147. (void *)int_values2keys);
  148. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
  149. (void *)int_assertion2keys);
  150. flags = SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING;
  151. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_FLAGS,
  152. (void *)&flags);
  153. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_NAMES,
  154. (void *)names);
  155. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_OID,
  156. (void *)INTEGER_SYNTAX_OID);
  157. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_COMPARE,
  158. (void *)int_compare);
  159. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
  160. (void *)int_validate);
  161. rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_SYNTAX_NORMALIZE,
  162. (void *)int_normalize);
  163. rc |= register_matching_rule_plugins();
  164. slapi_log_err(SLAPI_LOG_PLUGIN, SYNTAX_PLUGIN_SUBSYSTEM, "<= int_init %d\n", rc);
  165. return (rc);
  166. }
  167. static int
  168. int_filter_ava(Slapi_PBlock *pb, struct berval *bvfilter, Slapi_Value **bvals, int ftype, Slapi_Value **retVal)
  169. {
  170. int filter_normalized = 0;
  171. int syntax = SYNTAX_INT | SYNTAX_CES;
  172. if (pb) {
  173. slapi_pblock_get(pb, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED,
  174. &filter_normalized);
  175. if (filter_normalized) {
  176. syntax |= SYNTAX_NORM_FILT;
  177. }
  178. }
  179. return (string_filter_ava(bvfilter, bvals, syntax,
  180. ftype, retVal));
  181. }
  182. static int
  183. int_values2keys(Slapi_PBlock *pb, Slapi_Value **vals, Slapi_Value ***ivals, int ftype)
  184. {
  185. return (string_values2keys(pb, vals, ivals, SYNTAX_INT | SYNTAX_CES,
  186. ftype));
  187. }
  188. static int
  189. int_assertion2keys(Slapi_PBlock *pb, Slapi_Value *val, Slapi_Value ***ivals, int ftype)
  190. {
  191. return (string_assertion2keys_ava(pb, val, ivals,
  192. SYNTAX_INT | SYNTAX_CES, ftype));
  193. }
  194. static int
  195. int_compare(
  196. struct berval *v1,
  197. struct berval *v2)
  198. {
  199. return value_cmp(v1, v2, SYNTAX_INT | SYNTAX_CES, 3 /* Normalise both values */);
  200. }
  201. /* return 0 if valid, non-0 if invalid */
  202. static int
  203. int_validate(
  204. struct berval *val)
  205. {
  206. int rc = 0; /* assume the value is valid */
  207. char *p = NULL;
  208. char *end = NULL;
  209. /* Per RFC4517:
  210. *
  211. * Integer = (HYPHEN LDIGIT *DIGIT) / number
  212. * number = DIGIT / (LDIGIT 1*DIGIT)
  213. */
  214. if ((val != NULL) && (val->bv_len > 0)) {
  215. p = val->bv_val;
  216. end = &(val->bv_val[val->bv_len - 1]);
  217. /* If the first character is HYPHEN, we need
  218. * to make sure the next char is a LDIGIT. */
  219. if (*p == '-') {
  220. p++;
  221. if ((p > end) || !IS_LDIGIT(*p)) {
  222. rc = 1;
  223. goto exit;
  224. }
  225. p++;
  226. } else if (*p == '0') {
  227. /* 0 is allowed by itself, but not as
  228. * a leading 0 before other digits */
  229. if (p != end) {
  230. rc = 1;
  231. }
  232. /* We're done here */
  233. goto exit;
  234. }
  235. /* Now we can simply allow the rest to be DIGIT */
  236. for (; p <= end; p++) {
  237. if (!isdigit(*p)) {
  238. rc = 1;
  239. goto exit;
  240. }
  241. }
  242. } else {
  243. rc = 1;
  244. }
  245. exit:
  246. return (rc);
  247. }
  248. static void
  249. int_normalize(
  250. Slapi_PBlock *pb __attribute__((unused)),
  251. char *s,
  252. int trim_spaces,
  253. char **alt)
  254. {
  255. value_normalize_ext(s, SYNTAX_INT | SYNTAX_CES, trim_spaces, alt);
  256. return;
  257. }