r25763: Handle modifies, in the easy case (add/delete of elements), for the
[jra/samba/.git] / source4 / dsdb / samdb / ldb_modules / proxy.c
index fc1b896be47d1eaa1d8838a0f0211d26870b2d1e..d50d971e2a2c0907b228b6f6df77ef0c19c7b987 100644 (file)
@@ -10,7 +10,7 @@
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
+   version 3 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,8 +18,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
@@ -41,6 +40,7 @@
 #include "ldb/include/ldb.h"
 #include "ldb/include/ldb_errors.h"
 #include "ldb/include/ldb_private.h"
+#include "auth/credentials/credentials.h"
 
 struct proxy_data {
        struct ldb_context *upstream;
@@ -58,7 +58,7 @@ static int load_proxy_info(struct ldb_module *module)
 {
        struct proxy_data *proxy = talloc_get_type(module->private_data, struct proxy_data);
        struct ldb_dn *dn;
-       struct ldb_result *res;
+       struct ldb_result *res = NULL;
        int ret;
        const char *olddn, *newdn, *url, *username, *password, *oldstr, *newstr;
        struct cli_credentials *creds;
@@ -69,7 +69,7 @@ static int load_proxy_info(struct ldb_module *module)
                return 0;
        }
 
-       dn = ldb_dn_explode(proxy, "@PROXYINFO");
+       dn = ldb_dn_new(proxy, module->ldb, "@PROXYINFO");
        if (dn == NULL) {
                goto failed;
        }
@@ -80,26 +80,26 @@ static int load_proxy_info(struct ldb_module *module)
                goto failed;
        }
 
-       url      = ldb_msg_find_string(res->msgs[0], "url", NULL);
-       olddn    = ldb_msg_find_string(res->msgs[0], "olddn", NULL);
-       newdn    = ldb_msg_find_string(res->msgs[0], "newdn", NULL);
-       username = ldb_msg_find_string(res->msgs[0], "username", NULL);
-       password = ldb_msg_find_string(res->msgs[0], "password", NULL);
-       oldstr   = ldb_msg_find_string(res->msgs[0], "oldstr", NULL);
-       newstr   = ldb_msg_find_string(res->msgs[0], "newstr", NULL);
+       url      = ldb_msg_find_attr_as_string(res->msgs[0], "url", NULL);
+       olddn    = ldb_msg_find_attr_as_string(res->msgs[0], "olddn", NULL);
+       newdn    = ldb_msg_find_attr_as_string(res->msgs[0], "newdn", NULL);
+       username = ldb_msg_find_attr_as_string(res->msgs[0], "username", NULL);
+       password = ldb_msg_find_attr_as_string(res->msgs[0], "password", NULL);
+       oldstr   = ldb_msg_find_attr_as_string(res->msgs[0], "oldstr", NULL);
+       newstr   = ldb_msg_find_attr_as_string(res->msgs[0], "newstr", NULL);
 
        if (url == NULL || olddn == NULL || newdn == NULL || username == NULL || password == NULL) {
                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Need url, olddn, newdn, oldstr, newstr, username and password in @PROXYINFO\n");
                goto failed;
        }
 
-       proxy->olddn = ldb_dn_explode(proxy, olddn);
+       proxy->olddn = ldb_dn_new(proxy, module->ldb, olddn);
        if (proxy->olddn == NULL) {
                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Failed to explode olddn '%s'\n", olddn);
                goto failed;
        }
        
