schema.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* See http://www.python-ldap.org/ for details.
  2. * $Id: schema.c,v 1.8 2009/04/17 12:19:09 stroeder Exp $ */
  3. #include "common.h"
  4. #include "schema.h"
  5. #include "ldap_schema.h"
  6. /*
  7. This utility function takes a null delimited C array of (null
  8. delimited) C strings, creates its python equivalent and returns a
  9. new reference to it. If the array is empty or the pointer to it is
  10. NULL, an empty python array is returned.
  11. */
  12. PyObject* c_string_array_to_python(char **string_array)
  13. {
  14. Py_ssize_t count = 0;
  15. char **s;
  16. PyObject *py_list;
  17. if (string_array) {
  18. for (s=string_array; *s != 0; s++) count++;
  19. py_list = PyList_New(count);
  20. count = 0;
  21. for (s=string_array; *s != 0; s++){
  22. PyList_SetItem(py_list, count, PyString_FromString(*s));
  23. count++;
  24. }
  25. } else py_list=PyList_New(0);
  26. return py_list;
  27. }
  28. /*
  29. This function returns a list of tuples. The first entry of each
  30. tuple is a string (lsei_name), and the second is a lists built from
  31. lsei_values.
  32. Probably the C data structure is modeled along the lines of a
  33. mapping "lsei_name -> (list of lsei_values)". However, there seems
  34. to be no guarantee that a lsei_name is unique, so I dare not use a
  35. python mapping for this beast...
  36. */
  37. PyObject* schema_extension_to_python(LDAPSchemaExtensionItem **extensions)
  38. {
  39. Py_ssize_t count = 0;
  40. LDAPSchemaExtensionItem **e;
  41. PyObject *py_list, *item_tuple;
  42. if (extensions) {
  43. for (e = extensions; *e !=0; e++) count++;
  44. py_list = PyList_New(count);
  45. count = 0;
  46. for (e = extensions; *e !=0; e++) {
  47. item_tuple = PyTuple_New(2);
  48. PyTuple_SetItem(item_tuple, 0,
  49. PyString_FromString((*e)->lsei_name));
  50. PyTuple_SetItem(item_tuple, 1,
  51. c_string_array_to_python((*e)->lsei_values));
  52. PyList_SetItem(py_list, count, item_tuple);
  53. count++;
  54. }
  55. }
  56. else py_list=PyList_New(0);
  57. return py_list;
  58. }
  59. /*
  60. The following four functions do the boring job: they take a python
  61. string, feed it into the respective parser functions provided by
  62. openldap, and build a python list from the data structure returned
  63. by the C function.
  64. */
  65. static char doc_ldap_str2objectclass[] =
  66. "";
  67. static PyObject*
  68. l_ldap_str2objectclass(PyObject* self, PyObject *args)
  69. {
  70. int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
  71. char *oc_string;
  72. const char *errp;
  73. LDAPObjectClass *o;
  74. PyObject *oc_names, *oc_sup_oids, *oc_at_oids_must,
  75. *oc_at_oids_may, *py_ret;
  76. if (!PyArg_ParseTuple(args, "si", &oc_string, &flag))
  77. return NULL;
  78. o = ldap_str2objectclass( oc_string, &ret, &errp, flag);
  79. if (ret) {
  80. py_ret = PyInt_FromLong(ret);
  81. return py_ret;
  82. }
  83. oc_sup_oids = c_string_array_to_python(o->oc_sup_oids);
  84. oc_names = c_string_array_to_python(o->oc_names);
  85. oc_at_oids_must = c_string_array_to_python(o->oc_at_oids_must);
  86. oc_at_oids_may = c_string_array_to_python(o->oc_at_oids_may);
  87. py_ret = PyList_New(9);
  88. PyList_SetItem(py_ret, 0, PyString_FromString(o->oc_oid));
  89. PyList_SetItem(py_ret, 1, oc_names);
  90. if (o->oc_desc) {
  91. PyList_SetItem(py_ret, 2, PyString_FromString(o->oc_desc));
  92. } else {
  93. PyList_SetItem(py_ret, 2, PyString_FromString(""));
  94. }
  95. PyList_SetItem(py_ret, 3, PyInt_FromLong(o->oc_obsolete));
  96. PyList_SetItem(py_ret, 4, oc_sup_oids);
  97. PyList_SetItem(py_ret, 5, PyInt_FromLong(o->oc_kind));
  98. PyList_SetItem(py_ret, 6, oc_at_oids_must);
  99. PyList_SetItem(py_ret, 7, oc_at_oids_may);
  100. PyList_SetItem(py_ret, 8,
  101. schema_extension_to_python(o->oc_extensions));
  102. ldap_objectclass_free(o);
  103. return py_ret;
  104. }
  105. static char doc_ldap_str2attributetype[] =
  106. "";
  107. static PyObject*
  108. l_ldap_str2attributetype(PyObject* self, PyObject *args)
  109. {
  110. int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
  111. char *at_string;
  112. const char *errp;
  113. LDAPAttributeType *a;
  114. PyObject *py_ret;
  115. PyObject *at_names;
  116. if (!PyArg_ParseTuple(args, "si", &at_string,&flag))
  117. return NULL;
  118. a = ldap_str2attributetype( at_string, &ret, &errp, flag);
  119. if (ret) {
  120. py_ret = PyInt_FromLong(ret);
  121. return py_ret;
  122. }
  123. py_ret = PyList_New(15);
  124. PyList_SetItem(py_ret, 0, PyString_FromString(a->at_oid));
  125. at_names = c_string_array_to_python(a->at_names);
  126. PyList_SetItem(py_ret, 1, at_names);
  127. if (a->at_desc) {
  128. PyList_SetItem(py_ret, 2, PyString_FromString(a->at_desc));
  129. } else {
  130. PyList_SetItem(py_ret, 2, PyString_FromString(""));
  131. }
  132. PyList_SetItem(py_ret, 3, PyInt_FromLong(a->at_obsolete));
  133. if (a->at_sup_oid) {
  134. PyList_SetItem(py_ret, 4, PyString_FromString(a->at_sup_oid));
  135. } else {
  136. PyList_SetItem(py_ret, 4, PyString_FromString(""));
  137. }
  138. if (a->at_equality_oid) {
  139. PyList_SetItem(py_ret, 5, PyString_FromString(a->at_equality_oid));
  140. } else {
  141. PyList_SetItem(py_ret, 5, PyString_FromString(""));
  142. }
  143. if (a->at_ordering_oid) {
  144. PyList_SetItem(py_ret, 6, PyString_FromString(a->at_ordering_oid));
  145. } else {
  146. PyList_SetItem(py_ret, 6, PyString_FromString(""));
  147. }
  148. if (a->at_substr_oid) {
  149. PyList_SetItem(py_ret, 7, PyString_FromString(a->at_substr_oid));
  150. } else {
  151. PyList_SetItem(py_ret, 7, PyString_FromString(""));
  152. }
  153. if (a->at_syntax_oid) {
  154. PyList_SetItem(py_ret, 8, PyString_FromString(a->at_syntax_oid));
  155. } else {
  156. PyList_SetItem(py_ret, 8, PyString_FromString(""));
  157. }
  158. PyList_SetItem(py_ret, 9, PyInt_FromLong(a->at_syntax_len));
  159. PyList_SetItem(py_ret,10, PyInt_FromLong(a->at_single_value));
  160. PyList_SetItem(py_ret,11, PyInt_FromLong(a->at_collective));
  161. PyList_SetItem(py_ret,12, PyInt_FromLong(a->at_no_user_mod));
  162. PyList_SetItem(py_ret,13, PyInt_FromLong(a->at_usage));
  163. PyList_SetItem(py_ret, 14,
  164. schema_extension_to_python(a->at_extensions));
  165. ldap_attributetype_free(a);
  166. return py_ret;
  167. }
  168. static char doc_ldap_str2syntax[] =
  169. "";
  170. static PyObject*
  171. l_ldap_str2syntax(PyObject* self, PyObject *args)
  172. {
  173. LDAPSyntax *s;
  174. int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
  175. const char *errp;
  176. char *syn_string;
  177. PyObject *py_ret, *syn_names;
  178. if (!PyArg_ParseTuple(args, "si", &syn_string,&flag))
  179. return NULL;
  180. s = ldap_str2syntax(syn_string, &ret, &errp, flag);
  181. if (ret) {
  182. py_ret = PyInt_FromLong(ret);
  183. return py_ret;
  184. }
  185. py_ret = PyList_New(4);
  186. PyList_SetItem(py_ret, 0, PyString_FromString(s->syn_oid));
  187. syn_names = c_string_array_to_python(s->syn_names);
  188. PyList_SetItem(py_ret, 1, syn_names);
  189. if (s->syn_desc) {
  190. PyList_SetItem(py_ret, 2, PyString_FromString(s->syn_desc));
  191. } else {
  192. PyList_SetItem(py_ret, 2, PyString_FromString(""));
  193. }
  194. PyList_SetItem(py_ret, 3,
  195. schema_extension_to_python(s->syn_extensions));
  196. ldap_syntax_free(s);
  197. return py_ret;
  198. }
  199. static char doc_ldap_str2matchingrule[] =
  200. "";
  201. static PyObject*
  202. l_ldap_str2matchingrule(PyObject* self, PyObject *args)
  203. {
  204. LDAPMatchingRule *m;
  205. int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
  206. const char *errp;
  207. char *mr_string;
  208. PyObject *py_ret, *mr_names;
  209. if (!PyArg_ParseTuple(args, "si", &mr_string,&flag))
  210. return NULL;
  211. m = ldap_str2matchingrule(mr_string, &ret, &errp, flag);
  212. if (ret) {
  213. py_ret = PyInt_FromLong(ret);
  214. return py_ret;
  215. }
  216. py_ret = PyList_New(6);
  217. PyList_SetItem(py_ret, 0, PyString_FromString(m->mr_oid));
  218. mr_names = c_string_array_to_python(m->mr_names);
  219. PyList_SetItem(py_ret, 1, mr_names);
  220. if (m->mr_desc) {
  221. PyList_SetItem(py_ret, 2, PyString_FromString(m->mr_desc));
  222. } else {
  223. PyList_SetItem(py_ret, 2, PyString_FromString(""));
  224. }
  225. PyList_SetItem(py_ret, 3, PyInt_FromLong(m->mr_obsolete));
  226. if (m->mr_syntax_oid) {
  227. PyList_SetItem(py_ret, 4, PyString_FromString(m->mr_syntax_oid));
  228. } else {
  229. PyList_SetItem(py_ret, 4, PyString_FromString(""));
  230. }
  231. PyList_SetItem(py_ret, 5,
  232. schema_extension_to_python(m->mr_extensions));
  233. ldap_matchingrule_free(m);
  234. return py_ret;
  235. }
  236. /* methods */
  237. static PyMethodDef methods[] = {
  238. { "str2objectclass", (PyCFunction)l_ldap_str2objectclass, METH_VARARGS,
  239. doc_ldap_str2objectclass },
  240. { "str2attributetype", (PyCFunction)l_ldap_str2attributetype,
  241. METH_VARARGS, doc_ldap_str2attributetype },
  242. { "str2syntax", (PyCFunction)l_ldap_str2syntax,
  243. METH_VARARGS, doc_ldap_str2syntax },
  244. { "str2matchingrule", (PyCFunction)l_ldap_str2matchingrule,
  245. METH_VARARGS, doc_ldap_str2matchingrule },
  246. { NULL, NULL }
  247. };
  248. void
  249. LDAPinit_schema( PyObject* d ) {
  250. LDAPadd_methods( d, methods );
  251. }