1
0

bitwise.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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) 2007 Red Hat, Inc.
  35. * All rights reserved.
  36. * END COPYRIGHT BLOCK **/
  37. #ifdef HAVE_CONFIG_H
  38. # include <config.h>
  39. #endif
  40. /* orfilter.c - implementation of ordering rule filter */
  41. #include <ldap.h> /* LDAP_UTF8INC */
  42. #include <slap.h> /* for debug macros */
  43. #include <slapi-plugin.h> /* slapi_berval_cmp, SLAPI_BERVAL_EQ */
  44. #ifdef HPUX11
  45. #include <dl.h>
  46. #endif /* HPUX11 */
  47. /* the match function needs the attribute type and value from the search
  48. filter - this is unfortunately not passed into the match fn, so we
  49. have to keep track of this
  50. */
  51. struct bitwise_match_cb {
  52. char *type; /* the attribute type from the filter ava */
  53. struct berval *val; /* the value from the filter ava */
  54. };
  55. /*
  56. The type and val pointers are assumed to have sufficient lifetime -
  57. we don't have to copy them - they are usually just pointers into
  58. the SLAPI_PLUGIN_MR_TYPE and SLAPI_PLUGIN_MR_VALUE fields of the
  59. operation pblock, whose lifetime should encompass the creation
  60. and destruction of the bitwise_match_cb object.
  61. */
  62. static struct bitwise_match_cb *
  63. new_bitwise_match_cb(char *type, struct berval *val)
  64. {
  65. struct bitwise_match_cb *bmc = (struct bitwise_match_cb *)slapi_ch_calloc(1, sizeof(struct bitwise_match_cb));
  66. bmc->type = type;
  67. bmc->val = val;
  68. return bmc;
  69. }
  70. static void
  71. delete_bitwise_match_cb(struct bitwise_match_cb *bmc)
  72. {
  73. slapi_ch_free((void **)&bmc);
  74. }
  75. static void
  76. bitwise_filter_destroy(Slapi_PBlock* pb)
  77. {
  78. void *obj = NULL;
  79. slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &obj);
  80. if (obj) {
  81. struct bitwise_match_cb *bmc = (struct bitwise_match_cb *)obj;
  82. delete_bitwise_match_cb(bmc);
  83. obj = NULL;
  84. slapi_pblock_set(pb, SLAPI_PLUGIN_OBJECT, obj);
  85. }
  86. }
  87. #define BITWISE_OP_AND 0
  88. #define BITWISE_OP_OR 1
  89. static int
  90. internal_bitwise_filter_match(void* obj, Slapi_Entry* entry, Slapi_Attr* attr, int op)
  91. /* returns: 0 filter matched
  92. * -1 filter did not match
  93. * >0 an LDAP error code
  94. */
  95. {
  96. struct bitwise_match_cb *bmc = obj;
  97. auto int rc = -1; /* no match */
  98. char **ary = NULL;
  99. int ii;
  100. ary = slapi_entry_attr_get_charray(entry, bmc->type);
  101. /* look through all values until we find a match */
  102. for (ii = 0; (rc == -1) && ary && ary[ii]; ++ii) {
  103. unsigned long long a, b;
  104. char *val_from_entry = ary[ii];
  105. errno = 0;
  106. a = strtoull(val_from_entry, NULL, 10);
  107. if (errno != ERANGE) {
  108. errno = 0;
  109. b = strtoull(bmc->val->bv_val, NULL, 10);
  110. if (errno == ERANGE) {
  111. rc = LDAP_CONSTRAINT_VIOLATION;
  112. } else {
  113. int result;
  114. if (op == BITWISE_OP_AND) {
  115. result = (a & b);
  116. } else if (op == BITWISE_OP_OR) {
  117. result = (a | b);
  118. }
  119. if (result) {
  120. rc = 0;
  121. }
  122. }
  123. }
  124. }
  125. slapi_ch_array_free(ary);
  126. return rc;
  127. }
  128. static int
  129. bitwise_filter_match_and (void* obj, Slapi_Entry* entry, Slapi_Attr* attr)
  130. /* returns: 0 filter matched
  131. * -1 filter did not match
  132. * >0 an LDAP error code
  133. */
  134. {
  135. return internal_bitwise_filter_match(obj, entry, attr, BITWISE_OP_AND);
  136. }
  137. static int
  138. bitwise_filter_match_or (void* obj, Slapi_Entry* entry, Slapi_Attr* attr)
  139. /* returns: 0 filter matched
  140. * -1 filter did not match
  141. * >0 an LDAP error code
  142. */
  143. {
  144. return internal_bitwise_filter_match(obj, entry, attr, BITWISE_OP_OR);
  145. }
  146. static int
  147. bitwise_filter_create (Slapi_PBlock* pb)
  148. {
  149. auto int rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* failed to initialize */
  150. auto char* mrOID = NULL;
  151. auto char* mrTYPE = NULL;
  152. auto struct berval* mrVALUE = NULL;
  153. if (!slapi_pblock_get (pb, SLAPI_PLUGIN_MR_OID, &mrOID) && mrOID != NULL &&
  154. !slapi_pblock_get (pb, SLAPI_PLUGIN_MR_TYPE, &mrTYPE) && mrTYPE != NULL &&
  155. !slapi_pblock_get (pb, SLAPI_PLUGIN_MR_VALUE, &mrVALUE) && mrVALUE != NULL) {
  156. struct bitwise_match_cb *bmc = NULL;
  157. if (strcmp(mrOID, "1.2.840.113556.1.4.803") == 0) {
  158. slapi_pblock_set (pb, SLAPI_PLUGIN_MR_FILTER_MATCH_FN, (void*)bitwise_filter_match_and);
  159. } else if (strcmp(mrOID, "1.2.840.113556.1.4.804") == 0) {
  160. slapi_pblock_set (pb, SLAPI_PLUGIN_MR_FILTER_MATCH_FN, (void*)bitwise_filter_match_or);
  161. } else { /* this oid not handled by this plugin */
  162. LDAPDebug (LDAP_DEBUG_FILTER, "=> bitwise_filter_create OID (%s) not handled\n", mrOID, 0, 0);
  163. return rc;
  164. }
  165. bmc = new_bitwise_match_cb(mrTYPE, mrVALUE);
  166. slapi_pblock_set (pb, SLAPI_PLUGIN_OBJECT, bmc);
  167. slapi_pblock_set (pb, SLAPI_PLUGIN_DESTROY_FN, (void*)bitwise_filter_destroy);
  168. rc = LDAP_SUCCESS;
  169. } else {
  170. LDAPDebug (LDAP_DEBUG_FILTER, "=> bitwise_filter_create missing parameter(s)\n", 0, 0, 0);
  171. }
  172. LDAPDebug (LDAP_DEBUG_FILTER, "<= bitwise_filter_create %i\n", rc, 0, 0);
  173. return LDAP_SUCCESS;
  174. }
  175. static Slapi_PluginDesc pdesc = { "bitwise", VENDOR, PACKAGE_VERSION,
  176. "bitwise match plugin" };
  177. int /* LDAP error code */
  178. bitwise_init (Slapi_PBlock* pb)
  179. {
  180. int rc;
  181. rc = slapi_pblock_set (pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, (void*)bitwise_filter_create);
  182. if ( rc == 0 ) {
  183. rc = slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc );
  184. }
  185. LDAPDebug (LDAP_DEBUG_FILTER, "bitwise_init %i\n", rc, 0, 0);
  186. return rc;
  187. }