ldb: Allow to register extended match rules
[obnox/samba/samba-obnox.git] / lib / ldb / common / ldb.c
index a223b87c45e905cf311acdb497c072020a7053ef..0f0f5ab99b69b805cd0535399ca9d7c4c34abc11 100644 (file)
@@ -60,7 +60,6 @@ static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
 {
        struct ldb_context *ldb = talloc_get_type(context, struct ldb_context);
        enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL;
-       char *s = NULL;
 
        switch (level) {
        case TEVENT_DEBUG_FATAL:
@@ -77,10 +76,10 @@ static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
                break;
        };
 
-       vasprintf(&s, fmt, ap);
-       if (!s) return;
-       ldb_debug(ldb, ldb_level, "tevent: %s", s);
-       free(s);
+       /* There isn't a tevent: prefix here because to add it means
+        * actually printing the string, and most of the time we don't
+        * want to show it */
+       ldb_vdebug(ldb, ldb_level, fmt, ap);
 }
 
 /*
@@ -113,6 +112,10 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx)
         * having to provide their own private one explicitly */
        if (ev_ctx == NULL) {
                ev_ctx = tevent_context_init(ldb);
+               if (ev_ctx == NULL) {
+                       talloc_free(ldb);
+                       return NULL;
+               }
                tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb);
                tevent_loop_allow_nesting(ev_ctx);
        }
@@ -127,6 +130,11 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx)
        ldb_set_create_perms(ldb, 0666);
        ldb_set_modules_dir(ldb, LDB_MODULESDIR);
        ldb_set_event_context(ldb, ev_ctx);
+       ret = ldb_register_extended_match_rules(ldb);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(ldb);
+               return NULL;
+       }
 
        /* TODO: get timeout from options if available there */
        ldb->default_timeout = 300; /* set default to 5 minutes */
@@ -254,11 +262,12 @@ int ldb_connect(struct ldb_context *ldb, const char *url,
                return ret;
        }
 
-       if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
+       ret = ldb_load_modules(ldb, options);
+       if (ret != LDB_SUCCESS) {
                ldb_debug(ldb, LDB_DEBUG_FATAL,
                          "Unable to load modules for %s: %s",
                          url, ldb_errstring(ldb));
-               return LDB_ERR_OTHER;
+               return ret;
        }
 
        /* set the default base dn */
@@ -367,10 +376,14 @@ int ldb_transaction_start(struct ldb_context *ldb)
                                ldb_strerror(status),
                                status);
                }
-       }
-       if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 
-               ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s", 
-                         ldb_errstring(module->ldb));                          
+               if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
+                       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s",
+                                 ldb_errstring(module->ldb));
+               }
+       } else {
+               if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
+                       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction success");
+               }
        }
        return status;
 }
@@ -409,6 +422,7 @@ int ldb_transaction_prepare_commit(struct ldb_context *ldb)
 
        status = module->ops->prepare_commit(module);
        if (status != LDB_SUCCESS) {
+               ldb->transaction_active--;
                /* if a module fails the prepare then we need
                   to call the end transaction for everyone */
                FIRST_OP(ldb, del_transaction);
@@ -572,8 +586,8 @@ int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
        struct tevent_context *ev;
        int ret;
 
-       if (!handle) {
-               return ldb_error(handle->ldb, LDB_ERR_UNAVAILABLE, NULL);
+       if (handle == NULL) {
+               return LDB_ERR_UNAVAILABLE;
        }
 
        if (handle->state == LDB_ASYNC_DONE) {
@@ -727,6 +741,7 @@ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
 {
        TALLOC_CTX *tmp_ctx = talloc_new(req);
        unsigned int i;
+       struct ldb_ldif ldif;
 
        switch (req->operation) {
        case LDB_SEARCH:
@@ -766,18 +781,36 @@ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
                ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no");
                break;
        case LDB_ADD:
+               ldif.changetype = LDB_CHANGETYPE_ADD;
+               ldif.msg = discard_const_p(struct ldb_message, req->op.add.message);
+
                ldb_debug_add(ldb, "ldb_trace_request: ADD\n");
+
+               /* 
+                * The choice to call
+                * ldb_ldif_write_redacted_trace_string() is CRITICAL
+                * for security.  It ensures that we do not output
+                * passwords into debug logs 
+                */
+
                ldb_debug_add(req->handle->ldb, "%s\n", 
-                             ldb_ldif_message_string(req->handle->ldb, tmp_ctx, 
-                                                     LDB_CHANGETYPE_ADD, 
-                                                     req->op.add.message));
+                             ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif));
                break;
        case LDB_MODIFY:
+               ldif.changetype = LDB_CHANGETYPE_MODIFY;
+               ldif.msg = discard_const_p(struct ldb_message, req->op.mod.message);
+
                ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n");
+
+               /* 
+                * The choice to call
+                * ldb_ldif_write_redacted_trace_string() is CRITICAL
+                * for security.  It ensures that we do not output
+                * passwords into debug logs 
+                */
+
                ldb_debug_add(req->handle->ldb, "%s\n", 
-                             ldb_ldif_message_string(req->handle->ldb, tmp_ctx, 
-                                                     LDB_CHANGETYPE_ADD, 
-                                                     req->op.mod.message));
+                             ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif));
                break;
        case LDB_REQ_REGISTER_CONTROL:
                ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n");
@@ -1962,7 +1995,7 @@ uint32_t ldb_req_get_custom_flags(struct ldb_request *req)
 
 
 /**
  return true is a request is untrusted
* return true if a request is untrusted
  */
 bool ldb_req_is_untrusted(struct ldb_request *req)
 {