summaryrefslogtreecommitdiff
path: root/source4/libcli/ldap/ldap.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-11-06 20:15:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:35 -0500
commit8408b3428d8c263f8453a0da8ef71e7fc1e4ec81 (patch)
tree4c8b4a7686f730333fdf137c28166c7c561414b0 /source4/libcli/ldap/ldap.c
parenteee5cc3b9a6fe7cdc1fa81fac8ce524391bee519 (diff)
downloadsamba-8408b3428d8c263f8453a0da8ef71e7fc1e4ec81.tar.gz
samba-8408b3428d8c263f8453a0da8ef71e7fc1e4ec81.tar.bz2
samba-8408b3428d8c263f8453a0da8ef71e7fc1e4ec81.zip
r3583: - seperate the ldap client code and the ldap parsing code
(vl: we should only sync the parsing code with trunk) - use hierachical talloc in the ldap client code metze (This used to be commit 1e9c0b68ca9ddb28877d45fc1b47653b13a7446d)
Diffstat (limited to 'source4/libcli/ldap/ldap.c')
-rw-r--r--source4/libcli/ldap/ldap.c655
1 files changed, 3 insertions, 652 deletions
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c
index 6d2cef8bdb..315241e5b1 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap.c
@@ -24,11 +24,8 @@
*/
#include "includes.h"
-#include "system/network.h"
#include "system/iconv.h"
-#include "auth/auth.h"
#include "asn_1.h"
-#include "dlinklist.h"
/****************************************************************************
*
@@ -1218,8 +1215,8 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url,
char **host, uint16 *port, BOOL *ldaps)
{
int tmp_port = 0;
- fstring protocol;
- fstring tmp_host;
+ char protocol[11];
+ char tmp_host[255];
const char *p = url;
/* skip leading "URL:" (if any) */
@@ -1245,654 +1242,8 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url,
if (tmp_port != 0)
*port = tmp_port;
-
+
*host = talloc_strdup(mem_ctx, tmp_host);
return (*host != NULL);
}
-
-struct ldap_connection *new_ldap_connection(void)
-{
- TALLOC_CTX *mem_ctx = talloc_init("ldap_connection");
- struct ldap_connection *result;
-
- if (mem_ctx == NULL)
- return NULL;
-
- result = talloc(mem_ctx, sizeof(*result));
-
- if (result == NULL)
- return NULL;
-
- result->mem_ctx = mem_ctx;
- result->next_msgid = 1;
- result->outstanding = NULL;
- result->searchid = 0;
- result->search_entries = NULL;
- result->auth_dn = NULL;
- result->simple_pw = NULL;
- result->gensec = NULL;
-
- return result;
-}
-
-BOOL ldap_connect(struct ldap_connection *conn, const char *url)
-{
- struct hostent *hp;
- struct ipv4_addr ip;
-
- if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host,
- &conn->port, &conn->ldaps))
- return False;
-
- hp = sys_gethostbyname(conn->host);
-
- if ((hp == NULL) || (hp->h_addr == NULL))
- return False;
-
- putip((char *)&ip, (char *)hp->h_addr);
-
- conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT);
-
- return (conn->sock >= 0);
-}
-
-BOOL ldap_set_simple_creds(struct ldap_connection *conn,
- const char *dn, const char *password)
-{
- conn->auth_dn = talloc_strdup(conn->mem_ctx, dn);
- conn->simple_pw = talloc_strdup(conn->mem_ctx, password);
-
- return ((conn->auth_dn != NULL) && (conn->simple_pw != NULL));
-}
-
-struct ldap_message *new_ldap_message(void)
-{
- TALLOC_CTX *mem_ctx = talloc_init("ldap_message");
- struct ldap_message *result;
-
- if (mem_ctx == NULL)
- return NULL;
-
- result = talloc(mem_ctx, sizeof(*result));
-
- if (result == NULL)
- return NULL;
-
- result->mem_ctx = mem_ctx;
- return result;
-}
-
-void destroy_ldap_message(struct ldap_message *msg)
-{
- if (msg != NULL)
- talloc_destroy(msg->mem_ctx);
-}
-
-BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
- const struct timeval *endtime)
-{
- DATA_BLOB request;
- BOOL result;
- struct ldap_queue_entry *entry;
-
- msg->messageid = conn->next_msgid++;
-
- if (!ldap_encode(msg, &request))
- return False;
-
- result = (write_data_until(conn->sock, request.data, request.length,
- endtime) == request.length);
-
- data_blob_free(&request);
-
- if (!result)
- return result;
-
- /* abandon and unbind don't expect results */
-
- if ((msg->type == LDAP_TAG_AbandonRequest) ||
- (msg->type == LDAP_TAG_UnbindRequest))
- return True;
-
- entry = malloc(sizeof(*entry));
-
- if (entry == NULL)
- return False;
-
- entry->msgid = msg->messageid;
- entry->msg = NULL;
- DLIST_ADD(conn->outstanding, entry);
-
- return True;
-}
-
-BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg,
- const struct timeval *endtime)
-{
- struct asn1_data data;
- BOOL result;
-
- if (!asn1_read_sequence_until(conn->sock, &data, endtime))
- return False;
-
- result = ldap_decode(&data, msg);
-
- asn1_free(&data);
- return result;
-}
-
-static struct ldap_message *recv_from_queue(struct ldap_connection *conn,
- int msgid)
-{
- struct ldap_queue_entry *e;
-
- for (e = conn->outstanding; e != NULL; e = e->next) {
-
- if (e->msgid == msgid) {
- struct ldap_message *result = e->msg;
- DLIST_REMOVE(conn->outstanding, e);
- SAFE_FREE(e);
- return result;
- }
- }
-
- return NULL;
-}
-
-static void add_search_entry(struct ldap_connection *conn,
- struct ldap_message *msg)
-{
- struct ldap_queue_entry *e = malloc(sizeof *e);
-
- if (e == NULL)
- return;
-
- e->msg = msg;
- DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *);
- return;
-}
-
-static void fill_outstanding_request(struct ldap_connection *conn,
- struct ldap_message *msg)
-{
- struct ldap_queue_entry *e;
-
- for (e = conn->outstanding; e != NULL; e = e->next) {
- if (e->msgid == msg->messageid) {
- e->msg = msg;
- return;
- }
- }
-
- /* This reply has not been expected, destroy the incoming msg */
- destroy_ldap_message(msg);
- return;
-}
-
-struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid,
- const struct timeval *endtime)
-{
- struct ldap_message *result = recv_from_queue(conn, msgid);
-
- if (result != NULL)
- return result;
-
- while (True) {
- struct asn1_data data;
- BOOL res;
-
- result = new_ldap_message();
-
- if (!asn1_read_sequence_until(conn->sock, &data, endtime))
- return NULL;
-
- res = ldap_decode(&data, result);
- asn1_free(&data);
-
- if (!res)
- return NULL;
-
- if (result->messageid == msgid)
- return result;
-
- if (result->type == LDAP_TAG_SearchResultEntry) {
- add_search_entry(conn, result);
- } else {
- fill_outstanding_request(conn, result);
- }
- }
-
- return NULL;
-}
-
-struct ldap_message *ldap_transaction(struct ldap_connection *conn,
- struct ldap_message *request)
-{
- if (!ldap_send_msg(conn, request, NULL))
- return False;
-
- return ldap_receive(conn, request->messageid, NULL);
-}
-
-int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password)
-{
- struct ldap_message *response;
- struct ldap_message *msg;
- const char *dn, *pw;
- int result = LDAP_OTHER;
-
- if (conn == NULL)
- return result;
-
- if (userdn) {
- dn = userdn;
- } else {
- if (conn->auth_dn) {
- dn = conn->auth_dn;
- } else {
- dn = "";
- }
- }
-
- if (password) {
- pw = password;
- } else {
- if (conn->simple_pw) {
- pw = conn->simple_pw;
- } else {
- pw = "";
- }
- }
-
- msg = new_ldap_simple_bind_msg(dn, pw);
- if (!msg)
- return result;
-
- response = ldap_transaction(conn, msg);
- if (!response) {
- destroy_ldap_message(msg);
- return result;
- }
-
- result = response->r.BindResponse.response.resultcode;
-
- destroy_ldap_message(msg);
- destroy_ldap_message(response);
-
- return result;
-}
-
-int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password)
-{
- NTSTATUS status;
- TALLOC_CTX *mem_ctx = NULL;
- struct ldap_message *response;
- struct ldap_message *msg;
- DATA_BLOB input = data_blob(NULL, 0);
- DATA_BLOB output = data_blob(NULL, 0);
- int result = LDAP_OTHER;
-
- if (conn == NULL)
- return result;
-
- status = gensec_client_start(conn, &conn->gensec);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status)));
- return result;
- }
-
- gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL);
-
- status = gensec_set_domain(conn->gensec, domain);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n",
- domain, nt_errstr(status)));
- goto done;
- }
-
- status = gensec_set_username(conn->gensec, username);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n",
- username, nt_errstr(status)));
- goto done;
- }
-
- status = gensec_set_password(conn->gensec, password);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC client password: %s\n",
- nt_errstr(status)));
- goto done;
- }
-
- status = gensec_set_target_hostname(conn->gensec, conn->host);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n",
- nt_errstr(status)));
- goto done;
- }
-
- status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO");
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n",
- nt_errstr(status)));
- goto done;
- }
-
- mem_ctx = talloc_init("ldap_bind_sasl");
- if (!mem_ctx)
- goto done;
-
- status = gensec_update(conn->gensec, mem_ctx,
- input,
- &output);
-
- while(1) {
- if (NT_STATUS_IS_OK(status) && output.length == 0) {
- break;
- }
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
- break;
- }
-
- msg = new_ldap_sasl_bind_msg("GSS-SPNEGO", &output);
- if (!msg)
- goto done;
-
- response = ldap_transaction(conn, msg);
- destroy_ldap_message(msg);
-
- if (!response) {
- goto done;
- }
-
- result = response->r.BindResponse.response.resultcode;
-
- if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) {
- break;
- }
-
- status = gensec_update(conn->gensec, mem_ctx,
- response->r.BindResponse.SASL.secblob,
- &output);
-
- destroy_ldap_message(response);
- }
-
-done:
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-BOOL ldap_setup_connection(struct ldap_connection *conn,
- const char *url, const char *userdn, const char *password)
-{
- int result;
-
- if (!ldap_connect(conn, url)) {
- return False;
- }
-
- result = ldap_bind_simple(conn, userdn, password);
- if (result == LDAP_SUCCESS) {
- return True;
- }
-
- return False;
-}
-
-BOOL ldap_setup_connection_with_sasl(struct ldap_connection *conn, const char *url, const char *username, const char *domain, const char *password)
-{
- int result;
-
- if (!ldap_connect(conn, url)) {
- return False;
- }
-
- result = ldap_bind_sasl(conn, username, domain, password);
- if (result == LDAP_SUCCESS) {
- return True;
- }
-
- return False;
-}
-
-static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid,
- const struct timeval *endtime)
-{
- struct ldap_message *msg = new_ldap_message();
- BOOL result;
-
- if (msg == NULL)
- return False;
-
- msg->type = LDAP_TAG_AbandonRequest;
- msg->r.AbandonRequest.messageid = msgid;
-
- result = ldap_send_msg(conn, msg, endtime);
- destroy_ldap_message(msg);
- return result;
-}
-
-struct ldap_message *new_ldap_search_message(const char *base,
- enum ldap_scope scope,
- char *filter,
- int num_attributes,
- const char **attributes)
-{
- struct ldap_message *res = new_ldap_message();
-
- if (res == NULL)
- return NULL;
-
- res->type = LDAP_TAG_SearchRequest;
- res->r.SearchRequest.basedn = base;
- res->r.SearchRequest.scope = scope;
- res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER;
- res->r.SearchRequest.timelimit = 0;
- res->r.SearchRequest.sizelimit = 0;
- res->r.SearchRequest.attributesonly = False;
- res->r.SearchRequest.filter = filter;
- res->r.SearchRequest.num_attributes = num_attributes;
- res->r.SearchRequest.attributes = attributes;
- return res;
-}
-
-struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw)
-{
- struct ldap_message *res = new_ldap_message();
-
- if (res == NULL)
- return NULL;
-
- res->type = LDAP_TAG_BindRequest;
- res->r.BindRequest.version = 3;
- res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn);
- res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE;
- res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw);
- return res;
-}
-
-struct ldap_message *new_ldap_sasl_bind_msg(const char *sasl_mechanism, DATA_BLOB *secblob)
-{
- struct ldap_message *res = new_ldap_message();
-
- if (res == NULL)
- return NULL;
-
- res->type = LDAP_TAG_BindRequest;
- res->r.BindRequest.version = 3;
- res->r.BindRequest.dn = "";
- res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL;
- res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism);
- res->r.BindRequest.creds.SASL.secblob = *secblob;
- return res;
-}
-
-BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg,
- const struct timeval *endtime)
-{
- if ((conn->searchid != 0) &&
- (!ldap_abandon_message(conn, conn->searchid, endtime)))
- return False;
-
- conn->searchid = conn->next_msgid;
- return ldap_send_msg(conn, msg, endtime);
-}
-
-struct ldap_message *ldap_getsearchent(struct ldap_connection *conn,
- const struct timeval *endtime)
-{
- struct ldap_message *result;
-
- if (conn->search_entries != NULL) {
- struct ldap_queue_entry *e = conn->search_entries;
-
- result = e->msg;
- DLIST_REMOVE(conn->search_entries, e);
- SAFE_FREE(e);
- return result;
- }
-
- result = ldap_receive(conn, conn->searchid, endtime);
- if (!result) {
- return NULL;
- }
-
- if (result->type == LDAP_TAG_SearchResultEntry)
- return result;
-
- if (result->type == LDAP_TAG_SearchResultDone) {
- /* TODO: Handle Paged Results */
- destroy_ldap_message(result);
- return NULL;
- }
-
- /* TODO: Handle Search References here */
- return NULL;
-}
-
-void ldap_endsearchent(struct ldap_connection *conn,
- const struct timeval *endtime)
-{
- struct ldap_queue_entry *e;
-
- e = conn->search_entries;
-
- while (e != NULL) {
- struct ldap_queue_entry *next = e->next;
- DLIST_REMOVE(conn->search_entries, e);
- SAFE_FREE(e);
- e = next;
- }
-}
-
-struct ldap_message *ldap_searchone(struct ldap_connection *conn,
- struct ldap_message *msg,
- const struct timeval *endtime)
-{
- struct ldap_message *res1, *res2 = NULL;
- if (!ldap_setsearchent(conn, msg, endtime))
- return NULL;
-
- res1 = ldap_getsearchent(conn, endtime);
-
- if (res1 != NULL)
- res2 = ldap_getsearchent(conn, endtime);
-
- ldap_endsearchent(conn, endtime);
-
- if (res1 == NULL)
- return NULL;
-
- if (res2 != NULL) {
- /* More than one entry */
- destroy_ldap_message(res1);
- destroy_ldap_message(res2);
- return NULL;
- }
-
- return res1;
-}
-
-BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr,
- DATA_BLOB *value)
-{
- int i;
- struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
-
- if (msg->type != LDAP_TAG_SearchResultEntry)
- return False;
-
- for (i=0; i<r->num_attributes; i++) {
- if (strequal(attr, r->attributes[i].name)) {
- if (r->attributes[i].num_values != 1)
- return False;
-
- *value = r->attributes[i].values[0];
- return True;
- }
- }
- return False;
-}
-
-BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr,
- TALLOC_CTX *mem_ctx, char **value)
-{
- DATA_BLOB blob;
-
- if (!ldap_find_single_value(msg, attr, &blob))
- return False;
-
- *value = talloc(mem_ctx, blob.length+1);
-
- if (*value == NULL)
- return False;
-
- memcpy(*value, blob.data, blob.length);
- (*value)[blob.length] = '\0';
- return True;
-}
-
-BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr,
- int *value)
-{
- DATA_BLOB blob;
- char *val;
- int errno_save;
- BOOL res;
-
- if (!ldap_find_single_value(msg, attr, &blob))
- return False;
-
- val = malloc(blob.length+1);
- if (val == NULL)
- return False;
-
- memcpy(val, blob.data, blob.length);
- val[blob.length] = '\0';
-
- errno_save = errno;
- errno = 0;
-
- *value = strtol(val, NULL, 10);
-
- res = (errno == 0);
-
- free(val);
- errno = errno_save;
-
- return res;
-}
-
-int ldap_error(struct ldap_connection *conn)
-{
- return 0;
-}
-
-NTSTATUS ldap2nterror(int ldaperror)
-{
- return NT_STATUS_OK;
-}