1
0

bitwise.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. unsigned long long a, b;
  98. char *val_from_entry = NULL;
  99. auto int rc = -1; /* no match */
  100. val_from_entry = slapi_entry_attr_get_charptr(entry, bmc->type);
  101. if (val_from_entry) {
  102. errno = 0;
  103. a = strtoull(val_from_entry, NULL, 10);
  104. if (errno != ERANGE) {
  105. errno = 0;
  106. b = strtoull(bmc->val->bv_val, NULL, 10);
  107. if (errno == ERANGE) {
  108. rc = LDAP_CONSTRAINT_VIOLATION;
  109. } else {
  110. int result;
  111. if (op == BITWISE_OP_AND) {
  112. result = (a & b);
  113. } else if (op == BITWISE_OP_OR) {
  114. result = (a | b);
  115. }
  116. if (result) {
  117. rc = 0;
  118. }
  119. }
  120. }
  121. slapi_ch_free_string(&val_from_entry);
  122. }
  123. return rc;
  124. }
  125. static int
  126. bitwise_filter_match_and (void* obj, Slapi_Entry* entry, Slapi_Attr* attr)
  127. /* returns: 0 filter matched
  128. * -1 filter did not match
  129. * >0 an LDAP error code
  130. */
  131. {
  132. return internal_bitwise_filter_match(obj, entry, attr, BITWISE_OP_AND);
  133. }
  134. static int
  135. bitwise_filter_match_or (void* obj, Slapi_Entry* entry, Slapi_Attr* attr)
  136. /* returns: 0 filter matched
  137. * -1 filter did not match
  138. * >0 an LDAP error code
  139. */
  140. {
  141. return internal_bitwise_filter_match(obj, entry, attr, BITWISE_OP_OR);
  142. }
  143. static int
  144. bitwise_filter_create (Slapi_PBlock* pb)
  145. {
  146. auto int rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; /* failed to initialize */
  147. auto char* mrOID = NULL;
  148. auto char* mrTYPE = NULL;
  149. auto struct berval* mrVALUE = NULL;
  150. if (!slapi_pblock_get (pb, SLAPI_PLUGIN_MR_OID, &mrOID) && mrOID != NULL &&
  151. !slapi_pblock_get (pb, SLAPI_PLUGIN_MR_TYPE, &mrTYPE) && mrTYPE != NULL &&
  152. !slapi_pblock_get (pb, SLAPI_PLUGIN_MR_VALUE, &mrVALUE) && mrVALUE != NULL) {
  153. struct bitwise_match_cb *bmc = NULL;
  154. if (strcmp(mrOID, "1.2.840.113556.1.4.803") == 0) {
  155. slapi_pblock_set (pb, SLAPI_PLUGIN_MR_FILTER_MATCH_FN, (void*)bitwise_filter_match_and);
  156. } else if (strcmp(mrOID, "1.2.840.113556.1.4.804") == 0) {
  157. slapi_pblock_set (pb, SLAPI_PLUGIN_MR_FILTER_MATCH_FN, (void*)bitwise_filter_match_or);
  158. } else { /* this oid not handled by this plugin */
  159. LDAPDebug (LDAP_DEBUG_FILTER, "=> bitwise_filter_create OID (%s) not handled\n", mrOID, 0, 0);
  160. return rc;
  161. }
  162. bmc = new_bitwise_match_cb(mrTYPE, mrVALUE);
  163. slapi_pblock_set (pb, SLAPI_PLUGIN_OBJECT, bmc);
  164. slapi_pblock_set (pb, SLAPI_PLUGIN_DESTROY_FN, (void*)bitwise_filter_destroy);
  165. rc = LDAP_SUCCESS;
  166. } else {
  167. LDAPDebug (LDAP_DEBUG_FILTER, "=> bitwise_filter_create missing parameter(s)\n", 0, 0, 0);
  168. }
  169. LDAPDebug (LDAP_DEBUG_FILTER, "<= bitwise_filter_create %i\n", rc, 0, 0);
  170. return LDAP_SUCCESS;
  171. }
  172. static Slapi_PluginDesc pdesc = { "bitwise", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
  173. "bitwise match plugin" };
  174. int /* LDAP error code */
  175. bitwise_init (Slapi_PBlock* pb)
  176. {
  177. int rc;
  178. rc = slapi_pblock_set (pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, (void*)bitwise_filter_create);
  179. if ( rc == 0 ) {
  180. rc = slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc );
  181. }
  182. LDAPDebug (LDAP_DEBUG_FILTER, "bitwise_init %i\n", rc, 0, 0);
  183. return rc;
  184. }