-       proxy->newdn = ldb_dn_explode(proxy, newdn);
+       proxy->newdn = ldb_dn_new(proxy, module->ldb, newdn);
        if (proxy->newdn == NULL) {
                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Failed to explode newdn '%s'\n", newdn);
                goto failed;
@@ -225,9 +225,8 @@ static void proxy_convert_record(struct ldb_module *module, struct ldb_message *
        
        /* fix the message DN */
        if (ldb_dn_compare_base(module->ldb, proxy->olddn, msg->dn) == 0) {
-               struct ldb_dn *newdn = ldb_dn_copy(msg, msg->dn);
-               newdn->comp_num -= proxy->olddn->comp_num;
-               msg->dn = ldb_dn_compose(msg, newdn, proxy->newdn);
+               ldb_dn_remove_base_components(msg->dn, ldb_dn_get_comp_num(proxy->olddn));
+               ldb_dn_add_base(msg->dn, proxy->newdn);
        }
 
        /* fix any attributes */
@@ -249,7 +248,7 @@ static void proxy_convert_record(struct ldb_module *module, struct ldb_message *
 static int proxy_search_bytree(struct ldb_module *module, struct ldb_request *req)
 {
        struct proxy_data *proxy = talloc_get_type(module->private_data, struct proxy_data);
-       struct ldb_request newreq;
+       struct ldb_request *newreq;
        struct ldb_dn *base;
        int ret, i;
 
@@ -268,47 +267,52 @@ static int proxy_search_bytree(struct ldb_module *module, struct ldb_request *re
                goto passthru;
        }
 
-       newreq.op.search.tree = proxy_convert_tree(module, req->op.search.tree);
+       newreq = talloc(module, struct ldb_request);
+       if (newreq == NULL) {
+               return -1;
+       }
+
+       newreq->op.search.tree = proxy_convert_tree(module, req->op.search.tree);
 
        /* convert the basedn of this search */
        base = ldb_dn_copy(proxy, req->op.search.base);
        if (base == NULL) {
+               talloc_free(newreq);
                goto failed;
        }
-       base->comp_num -= proxy->newdn->comp_num;
-       base = ldb_dn_compose(proxy, newreq.op.search.base, proxy->olddn);
+       ldb_dn_remove_base_components(base, ldb_dn_get_comp_num(proxy->newdn));
+       ldb_dn_add_base(base, proxy->olddn);
 
        ldb_debug(module->ldb, LDB_DEBUG_FATAL, "proxying: '%s' with dn '%s' \n", 
-                 ldb_filter_from_tree(proxy, newreq.op.search.tree), ldb_dn_linearize(proxy, newreq.op.search.base));
+                 ldb_filter_from_tree(proxy, newreq->op.search.tree), ldb_dn_get_linearized(newreq->op.search.base));
        for (i = 0; req->op.search.attrs && req->op.search.attrs[i]; i++) {
                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "attr: '%s'\n", req->op.search.attrs[i]);
        }
 
-       newreq.op.search.base = base;
-       newreq.op.search.scope = req->op.search.scope;
-       newreq.op.search.attrs = req->op.search.attrs;
-       newreq.op.search.res = req->op.search.res;
-       ret = ldb_request(proxy->upstream, &newreq);
+       newreq->op.search.base = base;
+       newreq->op.search.scope = req->op.search.scope;
+       newreq->op.search.attrs = req->op.search.attrs;
+       newreq->op.search.res = req->op.search.res;
+       newreq->controls = req->controls;
+       ret = ldb_request(proxy->upstream, newreq);
        if (ret != LDB_SUCCESS) {
-               ldb_set_errstring(module, talloc_strdup(module, ldb_errstring(proxy->upstream)));
+               ldb_set_errstring(module->ldb, ldb_errstring(proxy->upstream));
+               talloc_free(newreq);
                return -1;
        }
 
-       for (i = 0; i < newreq.op.search.res->count; i++) {
-               struct ldb_ldif ldif;
+       for (i = 0; i < newreq->op.search.res->count; i++) {
                printf("# record %d\n", i+1);
                
-               proxy_convert_record(module, newreq.op.search.res->msgs[i]);
-
-               ldif.changetype = LDB_CHANGETYPE_NONE;
-               ldif.msg = newreq.op.search.res->msgs[i];
+               proxy_convert_record(module, newreq->op.search.res->msgs[i]);
        }
 
+       talloc_free(newreq);
        return ret;
 
 failed:
        ldb_debug(module->ldb, LDB_DEBUG_TRACE, "proxy failed for %s\n", 
-                 ldb_dn_linearize(proxy, req->op.search.base));
+                 ldb_dn_get_linearized(req->op.search.base));
 
 passthru:
        return ldb_next_request(module, req); 
@@ -332,26 +336,7 @@ static const struct ldb_module_ops proxy_ops = {
        .request        = proxy_request
 };
 
-#ifdef HAVE_DLOPEN_DISABLED
-struct ldb_module *init_module(struct ldb_context *ldb, const char *options[])
-#else
-struct ldb_module *proxy_module_init(struct ldb_context *ldb, const char *options[])
-#endif
+int proxy_module_init(void)
 {
-       struct ldb_module *ctx;
-
-       ctx = talloc(ldb, struct ldb_module);
-       if (!ctx)
-               return NULL;
-
-       ctx->ldb = ldb;
-       ctx->prev = ctx->next = NULL;
-       ctx->ops = &proxy_ops;
-
-       ctx->private_data = talloc_zero(ctx, struct proxy_data);
-       if (ctx->private_data == NULL) {
-               return NULL;
-       }
-
-       return ctx;
+       return ldb_register_module(&proxy_ops);
 }