Beispiel #1
0
/*	Close connection. */
static PyObject *
LDAPConnection_Close(LDAPConnection *self) {
	int rc;

	rc = _LDAP_unbind(self->ld);
	if (rc != LDAP_SUCCESS) {
		PyObject *ldaperror = get_error_by_code(rc);
		PyErr_SetString(ldaperror, ldap_err2string(rc));
		Py_DECREF(ldaperror);
		return NULL;
	}
	return Py_None;
}
Beispiel #2
0
/*	Delete an entry with the `dnstr` distinguished name on the server. */
int
LDAPConnection_DelEntryStringDN(LDAPConnection *self, char *dnstr) {
	int rc = LDAP_SUCCESS;

	if (dnstr != NULL) {
		rc = ldap_delete_ext_s(self->ld, dnstr, NULL, NULL);
		if (rc != LDAP_SUCCESS) {
			PyObject *ldaperror = get_error_by_code(rc);
			PyErr_SetString(ldaperror, ldap_err2string(rc));
			Py_DECREF(ldaperror);
			return -1;
		}
	}
	return 0;
}
Beispiel #3
0
static PyObject *
LDAPConnection_Whoami(LDAPConnection *self) {
	int rc = -1;
	struct berval *authzid = NULL;

	rc = ldap_whoami_s(self->ld, &authzid, NULL, NULL);
	if (rc != LDAP_SUCCESS) {
		PyObject *ldaperror = get_error_by_code(rc);
		PyErr_SetString(ldaperror, ldap_err2string(rc));
		Py_DECREF(ldaperror);
		return NULL;
	}

	if (authzid == NULL) return PyUnicode_FromString("anonym");

	if(authzid->bv_len == 0) {
		authzid->bv_val = "anonym";
		authzid->bv_len = 6;
	}
	return PyUnicode_FromString(authzid->bv_val);
}
Beispiel #4
0
/* Check on the initialisation thread and set cert policy. The `misc`
   parameter is never used (on Linux platform). The pointer of initialised
   LDAP struct is passed to the `ld` parameter. Return 1 if the initialisation
   thread is finished, 0 if it is still in progress, and -1 for error. */
