/* See http://www.python-ldap.org/ for details. * $Id: schema.c,v 1.8 2009/04/17 12:19:09 stroeder Exp $ */ #include "common.h" #include "schema.h" #include "ldap_schema.h" /* This utility function takes a null delimited C array of (null delimited) C strings, creates its python equivalent and returns a new reference to it. If the array is empty or the pointer to it is NULL, an empty python array is returned. */ PyObject* c_string_array_to_python(char **string_array) { Py_ssize_t count = 0; char **s; PyObject *py_list; if (string_array) { for (s=string_array; *s != 0; s++) count++; py_list = PyList_New(count); count = 0; for (s=string_array; *s != 0; s++){ PyList_SetItem(py_list, count, PyUnicode_FromString(*s)); count++; } } else py_list=PyList_New(0); return py_list; } /* This function returns a list of tuples. The first entry of each tuple is a string (lsei_name), and the second is a lists built from lsei_values. Probably the C data structure is modeled along the lines of a mapping "lsei_name -> (list of lsei_values)". However, there seems to be no guarantee that a lsei_name is unique, so I dare not use a python mapping for this beast... */ PyObject* schema_extension_to_python(LDAPSchemaExtensionItem **extensions) { Py_ssize_t count = 0; LDAPSchemaExtensionItem **e; PyObject *py_list, *item_tuple; if (extensions) { for (e = extensions; *e !=0; e++) count++; py_list = PyList_New(count); count = 0; for (e = extensions; *e !=0; e++) { item_tuple = PyTuple_New(2); PyTuple_SetItem(item_tuple, 0, PyUnicode_FromString((*e)->lsei_name)); PyTuple_SetItem(item_tuple, 1, c_string_array_to_python((*e)->lsei_values)); PyList_SetItem(py_list, count, item_tuple); count++; } } else py_list=PyList_New(0); return py_list; } /* The following four functions do the boring job: they take a python string, feed it into the respective parser functions provided by openldap, and build a python list from the data structure returned by the C function. */ static char doc_ldap_str2objectclass[] = ""; static PyObject* l_ldap_str2objectclass(PyObject* self, PyObject *args) { int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE; char *oc_string; const char *errp; LDAPObjectClass *o; PyObject *oc_names, *oc_sup_oids, *oc_at_oids_must, *oc_at_oids_may, *py_ret; if (!PyArg_ParseTuple(args, "si", &oc_string, &flag)) return NULL; o = ldap_str2objectclass( oc_string, &ret, &errp, flag); if (ret) { py_ret = PyInt_FromLong(ret); return py_ret; } oc_sup_oids = c_string_array_to_python(o->oc_sup_oids); oc_names = c_string_array_to_python(o->oc_names); oc_at_oids_must = c_string_array_to_python(o->oc_at_oids_must); oc_at_oids_may = c_string_array_to_python(o->oc_at_oids_may); py_ret = PyList_New(9); PyList_SetItem(py_ret, 0, PyUnicode_FromString(o->oc_oid)); PyList_SetItem(py_ret, 1, oc_names); if (o->oc_desc) { PyList_SetItem(py_ret, 2, PyUnicode_FromString(o->oc_desc)); } else { PyList_SetItem(py_ret, 2, PyUnicode_FromString("")); } PyList_SetItem(py_ret, 3, PyInt_FromLong(o->oc_obsolete)); PyList_SetItem(py_ret, 4, oc_sup_oids); PyList_SetItem(py_ret, 5, PyInt_FromLong(o->oc_kind)); PyList_SetItem(py_ret, 6, oc_at_oids_must); PyList_SetItem(py_ret, 7, oc_at_oids_may); PyList_SetItem(py_ret, 8, schema_extension_to_python(o->oc_extensions)); ldap_objectclass_free(o); return py_ret; } static char doc_ldap_str2attributetype[] = ""; static PyObject* l_ldap_str2attributetype(PyObject* self, PyObject *args) { int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE; char *at_string; const char *errp; LDAPAttributeType *a; PyObject *py_ret; PyObject *at_names; if (!PyArg_ParseTuple(args, "si", &at_string,&flag)) return NULL; a = ldap_str2attributetype( at_string, &ret, &errp, flag); if (ret) { py_ret = PyInt_FromLong(ret); return py_ret; } py_ret = PyList_New(15); PyList_SetItem(py_ret, 0, PyUnicode_FromString(a->at_oid)); at_names = c_string_array_to_python(a->at_names); PyList_SetItem(py_ret, 1, at_names); if (a->at_desc) { PyList_SetItem(py_ret, 2, PyUnicode_FromString(a->at_desc)); } else { PyList_SetItem(py_ret, 2, PyUnicode_FromString("")); } PyList_SetItem(py_ret, 3, PyInt_FromLong(a->at_obsolete)); if (a->at_sup_oid) { PyList_SetItem(py_ret, 4, PyUnicode_FromString(a->at_sup_oid)); } else { PyList_SetItem(py_ret, 4, PyUnicode_FromString("")); } if (a->at_equality_oid) { PyList_SetItem(py_ret, 5, PyUnicode_FromString(a->at_equality_oid)); } else { PyList_SetItem(py_ret, 5, PyUnicode_FromString("")); } if (a->at_ordering_oid) { PyList_SetItem(py_ret, 6, PyUnicode_FromString(a->at_ordering_oid)); } else { PyList_SetItem(py_ret, 6, PyUnicode_FromString("")); } if (a->at_substr_oid) { PyList_SetItem(py_ret, 7, PyUnicode_FromString(a->at_substr_oid)); } else { PyList_SetItem(py_ret, 7, PyUnicode_FromString("")); } if (a->at_syntax_oid) { PyList_SetItem(py_ret, 8, PyUnicode_FromString(a->at_syntax_oid)); } else { PyList_SetItem(py_ret, 8, PyUnicode_FromString("")); } PyList_SetItem(py_ret, 9, PyInt_FromLong(a->at_syntax_len)); PyList_SetItem(py_ret,10, PyInt_FromLong(a->at_single_value)); PyList_SetItem(py_ret,11, PyInt_FromLong(a->at_collective)); PyList_SetItem(py_ret,12, PyInt_FromLong(a->at_no_user_mod)); PyList_SetItem(py_ret,13, PyInt_FromLong(a->at_usage)); PyList_SetItem(py_ret, 14, schema_extension_to_python(a->at_extensions)); ldap_attributetype_free(a); return py_ret; } static char doc_ldap_str2syntax[] = ""; static PyObject* l_ldap_str2syntax(PyObject* self, PyObject *args) { LDAPSyntax *s; int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE; const char *errp; char *syn_string; PyObject *py_ret, *syn_names; if (!PyArg_ParseTuple(args, "si", &syn_string,&flag)) return NULL; s = ldap_str2syntax(syn_string, &ret, &errp, flag); if (ret) { py_ret = PyInt_FromLong(ret); return py_ret; } py_ret = PyList_New(4); PyList_SetItem(py_ret, 0, PyUnicode_FromString(s->syn_oid)); syn_names = c_string_array_to_python(s->syn_names); PyList_SetItem(py_ret, 1, syn_names); if (s->syn_desc) { PyList_SetItem(py_ret, 2, PyUnicode_FromString(s->syn_desc)); } else { PyList_SetItem(py_ret, 2, PyUnicode_FromString("")); } PyList_SetItem(py_ret, 3, schema_extension_to_python(s->syn_extensions)); ldap_syntax_free(s); return py_ret; } static char doc_ldap_str2matchingrule[] = ""; static PyObject* l_ldap_str2matchingrule(PyObject* self, PyObject *args) { LDAPMatchingRule *m; int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE; const char *errp; char *mr_string; PyObject *py_ret, *mr_names; if (!PyArg_ParseTuple(args, "si", &mr_string,&flag)) return NULL; m = ldap_str2matchingrule(mr_string, &ret, &errp, flag); if (ret) { py_ret = PyInt_FromLong(ret); return py_ret; } py_ret = PyList_New(6); PyList_SetItem(py_ret, 0, PyUnicode_FromString(m->mr_oid)); mr_names = c_string_array_to_python(m->mr_names); PyList_SetItem(py_ret, 1, mr_names); if (m->mr_desc) { PyList_SetItem(py_ret, 2, PyUnicode_FromString(m->mr_desc)); } else { PyList_SetItem(py_ret, 2, PyUnicode_FromString("")); } PyList_SetItem(py_ret, 3, PyInt_FromLong(m->mr_obsolete)); if (m->mr_syntax_oid) { PyList_SetItem(py_ret, 4, PyUnicode_FromString(m->mr_syntax_oid)); } else { PyList_SetItem(py_ret, 4, PyUnicode_FromString("")); } PyList_SetItem(py_ret, 5, schema_extension_to_python(m->mr_extensions)); ldap_matchingrule_free(m); return py_ret; } /* methods */ static PyMethodDef methods[] = { { "str2objectclass", (PyCFunction)l_ldap_str2objectclass, METH_VARARGS, doc_ldap_str2objectclass }, { "str2attributetype", (PyCFunction)l_ldap_str2attributetype, METH_VARARGS, doc_ldap_str2attributetype }, { "str2syntax", (PyCFunction)l_ldap_str2syntax, METH_VARARGS, doc_ldap_str2syntax }, { "str2matchingrule", (PyCFunction)l_ldap_str2matchingrule, METH_VARARGS, doc_ldap_str2matchingrule }, { NULL, NULL } }; void LDAPinit_schema( PyObject* d ) { LDAPadd_methods( d, methods ); }