| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- /* See http://www.python-ldap.org/ for details.
- * $Id: options.c,v 1.38 2010/10/01 18:23:18 stroeder Exp $ */
- #include "common.h"
- #include "errors.h"
- #include "LDAPObject.h"
- #include "ldapcontrol.h"
- #include "options.h"
- void
- set_timeval_from_double( struct timeval *tv, double d ) {
- tv->tv_usec = (long) ( fmod(d, 1.0) * 1000000.0 );
- tv->tv_sec = (long) floor(d);
- }
- /**
- * Converts a return code from ldap_set_option() or ldap_get_option()
- * into a python error, and returns NULL.
- */
- static PyObject *
- option_error(int res, const char *fn)
- {
- if (res == LDAP_OPT_ERROR)
- PyErr_SetString(PyExc_ValueError, "option error");
- else if (res == LDAP_PARAM_ERROR)
- PyErr_SetString(PyExc_ValueError, "parameter error");
- else if (res == LDAP_NO_MEMORY)
- PyErr_NoMemory();
- else
- PyErr_Format(PyExc_SystemError, "error %d from %s", res, fn);
- return NULL;
- }
- /**
- * Sets an LDAP option.
- * Returns 0 on failure, 1 on success
- */
- int
- LDAP_set_option(LDAPObject *self, int option, PyObject *value)
- {
- int res;
- int intval;
- double doubleval;
- char *strval;
- struct timeval tv;
- void *ptr;
- LDAP *ld;
- LDAPControl **controls = NULL;
- ld = self ? self->ldap : NULL;
- switch(option) {
- case LDAP_OPT_API_INFO:
- case LDAP_OPT_API_FEATURE_INFO:
- #ifdef HAVE_SASL
- case LDAP_OPT_X_SASL_SSF:
- #endif
- /* Read-only options */
- PyErr_SetString(PyExc_ValueError, "read-only option");
- return 0;
- case LDAP_OPT_REFERRALS:
- case LDAP_OPT_RESTART:
- #ifdef LDAP_OPT_X_SASL_NOCANON
- case LDAP_OPT_X_SASL_NOCANON:
- #endif
- #ifdef LDAP_OPT_CONNECT_ASYNC
- case LDAP_OPT_CONNECT_ASYNC:
- #endif
- /* Truth-value options */
- ptr = PyObject_IsTrue(value) ? LDAP_OPT_ON : LDAP_OPT_OFF;
- break;
- case LDAP_OPT_DEREF:
- case LDAP_OPT_SIZELIMIT:
- case LDAP_OPT_TIMELIMIT:
- case LDAP_OPT_PROTOCOL_VERSION:
- case LDAP_OPT_ERROR_NUMBER:
- case LDAP_OPT_DEBUG_LEVEL:
- #ifdef HAVE_TLS
- case LDAP_OPT_X_TLS:
- case LDAP_OPT_X_TLS_REQUIRE_CERT:
- #ifdef LDAP_OPT_X_TLS_CRLCHECK
- case LDAP_OPT_X_TLS_CRLCHECK:
- #endif
- #ifdef LDAP_OPT_X_TLS_NEWCTX
- case LDAP_OPT_X_TLS_NEWCTX:
- #endif
- #ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
- case LDAP_OPT_X_TLS_PROTOCOL_MIN:
- #endif
- #endif
- #ifdef HAVE_SASL
- case LDAP_OPT_X_SASL_SSF_MIN:
- case LDAP_OPT_X_SASL_SSF_MAX:
- #endif
- #ifdef LDAP_OPT_X_KEEPALIVE_IDLE
- case LDAP_OPT_X_KEEPALIVE_IDLE:
- #endif
- #ifdef LDAP_OPT_X_KEEPALIVE_PROBES
- case LDAP_OPT_X_KEEPALIVE_PROBES:
- #endif
- #ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
- case LDAP_OPT_X_KEEPALIVE_INTERVAL:
- #endif
- /* integer value options */
- if (!PyArg_Parse(value, "i:set_option", &intval))
- return 0;
- ptr = &intval;
- break;
- case LDAP_OPT_HOST_NAME:
- case LDAP_OPT_URI:
- #ifdef LDAP_OPT_DEFBASE
- case LDAP_OPT_DEFBASE:
- #endif
- case LDAP_OPT_ERROR_STRING:
- case LDAP_OPT_MATCHED_DN:
- #ifdef HAVE_TLS
- case LDAP_OPT_X_TLS_CACERTFILE:
- case LDAP_OPT_X_TLS_CACERTDIR:
- case LDAP_OPT_X_TLS_CERTFILE:
- case LDAP_OPT_X_TLS_KEYFILE:
- case LDAP_OPT_X_TLS_CIPHER_SUITE:
- case LDAP_OPT_X_TLS_RANDOM_FILE:
- case LDAP_OPT_X_TLS_DHFILE:
- #ifdef LDAP_OPT_X_TLS_CRLFILE
- case LDAP_OPT_X_TLS_CRLFILE:
- #endif
- #endif
- #ifdef HAVE_SASL
- case LDAP_OPT_X_SASL_SECPROPS:
- #endif
- /* String valued options */
- if (!PyArg_Parse(value, "s:set_option", &strval))
- return 0;
- ptr = strval;
- break;
- case LDAP_OPT_TIMEOUT:
- case LDAP_OPT_NETWORK_TIMEOUT:
- /* Float valued timeval options */
- if (!PyArg_Parse(value, "d:set_option", &doubleval))
- return 0;
- if (doubleval >= 0) {
- set_timeval_from_double( &tv, doubleval );
- ptr = &tv;
- } else {
- ptr = NULL;
- }
- break;
- case LDAP_OPT_SERVER_CONTROLS:
- case LDAP_OPT_CLIENT_CONTROLS:
- if (!LDAPControls_from_object(value, &controls))
- return 0;
- ptr = controls;
- break;
- default:
- PyErr_Format(PyExc_ValueError, "unknown option %d", option);
- return 0;
- }
-
- if (self) LDAP_BEGIN_ALLOW_THREADS(self);
- res = ldap_set_option(ld, option, ptr);
- if (self) LDAP_END_ALLOW_THREADS(self);
- if ((option == LDAP_OPT_SERVER_CONTROLS) || (option == LDAP_OPT_CLIENT_CONTROLS))
- LDAPControl_List_DEL(controls);
-
- if (res != LDAP_OPT_SUCCESS) {
- option_error(res, "ldap_set_option");
- return 0;
- }
- return 1;
- }
- PyObject *
- LDAP_get_option(LDAPObject *self, int option)
- {
- int res;
- int intval;
- struct timeval *tv;
- LDAPAPIInfo apiinfo;
- LDAPControl **lcs;
- LDAPControl *lc;
- char *strval;
- PyObject *extensions, *v, *tup;
- Py_ssize_t i, num_extensions, num_controls;
- LDAP *ld;
- ld = self ? self->ldap : NULL;
- switch(option) {
- case LDAP_OPT_API_INFO:
- apiinfo.ldapai_info_version = LDAP_API_INFO_VERSION;
- if (self) LDAP_BEGIN_ALLOW_THREADS(self);
- res = ldap_get_option( ld, option, &apiinfo );
- if (self) LDAP_END_ALLOW_THREADS(self);
- if (res != LDAP_OPT_SUCCESS)
- return option_error(res, "ldap_get_option");
-
- /* put the extensions into tuple form */
- num_extensions = 0;
- while (apiinfo.ldapai_extensions[num_extensions])
- num_extensions++;
- extensions = PyTuple_New(num_extensions);
- for (i = 0; i < num_extensions; i++)
- PyTuple_SET_ITEM(extensions, i,
- PyString_FromString(apiinfo.ldapai_extensions[i]));
- /* return api info as a dictionary */
- v = Py_BuildValue("{s:i, s:i, s:i, s:s, s:i, s:O}",
- "info_version", apiinfo.ldapai_info_version,
- "api_version", apiinfo.ldapai_api_version,
- "protocol_version", apiinfo.ldapai_protocol_version,
- "vendor_name", apiinfo.ldapai_vendor_name,
- "vendor_version", apiinfo.ldapai_vendor_version,
- "extensions", extensions);
- if (apiinfo.ldapai_vendor_name)
- ldap_memfree(apiinfo.ldapai_vendor_name);
- for (i = 0; i < num_extensions; i++)
- ldap_memfree(apiinfo.ldapai_extensions[i]);
- ldap_memfree(apiinfo.ldapai_extensions);
- Py_DECREF(extensions);
- return v;
- #ifdef HAVE_SASL
- case LDAP_OPT_X_SASL_SSF:
- #endif
- case LDAP_OPT_REFERRALS:
- case LDAP_OPT_RESTART:
- case LDAP_OPT_DEREF:
- case LDAP_OPT_SIZELIMIT:
- case LDAP_OPT_TIMELIMIT:
- case LDAP_OPT_PROTOCOL_VERSION:
- case LDAP_OPT_ERROR_NUMBER:
- case LDAP_OPT_DEBUG_LEVEL:
- #ifdef HAVE_TLS
- case LDAP_OPT_X_TLS:
- case LDAP_OPT_X_TLS_REQUIRE_CERT:
- #ifdef LDAP_OPT_X_TLS_CRLCHECK
- case LDAP_OPT_X_TLS_CRLCHECK:
- #endif
- #ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
- case LDAP_OPT_X_TLS_PROTOCOL_MIN:
- #endif
- #endif
- #ifdef HAVE_SASL
- case LDAP_OPT_X_SASL_SSF_MIN:
- case LDAP_OPT_X_SASL_SSF_MAX:
- #endif
- #ifdef LDAP_OPT_X_SASL_NOCANON
- case LDAP_OPT_X_SASL_NOCANON:
- #endif
- #ifdef LDAP_OPT_CONNECT_ASYNC
- case LDAP_OPT_CONNECT_ASYNC:
- #endif
- #ifdef LDAP_OPT_X_KEEPALIVE_IDLE
- case LDAP_OPT_X_KEEPALIVE_IDLE:
- #endif
- #ifdef LDAP_OPT_X_KEEPALIVE_PROBES
- case LDAP_OPT_X_KEEPALIVE_PROBES:
- #endif
- #ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
- case LDAP_OPT_X_KEEPALIVE_INTERVAL:
- #endif
- /* Integer-valued options */
- if (self) LDAP_BEGIN_ALLOW_THREADS(self);
- res = ldap_get_option(ld, option, &intval);
- if (self) LDAP_END_ALLOW_THREADS(self);
- if (res != LDAP_OPT_SUCCESS)
- return option_error(res, "ldap_get_option");
- return PyInt_FromLong(intval);
- case LDAP_OPT_HOST_NAME:
- case LDAP_OPT_URI:
- #ifdef LDAP_OPT_DEFBASE
- case LDAP_OPT_DEFBASE:
- #endif
- case LDAP_OPT_ERROR_STRING:
- case LDAP_OPT_MATCHED_DN:
- #ifdef HAVE_TLS
- case LDAP_OPT_X_TLS_CACERTFILE:
- case LDAP_OPT_X_TLS_CACERTDIR:
- case LDAP_OPT_X_TLS_CERTFILE:
- case LDAP_OPT_X_TLS_KEYFILE:
- case LDAP_OPT_X_TLS_CIPHER_SUITE:
- case LDAP_OPT_X_TLS_RANDOM_FILE:
- case LDAP_OPT_X_TLS_DHFILE:
- #ifdef LDAP_OPT_X_TLS_CRLFILE
- case LDAP_OPT_X_TLS_CRLFILE:
- #endif
- #endif
- #ifdef HAVE_SASL
- case LDAP_OPT_X_SASL_SECPROPS:
- case LDAP_OPT_X_SASL_MECH:
- case LDAP_OPT_X_SASL_REALM:
- case LDAP_OPT_X_SASL_AUTHCID:
- case LDAP_OPT_X_SASL_AUTHZID:
- #ifdef LDAP_OPT_X_SASL_USERNAME
- case LDAP_OPT_X_SASL_USERNAME:
- #endif
- #endif
- /* String-valued options */
- if (self) LDAP_BEGIN_ALLOW_THREADS(self);
- res = ldap_get_option(ld, option, &strval);
- if (self) LDAP_END_ALLOW_THREADS(self);
- if (res != LDAP_OPT_SUCCESS)
- return option_error(res, "ldap_get_option");
- if (strval == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- v = PyString_FromString(strval);
- ldap_memfree(strval);
- return v;
- case LDAP_OPT_TIMEOUT:
- case LDAP_OPT_NETWORK_TIMEOUT:
- /* Double-valued timeval options */
- if (self) LDAP_BEGIN_ALLOW_THREADS(self);
- res = ldap_get_option(ld, option, &tv);
- if (self) LDAP_END_ALLOW_THREADS(self);
- if (res != LDAP_OPT_SUCCESS)
- return option_error(res, "ldap_get_option");
- if (tv == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- v = PyFloat_FromDouble(
- (double) tv->tv_sec + ( (double) tv->tv_usec / 1000000.0 )
- );
- ldap_memfree(tv);
- return v;
- case LDAP_OPT_SERVER_CONTROLS:
- case LDAP_OPT_CLIENT_CONTROLS:
- if (self) LDAP_BEGIN_ALLOW_THREADS(self);
- res = ldap_get_option(ld, option, &lcs);
- if (self) LDAP_END_ALLOW_THREADS(self);
- if (res != LDAP_OPT_SUCCESS)
- return option_error(res, "ldap_get_option");
- if (lcs == NULL)
- return PyList_New(0);
-
- /* Get the number of controls */
- num_controls = 0;
- while (lcs[num_controls])
- num_controls++;
- /* We'll build a list of controls, with each control a tuple */
- v = PyList_New(num_controls);
- for (i = 0; i < num_controls; i++) {
- lc = lcs[i];
- tup = Py_BuildValue("(sbs)",
- lc->ldctl_oid,
- lc->ldctl_iscritical,
- lc->ldctl_value.bv_val);
- PyList_SET_ITEM(v, i, tup);
- }
-
- ldap_controls_free(lcs);
- return v;
-
- default:
- PyErr_Format(PyExc_ValueError, "unknown option %d", option);
- return NULL;
- }
- }
|