int
_ldap_finish_init_thread(char async, XTHREAD thread, int *timeout, void *misc, LDAP **ld) {
    int rc = 0;
    ldapInitThreadData *val = (ldapInitThreadData *)misc;
    struct timespec ts;
    struct timeval now;
    struct timespec rest;
    int wait_msec = 100;
    long long nanosecs = 0;
    unsigned long long start_time, end_time;
    int retval = 0;

    /* Sanity check. */
    if (val == NULL) return -1;

    DEBUG("_ldap_finish_init_thread (async:%d, thread:%lu, timeout:%d, misc:%p)",
            async, thread, *timeout, misc);
    if (async || *timeout == -1) {
        wait_msec = 100;
    } else {
        wait_msec = *timeout;
    }

    /* Create absolute time. */
    rc = gettimeofday(&now, NULL);
    if (rc != 0) {
        PyErr_BadInternalCall();
        retval = -1;
        goto end;
    }
    ts.tv_sec = now.tv_sec;
    nanosecs = (now.tv_usec + 1000UL * wait_msec) * 1000UL;
    while (nanosecs >= 1000000000) {
        /* Nanosecs are over 1 second. */
        ts.tv_sec += 1;
        nanosecs -= 1000000000;
    }
    ts.tv_nsec = (long)nanosecs;

    /* Waiting on thread to release the lock. */
    rc = _pthread_mutex_timedlock(val->mux, &ts);

    switch (rc) {
    case ETIMEDOUT:
        if (async == 0 && *timeout != -1) {
            pthread_cancel(thread);
            set_exception(NULL, LDAP_TIMEOUT);
            free(val->ld);
            retval = -1;
            goto end;
        }
        return 0;
    case 0:
        if (val->flag == 0) {
            /* Premature locking, thread function is not finished. */
            pthread_mutex_unlock(val->mux);
            /* Set 5ms for sleeping time. */
            rest.tv_sec = 0;
            rest.tv_nsec = 5000000;
            /* Take a nap, try to avoid constantly locking from the main thread. */
            nanosleep(&rest, NULL);
            if (*timeout != -1) {
                *timeout -= 5;
                if (*timeout < 0) *timeout = 0;
            }
            return 0;
        }
        /* Block until thread is finished, but if it's async already
           waited enough on releasing the lock. */
        rc = pthread_join(thread, NULL);
        /* Thread is finished. */
        if (val->retval != LDAP_SUCCESS) {
#ifdef HAVE_KRB5
            if (val->info->errmsg != NULL) {
                PyObject *error = get_error_by_code(0x31);
                if (error == NULL) goto end;
                PyErr_SetString(error, val->info->errmsg);
                Py_DECREF(error);
            } else {
                set_exception(NULL, val->retval);
            }
#else
            set_exception(NULL, val->retval);
#endif
            free(val->ld);
            retval = -1;
            goto end;
        }
        if (*timeout != -1) {
            /* Calculate passed time in milliseconds. */
            start_time = (unsigned long long)(now.tv_sec) * 1000
                    + (unsigned long long)(now.tv_usec) / 1000;

            gettimeofday(&now, NULL);
            end_time = (unsigned long long)(now.tv_sec) * 1000
                            + (unsigned long long)(now.tv_usec) / 1000;
            /* Deduct the passed time from the overall timeout. */
            *timeout -= (end_time - start_time);
            if (*timeout < 0) *timeout = 0;
        }
        /* Set initialised LDAP struct pointer. */
        *ld = val->ld;
        retval = 1;
        goto end;
    default:
        /* The thread is failed. */
        PyErr_BadInternalCall();
        retval = -1;
        goto end;
    }
end:
    /* Clean-up. */
    free(val->url);
    pthread_mutex_destroy(val->mux);
    free(val->mux);
    free(val);
    return retval;
}
Beispiel #5
0
/*	Opens a connection to the LDAP server. Initializes LDAP structure.
	If TLS is true, starts TLS session.
*/
static int
connecting(LDAPConnection *self) {
	int rc = -1;
	int tls_option = -1;
	char *binddn = NULL;
	char *pswstr = NULL;
	char *mech = NULL;
	char *authzid = "";
	char *realm = NULL;
	char *authcid = NULL;
	PyObject *url = NULL;
	PyObject *tls = NULL;
	PyObject *tmp = NULL;
	PyObject *creds = NULL;

	url = PyObject_GetAttrString(self->client, "_LDAPClient__url");
	if (url == NULL) return -1;

	tmp = PyObject_GetAttrString(self->client, "_LDAPClient__cert_policy");
	tls_option = (int)PyLong_AsLong(tmp);
	Py_DECREF(tmp);

	rc = _LDAP_initialization(&(self->ld), url, tls_option);
	Py_DECREF(url);

	if (rc != LDAP_SUCCESS) {
		PyObject *ldaperror = get_error_by_code(rc);
		PyErr_SetString(ldaperror, ldap_err2string(rc));
		Py_DECREF(ldaperror);
		return -1;
	}

	tls = PyObject_GetAttrString(self->client, "_LDAPClient__tls");
	if (tls == NULL) return -1;

	/* Start TLS, if it necessary. */
	if (PyObject_IsTrue(tls)) {
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
		rc = ldap_start_tls_sA(self->ld, NULL, NULL, NULL, NULL);
#else
		rc = ldap_start_tls_s(self->ld, NULL, NULL);
#endif
		if (rc != LDAP_SUCCESS) {
			//TODO Proper errors
			PyObject *ldaperror = get_error_by_code(rc);
			PyErr_SetString(ldaperror, ldap_err2string(rc));
			Py_DECREF(ldaperror);
			Py_DECREF(tls);
			return -1;
		}
	}
	Py_DECREF(tls);

	creds = PyObject_GetAttrString(self->client, "_LDAPClient__credentials");
	if (creds == NULL) return -1;

	tmp = PyObject_GetAttrString(self->client, "_LDAPClient__mechanism");
	if (tmp == NULL) return -1;
	mech = PyObject2char(tmp);
	Py_XDECREF(tmp);

	/* Get credential information, if it's given. */
	if (PyTuple_Check(creds) && PyTuple_Size(creds) > 1) {
		if (strcmp(mech, "SIMPLE") == 0) {
			tmp = PyTuple_GetItem(creds, 0);
			binddn = PyObject2char(tmp);
		} else {
			tmp = PyTuple_GetItem(creds, 0);
			authcid = PyObject2char(tmp);
			tmp = PyDict_GetItemString(creds, "realm");
			realm = PyObject2char(tmp);
		}
		tmp = PyTuple_GetItem(creds, 1);
		pswstr = PyObject2char(tmp);
	}

	if (authzid == NULL) authzid = "";

	rc = _LDAP_bind_s(self->ld, mech, binddn, pswstr, authcid, realm, authzid);

	free(mech);
	free(binddn);
	free(pswstr);
	free(authcid);
	free(realm);
	if (strcmp(authzid, "") != 0) free(authzid);

	if (rc != LDAP_SUCCESS) {
		PyObject *ldaperror = get_error_by_code(rc);
		PyErr_SetString(ldaperror, ldap_err2string(rc));
		Py_DECREF(ldaperror);
		Py_DECREF(creds);
		return -1;
	}
	Py_DECREF(creds);

	return 0;
}
Beispiel #6
0
/*	LDAP search function for internal use. Returns a Python list of LDAPEntries.
	The `basestr` is the base DN of the searching, `scope` is the search scope (BASE|ONELEVEL|SUB),
	`filterstr` is the LDAP search filter string, `attrs` is a null-terminated string list of attributes'
	names to get only the selected attributes. If `attrsonly` is 1 get only attributes' name without values.
	If `firstonly` is 1, get only the first LDAP entry of the messages. The `timeout` is an integer of
	seconds for timelimit, `sizelimit` is a limit for size.
*/
PyObject *
LDAPConnection_Searching(LDAPConnection *self, PyObject *iterator) {
	int rc;
	int num_of_ctrls = 0;
	LDAPMessage *res, *entry;
	PyObject *entrylist = NULL;
	LDAPEntry *entryobj = NULL;
	LDAPControl *page_ctrl = NULL;
	LDAPControl *sort_ctrl = NULL;
	LDAPControl **server_ctrls = NULL;
	LDAPControl **returned_ctrls = NULL;
	LDAPSearchIter *search_iter = (LDAPSearchIter *)iterator;

	entrylist = PyList_New(0);
	if (entrylist == NULL) {
		return PyErr_NoMemory();
	}

	/* Check the number of server controls and allocate it. */
	if (self->page_size > 1) num_of_ctrls++;
	if (self->sort_list != NULL) num_of_ctrls++;
	if (num_of_ctrls > 0) {
		server_ctrls = (LDAPControl **)malloc(sizeof(LDAPControl *)
				* (num_of_ctrls + 1));
		if (server_ctrls == NULL) return PyErr_NoMemory();
		num_of_ctrls = 0;
	}

	if (self->page_size > 1) {
		/* Create page control and add to the server controls. */
		rc = ldap_create_page_control(self->ld, (ber_int_t)(self->page_size),
				search_iter->cookie, 0, &page_ctrl);
		if (rc != LDAP_SUCCESS) {
			PyErr_BadInternalCall();
			return NULL;
		}
		server_ctrls[num_of_ctrls++] = page_ctrl;
		server_ctrls[num_of_ctrls] = NULL;
	}

	if (self->sort_list != NULL) {
		rc = ldap_create_sort_control(self->ld, self->sort_list, 0, &sort_ctrl);
		if (rc != LDAP_SUCCESS) {
			PyErr_BadInternalCall();
			return NULL;
		}
		server_ctrls[num_of_ctrls++] = sort_ctrl;
		server_ctrls[num_of_ctrls] = NULL;
	}

	rc = ldap_search_ext_s(self->ld, search_iter->base,
				search_iter->scope,
				search_iter->filter,
				search_iter->attrs,
				search_iter->attrsonly,
				server_ctrls, NULL,
				search_iter->timeout,
				search_iter->sizelimit, &res);

	if (rc == LDAP_NO_SUCH_OBJECT) {
		return entrylist;
	}
	if (rc != LDAP_SUCCESS  && rc != LDAP_PARTIAL_RESULTS) {
		Py_DECREF(entrylist);
		PyObject *ldaperror = get_error_by_code(rc);
		PyErr_SetString(ldaperror, ldap_err2string(rc));
		Py_DECREF(ldaperror);
        return NULL;
	}

	rc = ldap_parse_result(self->ld, res, NULL, NULL, NULL, NULL, &returned_ctrls, 0);
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)

	if (search_iter->cookie != NULL && search_iter->cookie->bv_val != NULL) {
    	ber_bvfree(search_iter->cookie);
    	search_iter->cookie = NULL;
    }
    rc = ldap_parse_page_control(self->ld, returned_ctrls, NULL, &(search_iter->cookie));
#else
	rc = ldap_parse_pageresponse_control(self->ld,
			ldap_control_find(LDAP_CONTROL_PAGEDRESULTS, returned_ctrls, NULL),
			NULL, search_iter->cookie);
#endif
	/* Iterate over the response LDAP messages. */
	for (entry = ldap_first_entry(self->ld, res);
		entry != NULL;
		entry = ldap_next_entry(self->ld, entry)) {
		entryobj = LDAPEntry_FromLDAPMessage(entry, self);
		if (entryobj == NULL) {
			Py_DECREF(entrylist);
			return NULL;
		}
		if ((entryobj == NULL) ||
				(PyList_Append(entrylist, (PyObject *)entryobj)) != 0) {
			Py_XDECREF(entryobj);
			Py_DECREF(entrylist);
			return PyErr_NoMemory();
		}
		Py_DECREF(entryobj);
	}
	/* Cleanup. */
	if (returned_ctrls != NULL) ldap_controls_free(returned_ctrls);
	if (page_ctrl != NULL) ldap_control_free(page_ctrl);
	if (sort_ctrl != NULL) ldap_control_free(sort_ctrl);
	if (server_ctrls != NULL) free(server_ctrls);

	ldap_msgfree(res);
	return entrylist;
}