Specify event_context to ldb_wrap_connect explicitly.
[samba.git] / source4 / ldap_server / ldap_backend.c
index e81c5bf445e05c9bb0c8ac9a2a71bef8b8029f3d..9047773529906a5a55a138e3d3a8c3095b90a303 100644 (file)
 #include "libcli/ldap/ldap.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
-#include "lib/db_wrap.h"
+#include "lib/ldb_wrap.h"
 #include "auth/credentials/credentials.h"
 #include "auth/gensec/gensec.h"
 #include "param/param.h"
+#include "smbd/service_stream.h"
 
 #define VALID_DN_SYNTAX(dn,i) do {\
        if (!(dn)) {\
@@ -55,7 +56,11 @@ static int map_ldb_error(struct ldb_context *ldb, int err, const char **errstrin
 */
 NTSTATUS ldapsrv_backend_Init(struct ldapsrv_connection *conn) 
 {
-       conn->ldb = ldb_wrap_connect(conn, lp_sam_url(global_loadparm), conn->session_info,
+       conn->ldb = ldb_wrap_connect(conn, 
+                                    conn->connection->event.ctx,
+                                    conn->lp_ctx,
+                                    lp_sam_url(conn->lp_ctx), 
+                                    conn->session_info,
                                     NULL, conn->global_catalog ? LDB_FLG_RDONLY : 0, NULL);
        if (conn->ldb == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -64,10 +69,8 @@ NTSTATUS ldapsrv_backend_Init(struct ldapsrv_connection *conn)
        if (conn->server_credentials) {
                char **sasl_mechs = NULL;
                struct gensec_security_ops **backends = gensec_security_all();
-               enum credentials_use_kerberos use_kerberos
-                       = cli_credentials_get_kerberos_state(conn->server_credentials);
                struct gensec_security_ops **ops
-                       = gensec_use_kerberos_mechs(conn, backends, use_kerberos);
+                       = gensec_use_kerberos_mechs(conn, backends, conn->server_credentials);
                int i, j = 0;
                for (i = 0; ops && ops[i]; i++) {
                        if (ops[i]->sasl_name && ops[i]->server_start) {
@@ -215,9 +218,6 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
        lreq = talloc(local_ctx, struct ldb_request);
        NT_STATUS_HAVE_NO_MEMORY(lreq);
 
-       res = talloc_zero(local_ctx, struct ldb_result);
-       NT_STATUS_HAVE_NO_MEMORY(res);
-       
        lreq->operation = LDB_SEARCH;
        lreq->op.search.base = basedn;
        lreq->op.search.scope = scope;
@@ -241,6 +241,9 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
                }
        }
 
+       res = talloc_zero(lreq, struct ldb_result);
+       NT_STATUS_HAVE_NO_MEMORY(res);
+       
        lreq->context = res;
        lreq->callback = ldb_search_default_callback;
 
@@ -260,6 +263,11 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
                        ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry);
                        NT_STATUS_HAVE_NO_MEMORY(ent_r);
 
+                       /* Better to have the whole message kept here,
+                        * than to find someone further up didn't put
+                        * a value in the right spot in the talloc tree */
+                       talloc_steal(ent_r, res->msgs[i]);
+                       
                        ent = &ent_r->msg->r.SearchResultEntry;
                        ent->dn = ldb_dn_alloc_linearized(ent_r, res->msgs[i]->dn);
                        ent->num_attributes = 0;
@@ -300,10 +308,6 @@ reply:
                        DEBUG(10,("SearchRequest: results: [%d]\n", res->count));
                        result = LDAP_SUCCESS;
                        errstr = NULL;
-               } else if (res->count == 0) {
-                       DEBUG(10,("SearchRequest: no results\n"));
-                       result = LDAP_NO_SUCH_OBJECT;
-                       errstr = ldb_errstring(samdb);
                }
                if (res->controls) {
                        done_r->msg->controls = res->controls;
@@ -724,6 +728,18 @@ static NTSTATUS ldapsrv_AbandonRequest(struct ldapsrv_call *call)
 
 NTSTATUS ldapsrv_do_call(struct ldapsrv_call *call)
 {
+       int i;
+       struct ldap_message *msg = call->request;
+       /* Check for undecoded critical extensions */
+       for (i=0; msg->controls && msg->controls[i]; i++) {
+               if (!msg->controls_decoded[i] && 
+                   msg->controls[i]->critical) {
+                       DEBUG(3, ("ldapsrv_do_call: Critical extension %s is not known to this server\n",
+                                 msg->controls[i]->oid));
+                       return ldapsrv_unwilling(call, LDAP_UNAVAILABLE_CRITICAL_EXTENSION);
+               }
+       }
+
        switch(call->request->type) {
        case LDAP_TAG_BindRequest:
                return ldapsrv_BindRequest(call);