r6732: - move sasl send recv code to the ldap lib
authorStefan Metzmacher <metze@samba.org>
Wed, 11 May 2005 14:38:13 +0000 (14:38 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:16:39 +0000 (13:16 -0500)
- support 'modrdn' ldif

metze

source/libcli/ldap/ldap_client.c
source/libcli/ldap/ldap_ldif.c
source/torture/ldap/basic.c
source/torture/ldap/common.c

index 71b57e116e6359f389a6b36ccdc58c6b84e02a92..8867344de3ac1c095f6257ea8522ce362bc7ab98 100644 (file)
@@ -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)) {
index e5e5cdd6df2debb331d335de7280422176afc631..c36106e1165c2e4d5140515ed0ca48388995815a 100644 (file)
@@ -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:
index b53515fdbc6285292f8293ed6501145d44ca14fc..7114aa257609a972bd537b60ccef73decca605da 100644 (file)
@@ -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;
        }
index 9dbe2557eba270f442acce1f727b22676b17c200..a65d24804c43c909a38054feb7524cc2eaa8740a 100644 (file)
@@ -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;
-}