summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/ldap/ldap_client.c131
-rw-r--r--source4/libcli/ldap/ldap_ldif.c58
-rw-r--r--source4/torture/ldap/basic.c37
-rw-r--r--source4/torture/ldap/common.c146
4 files changed, 219 insertions, 153 deletions
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 71b57e116e..8867344de3 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -548,9 +548,138 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid,
return NULL;
}
+/*
+ Write data to a fd
+*/
+static ssize_t write_data(int fd, char *buffer, size_t N)
+{
+ size_t total=0;
+ ssize_t ret;
+
+ while (total < N) {
+ ret = sys_write(fd,buffer + total,N - total);
+
+ if (ret == -1) {
+ DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (ret == 0)
+ return total;
+
+ total += ret;
+ }
+
+ return (ssize_t)total;
+}
+
+
+/*
+ Read data from the client, reading exactly N bytes
+*/
+static ssize_t read_data(int fd, char *buffer, size_t N)
+{
+ ssize_t ret;
+ size_t total=0;
+
+ while (total < N) {
+
+ ret = sys_read(fd,buffer + total,N - total);
+
+ if (ret == 0) {
+ DEBUG(10,("read_data: read of %d returned 0. Error = %s\n",
+ (int)(N - total), strerror(errno) ));
+ return 0;
+ }
+
+ if (ret == -1) {
+ DEBUG(0,("read_data: read failure for %d. Error = %s\n",
+ (int)(N - total), strerror(errno) ));
+ return -1;
+ }
+ total += ret;
+ }
+
+ return (ssize_t)total;
+}
+
+static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, struct ldap_message *req)
+{
+ NTSTATUS status;
+ DATA_BLOB request;
+ BOOL result;
+ DATA_BLOB wrapped;
+ int len;
+ char length[4];
+ struct asn1_data asn1;
+ struct ldap_message *rep;
+
+ req->messageid = conn->next_msgid++;
+
+ if (!ldap_encode(req, &request))
+ return NULL;
+
+ status = gensec_wrap(conn->gensec,
+ req->mem_ctx,
+ &request,
+ &wrapped);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status)));
+ return NULL;
+ }
+
+ RSIVAL(length, 0, wrapped.length);
+
+ result = (write_data(conn->sock, length, 4) == 4);
+ if (!result)
+ return NULL;
+
+ result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length);
+ if (!result)
+ return NULL;
+
+ wrapped = data_blob(NULL, 0x4000);
+ data_blob_clear(&wrapped);
+
+ result = (read_data(conn->sock, length, 4) == 4);
+ if (!result)
+ return NULL;
+
+ len = RIVAL(length,0);
+
+ result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len);
+ if (!result)
+ return NULL;
+
+ wrapped.length = len;
+
+ status = gensec_unwrap(conn->gensec,
+ req->mem_ctx,
+ &wrapped,
+ &request);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status)));
+ return NULL;
+ }
+
+ rep = new_ldap_message(req->mem_ctx);
+
+ asn1_load(&asn1, request);
+ if (!ldap_decode(&asn1, rep)) {
+ return NULL;
+ }
+
+ return rep;
+}
+
struct ldap_message *ldap_transaction(struct ldap_connection *conn,
struct ldap_message *request)
{
+ if ((request->type != LDAP_TAG_BindRequest) && conn->gensec &&
+ (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
+ gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) {
+ return ldap_transaction_sasl(conn, request);
+ }
+
if (!ldap_send_msg(conn, request, NULL))
return False;
@@ -624,7 +753,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds)
return result;
}
- gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
+ gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
status = gensec_set_credentials(conn->gensec, creds);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c
index e5e5cdd6df..c36106e116 100644
--- a/source4/libcli/ldap/ldap_ldif.c
+++ b/source4/libcli/ldap/ldap_ldif.c
@@ -305,6 +305,53 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk)
return True;
}
+static BOOL fill_modrdn(struct ldap_message *msg, char **chunk)
+{
+ struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
+ const char *attr_name;
+ struct ldap_val value;
+
+ r->newrdn = NULL;
+ r->deleteolddn = False;
+ r->newsuperior = NULL;
+
+ if (next_attr(chunk, &attr_name, &value) != 0) {
+ return False;
+ }
+
+ if (!strequal(attr_name, "newrdn")) {
+ return False;
+ }
+
+ r->newrdn = value.data;
+
+ if (next_attr(chunk, &attr_name, &value) != 0) {
+ return False;
+ }
+
+ if (!strequal(attr_name, "deleteoldrdn")) {
+ return False;
+ }
+
+ if (value.data && (((char *)value.data)[0] != '0')) {
+ r->deleteolddn = True;
+ }
+
+ if (next_attr(chunk, &attr_name, &value) != 0) {
+ /* newsuperior is optional */
+ return True;
+ }
+
+ if (!strequal(attr_name, "newsuperior")) {
+ return False;
+ }
+
+ r->newsuperior = value.data;
+
+ return True;
+}
+
+
/*
read from a LDIF source, creating a ldap_message
*/
@@ -381,6 +428,17 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void
return msg;
}
+ if (strequal(value.data, "modrdn")) {
+ msg->type = LDAP_TAG_ModifyDNRequest;
+
+ msg->r.ModifyDNRequest.dn = dn;
+
+ if (!fill_modrdn(msg, &s))
+ goto failed;
+
+ return msg;
+ }
+
DEBUG(3, ("changetype %s not supported\n", (char *)value.data));
failed:
diff --git a/source4/torture/ldap/basic.c b/source4/torture/ldap/basic.c
index b53515fdbc..7114aa2576 100644
--- a/source4/torture/ldap/basic.c
+++ b/source4/torture/ldap/basic.c
@@ -137,8 +137,7 @@ static BOOL test_search_rootDSE(struct ldap_connection *conn, char **basedn)
static BOOL test_compare_sasl(struct ldap_connection *conn, const char *basedn)
{
- BOOL ret = True;
- struct ldap_message *msg, *result;
+ struct ldap_message *req, *rep;
const char *val;
printf("Testing SASL Compare: %s\n", basedn);
@@ -149,37 +148,33 @@ static BOOL test_compare_sasl(struct ldap_connection *conn, const char *basedn)
conn->next_msgid = 55;
- msg = new_ldap_message(conn);
- if (!msg) {
+ req = new_ldap_message(conn);
+ if (!req) {
return False;
}
- msg->type = LDAP_TAG_CompareRequest;
- msg->r.CompareRequest.dn = basedn;
- msg->r.CompareRequest.attribute = talloc_strdup(msg->mem_ctx, "objectClass");
+ req->type = LDAP_TAG_CompareRequest;
+ req->r.CompareRequest.dn = basedn;
+ req->r.CompareRequest.attribute = talloc_strdup(req->mem_ctx, "objectClass");
val = "domain";
- msg->r.CompareRequest.value = data_blob_talloc(msg->mem_ctx, val, strlen(val));
+ req->r.CompareRequest.value = data_blob_talloc(req->mem_ctx, val, strlen(val));
- if (!ldap_sasl_send_msg(conn, msg, NULL)) {
+ rep = ldap_transaction(conn, req);
+ if (!rep) {
return False;
}
DEBUG(5,("Code: %d DN: [%s] ERROR:[%s] REFERRAL:[%s]\n",
- msg->r.CompareResponse.resultcode,
- msg->r.CompareResponse.dn,
- msg->r.CompareResponse.errormessage,
- msg->r.CompareResponse.referral));
-
- return True;
- if (!result) {
- return False;
- }
+ rep->r.CompareResponse.resultcode,
+ rep->r.CompareResponse.dn,
+ rep->r.CompareResponse.errormessage,
+ rep->r.CompareResponse.referral));
- if (result->type != LDAP_TAG_CompareResponse) {
+ if (rep->type != LDAP_TAG_CompareResponse) {
return False;
}
- return ret;
+ return True;
}
BOOL torture_ldap_basic(void)
@@ -199,7 +194,7 @@ BOOL torture_ldap_basic(void)
url = talloc_asprintf(mem_ctx, "ldap://%s/", host);
- status = torture_ldap_connection(mem_ctx, &conn, url, userdn, secret);
+ status = torture_ldap_connection2(mem_ctx, &conn, url, userdn, secret);
if (!NT_STATUS_IS_OK(status)) {
return False;
}
diff --git a/source4/torture/ldap/common.c b/source4/torture/ldap/common.c
index 9dbe2557eb..a65d24804c 100644
--- a/source4/torture/ldap/common.c
+++ b/source4/torture/ldap/common.c
@@ -24,6 +24,7 @@
#include "includes.h"
#include "asn_1.h"
#include "libcli/ldap/ldap.h"
+#include "auth/gensec/gensec.h"
NTSTATUS torture_ldap_bind(struct ldap_connection *conn, const char *userdn, const char *password)
{
@@ -70,10 +71,9 @@ NTSTATUS torture_ldap_bind_sasl(struct ldap_connection *conn,
/* open a ldap connection to a server */
NTSTATUS torture_ldap_connection(TALLOC_CTX *mem_ctx, struct ldap_connection **conn,
- const char *url, const char *userdn, const char *password)
+ const char *url)
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- int ret;
if (!url) {
printf("You must specify a url string\n");
@@ -86,6 +86,19 @@ NTSTATUS torture_ldap_connection(TALLOC_CTX *mem_ctx, struct ldap_connection **c
return status;
}
+ return NT_STATUS_OK;
+}
+
+/* open a ldap connection to a server */
+NTSTATUS torture_ldap_connection2(TALLOC_CTX *mem_ctx, struct ldap_connection **conn,
+ const char *url, const char *userdn, const char *password)
+{
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ int ret;
+
+ status = torture_ldap_connection(mem_ctx, conn, url);
+ NT_STATUS_NOT_OK_RETURN(status);
+
ret = ldap_bind_simple(*conn, userdn, password);
if (ret != LDAP_SUCCESS) {
printf("Failed to connect with url [%s]\n", url);
@@ -104,132 +117,3 @@ NTSTATUS torture_ldap_close(struct ldap_connection *conn)
:-) sss */
return NT_STATUS_OK;
}
-
-
-/*
- Write data to a fd
-*/
-static ssize_t write_data(int fd, char *buffer, size_t N)
-{
- size_t total=0;
- ssize_t ret;
-
- while (total < N) {
- ret = sys_write(fd,buffer + total,N - total);
-
- if (ret == -1) {
- DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
- return -1;
- }
- if (ret == 0)
- return total;
-
- total += ret;
- }
-
- return (ssize_t)total;
-}
-
-
-/*
- Read data from the client, reading exactly N bytes
-*/
-static ssize_t read_data(int fd, char *buffer, size_t N)
-{
- ssize_t ret;
- size_t total=0;
-
- while (total < N) {
-
- ret = sys_read(fd,buffer + total,N - total);
-
- if (ret == 0) {
- DEBUG(10,("read_data: read of %d returned 0. Error = %s\n",
- (int)(N - total), strerror(errno) ));
- return 0;
- }
-
- if (ret == -1) {
- DEBUG(0,("read_data: read failure for %d. Error = %s\n",
- (int)(N - total), strerror(errno) ));
- return -1;
- }
- total += ret;
- }
-
- return (ssize_t)total;
-}
-
-BOOL ldap_sasl_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
- const struct timeval *endtime)
-{
- NTSTATUS status;
- DATA_BLOB request;
- BOOL result;
- DATA_BLOB wrapped;
- int len;
- char length[4];
- struct asn1_data asn1;
- TALLOC_CTX *mem_ctx;
-
- msg->messageid = conn->next_msgid++;
-
- if (!ldap_encode(msg, &request))
- return False;
-
- status = gensec_wrap(conn->gensec,
- msg->mem_ctx,
- &request,
- &wrapped);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status)));
- return False;
- }
-
- RSIVAL(length, 0, wrapped.length);
-
- result = (write_data(conn->sock, length, 4) == 4);
- if (!result)
- return result;
-
- result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length);
- if (!result)
- return result;
-
- wrapped = data_blob(NULL, 0x4000);
- data_blob_clear(&wrapped);
-
- result = (read_data(conn->sock, length, 4) == 4);
- if (!result)
- return result;
-
- len = RIVAL(length,0);
-
- result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len);
- if (!result)
- return result;
-
- wrapped.length = len;
-
- status = gensec_unwrap(conn->gensec,
- msg->mem_ctx,
- &wrapped,
- &request);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status)));
- return False;
- }
-
- mem_ctx = msg->mem_ctx;
- ZERO_STRUCTP(msg);
- msg->mem_ctx = mem_ctx;
-
- asn1_load(&asn1, request);
- if (!ldap_decode(&asn1, msg)) {
- return False;
- }
-
- result = True;
-
- return result;
-}