ldapcontrol.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /* See http://www.python-ldap.org/ for details.
  2. * $Id: ldapcontrol.c,v 1.17 2009/08/17 01:49:47 leonard Exp $ */
  3. #include "common.h"
  4. #include "LDAPObject.h"
  5. #include "ldapcontrol.h"
  6. #include "berval.h"
  7. #include "errors.h"
  8. #include "lber.h"
  9. /* Prints to stdout the contents of an array of LDAPControl objects */
  10. /* XXX: This is a debugging tool, and the printf generates some warnings
  11. * about pointer types. I left it here in case something breaks and we
  12. * need to inspect an LDAPControl structure.
  13. static void
  14. LDAPControl_DumpList( LDAPControl** lcs ) {
  15. LDAPControl** lcp;
  16. LDAPControl* lc;
  17. for ( lcp = lcs; *lcp; lcp++ ) {
  18. lc = *lcp;
  19. printf("OID: %s\nCriticality: %d\nBER length: %d\nBER value: %x\n",
  20. lc->ldctl_oid, lc->ldctl_iscritical, lc->ldctl_value.bv_len,
  21. lc->ldctl_value.bv_val);
  22. }
  23. } */
  24. /* Free a single LDAPControl object created by Tuple_to_LDAPControl */
  25. static void
  26. LDAPControl_DEL( LDAPControl* lc )
  27. {
  28. if (lc == NULL)
  29. return;
  30. if (lc->ldctl_oid)
  31. PyMem_DEL(lc->ldctl_oid);
  32. PyMem_DEL(lc);
  33. }
  34. /* Free an array of LDAPControl objects created by LDAPControls_from_object */
  35. void
  36. LDAPControl_List_DEL( LDAPControl** lcs )
  37. {
  38. LDAPControl** lcp;
  39. if (lcs == NULL)
  40. return;
  41. for ( lcp = lcs; *lcp; lcp++ )
  42. LDAPControl_DEL( *lcp );
  43. PyMem_DEL( lcs );
  44. }
  45. /* Takes a tuple of the form:
  46. * (OID: string, Criticality: int/boolean, Value: string/None)
  47. * and converts it into an LDAPControl structure.
  48. *
  49. * The Value string should represent an ASN.1 encoded structure.
  50. */
  51. static LDAPControl*
  52. Tuple_to_LDAPControl( PyObject* tup )
  53. {
  54. char *oid;
  55. char iscritical;
  56. struct berval berbytes;
  57. PyObject *bytes;
  58. LDAPControl *lc = NULL;
  59. Py_ssize_t len;
  60. if (!PyTuple_Check(tup)) {
  61. PyErr_SetObject(PyExc_TypeError, Py_BuildValue("sO",
  62. "expected a tuple", tup));
  63. return NULL;
  64. }
  65. if (!PyArg_ParseTuple( tup, "sbO", &oid, &iscritical, &bytes ))
  66. return NULL;
  67. lc = PyMem_NEW(LDAPControl, 1);
  68. if (lc == NULL) {
  69. PyErr_NoMemory();
  70. return NULL;
  71. }
  72. lc->ldctl_iscritical = iscritical;
  73. len = strlen(oid);
  74. lc->ldctl_oid = PyMem_NEW(char, len + 1);
  75. if (lc->ldctl_oid == NULL) {
  76. PyErr_NoMemory();
  77. LDAPControl_DEL(lc);
  78. return NULL;
  79. }
  80. memcpy(lc->ldctl_oid, oid, len + 1);
  81. /* The berval can either be None or a String */
  82. if (PyNone_Check(bytes)) {
  83. berbytes.bv_len = 0;
  84. berbytes.bv_val = NULL;
  85. }
  86. else if (PyString_Check(bytes)) {
  87. berbytes.bv_len = PyString_Size(bytes);
  88. berbytes.bv_val = PyString_AsString(bytes);
  89. }
  90. else {
  91. PyErr_SetObject(PyExc_TypeError, Py_BuildValue("sO",
  92. "expected a string", bytes));
  93. LDAPControl_DEL(lc);
  94. return NULL;
  95. }
  96. lc->ldctl_value = berbytes;
  97. return lc;
  98. }
  99. /* Convert a list of tuples (of a format acceptable to the Tuple_to_LDAPControl
  100. * function) into an array of LDAPControl objects. */
  101. int
  102. LDAPControls_from_object(PyObject* list, LDAPControl ***controls_ret)
  103. {
  104. Py_ssize_t len, i;
  105. LDAPControl** ldcs;
  106. LDAPControl* ldc;
  107. PyObject* item;
  108. if (!PySequence_Check(list)) {
  109. PyErr_SetObject(PyExc_TypeError, Py_BuildValue("sO",
  110. "expected a list", list));
  111. return 0;
  112. }
  113. len = PySequence_Length(list);
  114. ldcs = PyMem_NEW(LDAPControl*, len + 1);
  115. if (ldcs == NULL) {
  116. PyErr_NoMemory();
  117. return 0;
  118. }
  119. for (i = 0; i < len; i++) {
  120. item = PySequence_GetItem(list, i);
  121. if (item == NULL) {
  122. PyMem_DEL(ldcs);
  123. return 0;
  124. }
  125. ldc = Tuple_to_LDAPControl(item);
  126. if (ldc == NULL) {
  127. PyMem_DEL(ldcs);
  128. return 0;
  129. }
  130. ldcs[i] = ldc;
  131. }
  132. ldcs[len] = NULL;
  133. *controls_ret = ldcs;
  134. return 1;
  135. }
  136. PyObject*
  137. LDAPControls_to_List(LDAPControl **ldcs)
  138. {
  139. PyObject *res = 0, *pyctrl;
  140. LDAPControl **tmp = ldcs;
  141. Py_ssize_t num_ctrls = 0, i;
  142. if (tmp)
  143. while (*tmp++) num_ctrls++;
  144. if (!(res = PyList_New(num_ctrls)))
  145. goto endlbl;
  146. for (i = 0; i < num_ctrls; i++) {
  147. if (!(pyctrl = Py_BuildValue("sbO&", ldcs[i]->ldctl_oid,
  148. ldcs[i]->ldctl_iscritical,
  149. LDAPberval_to_object,
  150. &ldcs[i]->ldctl_value))) {
  151. goto endlbl;
  152. }
  153. PyList_SET_ITEM(res, i, pyctrl);
  154. }
  155. Py_INCREF(res);
  156. endlbl:
  157. Py_XDECREF(res);
  158. return res;
  159. }
  160. /* --------------- en-/decoders ------------- */
  161. /* Matched Values, aka, Values Return Filter */
  162. static PyObject*
  163. encode_rfc3876(PyObject *self, PyObject *args)
  164. {
  165. PyObject *res = 0;
  166. int err;
  167. BerElement *vrber = 0;
  168. char *vrFilter;
  169. struct berval *ctrl_val;
  170. if (!PyArg_ParseTuple(args, "s:encode_valuesreturnfilter_control", &vrFilter)) {
  171. goto endlbl;
  172. }
  173. if (!(vrber = ber_alloc_t(LBER_USE_DER))) {
  174. LDAPerr(LDAP_NO_MEMORY);
  175. goto endlbl;
  176. }
  177. err = ldap_put_vrFilter(vrber, vrFilter);
  178. if (err == -1) {
  179. LDAPerr(LDAP_FILTER_ERROR);
  180. goto endlbl;
  181. }
  182. err = ber_flatten(vrber, &ctrl_val);
  183. if (err == -1) {
  184. LDAPerr(LDAP_NO_MEMORY);
  185. goto endlbl;
  186. }
  187. res = LDAPberval_to_object(ctrl_val);
  188. endlbl:
  189. if (vrber)
  190. ber_free(vrber, 1);
  191. return res;
  192. }
  193. static PyObject*
  194. encode_rfc2696(PyObject *self, PyObject *args)
  195. {
  196. PyObject *res = 0;
  197. BerElement *ber = 0;
  198. struct berval cookie, *ctrl_val;
  199. Py_ssize_t cookie_len;
  200. unsigned long size;
  201. ber_tag_t tag;
  202. if (!PyArg_ParseTuple(args, "is#:encode_page_control", &size,
  203. &cookie.bv_val, &cookie_len)) {
  204. goto endlbl;
  205. }
  206. cookie.bv_len = (ber_len_t) cookie_len;
  207. if (!(ber = ber_alloc_t(LBER_USE_DER))) {
  208. LDAPerr(LDAP_NO_MEMORY);
  209. goto endlbl;
  210. }
  211. tag = ber_printf(ber, "{i", size);
  212. if (tag == LBER_ERROR) {
  213. LDAPerr(LDAP_ENCODING_ERROR);
  214. goto endlbl;
  215. }
  216. if (!cookie.bv_len)
  217. tag = ber_printf(ber, "o", "", 0);
  218. else
  219. tag = ber_printf(ber, "O", &cookie);
  220. if (tag == LBER_ERROR) {
  221. LDAPerr(LDAP_ENCODING_ERROR);
  222. goto endlbl;
  223. }
  224. tag = ber_printf(ber, /*{ */ "N}");
  225. if (tag == LBER_ERROR) {
  226. LDAPerr(LDAP_ENCODING_ERROR);
  227. goto endlbl;
  228. }
  229. if (-1 == ber_flatten(ber, &ctrl_val)) {
  230. LDAPerr(LDAP_NO_MEMORY);
  231. goto endlbl;
  232. }
  233. res = LDAPberval_to_object(ctrl_val);
  234. endlbl:
  235. if (ber)
  236. ber_free(ber, 1);
  237. return res;
  238. }
  239. static PyObject*
  240. decode_rfc2696(PyObject *self, PyObject *args)
  241. {
  242. PyObject *res = 0;
  243. BerElement *ber = 0;
  244. struct berval ldctl_value;
  245. ber_tag_t tag;
  246. struct berval *cookiep;
  247. unsigned long count;
  248. Py_ssize_t ldctl_value_len;
  249. if (!PyArg_ParseTuple(args, "s#:decode_page_control",
  250. &ldctl_value.bv_val, &ldctl_value_len)) {
  251. goto endlbl;
  252. }
  253. ldctl_value.bv_len = (ber_len_t) ldctl_value_len;
  254. if (!(ber = ber_init(&ldctl_value))) {
  255. LDAPerr(LDAP_NO_MEMORY);
  256. goto endlbl;
  257. }
  258. tag = ber_scanf(ber, "{iO", &count, &cookiep);
  259. if (tag == LBER_ERROR) {
  260. LDAPerr(LDAP_DECODING_ERROR);
  261. goto endlbl;
  262. }
  263. res = Py_BuildValue("(lO&)", count, LDAPberval_to_object, cookiep);
  264. endlbl:
  265. if (ber)
  266. ber_free(ber, 1);
  267. return res;
  268. }
  269. #ifdef LIBLDAP_HAS_ASSERTION_CONTROL_FUNC
  270. static PyObject*
  271. encode_assertion_control(PyObject *self, PyObject *args)
  272. {
  273. int err;
  274. PyObject *res = 0;
  275. char *assertion_filterstr;
  276. struct berval ctrl_val;
  277. BerElement *ber = 0;
  278. if (!PyArg_ParseTuple(args, "s:encode_assertion_control",
  279. &assertion_filterstr)) {
  280. goto endlbl;
  281. }
  282. err = ldap_create_assertion_control_value(NULL,assertion_filterstr,&ctrl_val);
  283. res = LDAPberval_to_object(&ctrl_val);
  284. endlbl:
  285. if (ber)
  286. ber_free(ber, 1);
  287. return res;
  288. }
  289. #endif
  290. static PyMethodDef methods[] = {
  291. {"encode_page_control", encode_rfc2696, METH_VARARGS },
  292. {"decode_page_control", decode_rfc2696, METH_VARARGS },
  293. {"encode_valuesreturnfilter_control", encode_rfc3876, METH_VARARGS },
  294. #ifdef LIBLDAP_HAS_ASSERTION_CONTROL_FUNC
  295. {"encode_assertion_control", encode_assertion_control, METH_VARARGS },
  296. #endif
  297. { NULL, NULL }
  298. };
  299. void
  300. LDAPinit_control(PyObject *d)
  301. {
  302. LDAPadd_methods(d, methods);
  303. }