1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

r15795: Try to use the async code by default

It passess all my tests, but I still need to work on a lot of stuff.
Shouldn't impact anybody else work, so I want to commit now and see what happens

Will work to remove the old code from modules and backends soon, and make some
more restyling in ldb internals.

So, if there is something you don't like in this desgin please speak now.

Simo.
(This used to be commit 8b2a563e71)
This commit is contained in:
Simo Sorce 2006-05-22 03:55:01 +00:00 committed by Gerald (Jerry) Carter
parent 79183f68fc
commit 8081e4f402
4 changed files with 185 additions and 28 deletions

View File

@ -975,16 +975,25 @@ static int add_krb5_keys_from_NThash(struct ldb_module *module, struct ldb_messa
return LDB_SUCCESS;
}
static int set_pwdLastSet(struct ldb_module *module, struct ldb_message *msg)
static int set_pwdLastSet(struct ldb_module *module, struct ldb_message *msg, int is_mod)
{
NTTIME now_nt;
/* set it as now */
unix_to_nt_time(&now_nt, time(NULL));
/* replace or add */
if (ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
if (!is_mod) {
/* be sure there isn't a 0 value set (eg. coming from the template) */
ldb_msg_remove_attr(msg, "pwdLastSet");
/* add */
if (ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_ADD) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
} else {
/* replace */
if (ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
}
if (samdb_msg_add_uint64(module->ldb, msg, msg, "pwdLastSet", now_nt) != 0) {
@ -1326,7 +1335,7 @@ static int password_hash_add_async_do_add(struct ldb_async_handle *h) {
/* don't touch it if a value is set. It could be an incoming samsync */
if (ldb_msg_find_uint64(msg, "pwdLastSet", 0) == 0) {
if (set_pwdLastSet(ac->module, msg) != LDB_SUCCESS) {
if (set_pwdLastSet(ac->module, msg, 0) != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}
}
@ -1630,7 +1639,7 @@ static int password_hash_mod_async_do_mod(struct ldb_async_handle *h) {
}
/* set change time */
if (set_pwdLastSet(ac->module, msg) != LDB_SUCCESS) {
if (set_pwdLastSet(ac->module, msg, 1) != LDB_SUCCESS) {
return LDB_ERR_OPERATIONS_ERROR;
}

View File

@ -94,14 +94,35 @@ static BOOL samldb_msg_add_sid(struct ldb_module *module, struct ldb_message *ms
return (ldb_msg_add_value(msg, name, &v) == 0);
}
static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value)
static BOOL samldb_find_or_add_value(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value)
{
if (msg == NULL || name == NULL || value == NULL || set_value == NULL) {
return False;
}
if (samldb_find_attribute(msg, name, value) == NULL) {
return samldb_msg_add_string(module, msg, name, set_value);
}
return True;
}
static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *set_value)
{
int j;
struct ldb_message_element *el;
if (msg == NULL || name == NULL || set_value == NULL) {
return False;
}
el = ldb_msg_find_element(msg, name);
if (el) {
return True;
}
return samldb_msg_add_string(module, msg, name, set_value);
}
/*
allocate a new id, attempting to do it atomically
return 0 on failure, the id on success
@ -492,16 +513,15 @@ static int samldb_copy_template(struct ldb_module *module, struct ldb_message *m
strcasecmp((char *)el->values[j].data, "secretTemplate") == 0) {
continue;
}
if ( ! samldb_find_or_add_attribute(module, msg, el->name,
(char *)el->values[j].data,
(char *)el->values[j].data)) {
if ( ! samldb_find_or_add_value(module, msg, el->name,
(char *)el->values[j].data,
(char *)el->values[j].data)) {
ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Attribute adding failed...\n");
talloc_free(res);
return -1;
}
} else {
if ( ! samldb_find_or_add_attribute(module, msg, el->name,
NULL,
(char *)el->values[j].data)) {
ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Attribute adding failed...\n");
talloc_free(res);
@ -558,7 +578,7 @@ static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, name)) {
if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", name)) {
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
@ -620,7 +640,7 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
}
/* if the only attribute was: "objectclass: computer", then make sure we also add "user" objectclass */
if ( ! samldb_find_or_add_attribute(module, msg2, "objectclass", "user", "user")) {
if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) {
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
@ -633,7 +653,7 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, name)) {
if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", name)) {
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}

View File

@ -2,6 +2,7 @@
ldb database library
Copyright (C) Andrew Tridgell 2004
Copyright (C) Simo Sorce 2005-2006
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@ -251,6 +252,7 @@ int ldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type typ
return handle->module->ops->async_wait(handle, type);
}
/*
check for an error return from an op
if an op fails, but has not setup an error string, then setup one now
@ -272,6 +274,7 @@ static int ldb_op_finish(struct ldb_context *ldb, int status)
/*
start an ldb request
autostarts a transacion if none active and the operation is not a search
does not work for ASYNC operations
NOTE: the request must be a talloc context.
returns LDB_ERR_* on errors.
*/
@ -285,7 +288,7 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
req->op.search.res = NULL;
}
/* start a transaction if needed */
/* start a transaction if not async and not search */
if ((!ldb->transaction_active) &&
(req->operation == LDB_REQ_ADD ||
req->operation == LDB_REQ_MODIFY ||
@ -317,6 +320,71 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
Use talloc_free to free the ldb_message returned in 'res', if successful
*/
static int ldb_search_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares)
{
struct ldb_result *res;
int n;
if (!context) {
ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context in callback"));
return LDB_ERR_OPERATIONS_ERROR;
}
res = *((struct ldb_result **)context);
if (!res || !ares) {
goto error;
}
if (ares->type == LDB_REPLY_ENTRY) {
res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2);
if (! res->msgs) {
goto error;
}
res->msgs[res->count + 1] = NULL;
res->msgs[res->count] = talloc_steal(res->msgs, ares->message);
if (! res->msgs[res->count]) {
goto error;
}
res->count++;
}
if (ares->type == LDB_REPLY_REFERRAL) {
if (res->refs) {
for (n = 0; res->refs[n]; n++) /*noop*/ ;
} else {
n = 0;
}
res->refs = talloc_realloc(res, res->refs, char *, n + 2);
if (! res->refs) {
goto error;
}
res->refs[n] = talloc_steal(res->refs, ares->referral);
res->refs[n + 1] = NULL;
}
if (ares->controls) {
res->controls = talloc_steal(res, ares->controls);
if (! res->controls) {
goto error;
}
}
talloc_free(ares);
return LDB_SUCCESS;
error:
talloc_free(ares);
talloc_free(res);
*((struct ldb_result **)context) = NULL;
return LDB_ERR_OPERATIONS_ERROR;
}
int ldb_search(struct ldb_context *ldb,
const struct ldb_dn *base,
enum ldb_scope scope,
@ -327,7 +395,10 @@ int ldb_search(struct ldb_context *ldb,
struct ldb_request *req;
int ret;
(*res) = NULL;
*res = talloc_zero(ldb, struct ldb_result);
if (! *res) {
return LDB_ERR_OPERATIONS_ERROR;
}
req = talloc(ldb, struct ldb_request);
if (req == NULL) {
@ -335,7 +406,7 @@ int ldb_search(struct ldb_context *ldb,
return LDB_ERR_OPERATIONS_ERROR;
}
req->operation = LDB_REQ_SEARCH;
req->operation = LDB_ASYNC_SEARCH;
req->op.search.base = base;
req->op.search.scope = scope;
@ -348,16 +419,53 @@ int ldb_search(struct ldb_context *ldb,
req->op.search.attrs = attrs;
req->controls = NULL;
req->creds = NULL;
req->async.context = res;
req->async.callback = ldb_search_callback;
req->async.timeout = 600; /* 10 minutes */
ret = ldb_request(ldb, req);
if (ret == LDB_SUCCESS) {
(*res) = talloc_steal(ldb, req->op.search.res);
ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
}
if (ret != LDB_SUCCESS) {
talloc_free(*res);
*res = NULL;
}
talloc_free(req);
return ret;
}
static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req)
{
int ret, close_transaction;
close_transaction = 0;
if (!ldb->transaction_active) {
ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
return ret;
}
close_transaction = 1;
}
ret = ldb_request(ldb, req);
if (ret == LDB_SUCCESS) {
ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
}
if (close_transaction) {
return ldb_op_finish(ldb, ret);
}
return ret;
}
/*
add a record to the database. Will fail if a record with the given class and key
already exists
@ -377,11 +485,16 @@ int ldb_add(struct ldb_context *ldb,
return LDB_ERR_OPERATIONS_ERROR;
}
req->operation = LDB_REQ_ADD;
req->operation = LDB_ASYNC_ADD;
req->op.add.message = message;
req->controls = NULL;
req->creds = NULL;
req->async.context = NULL;
req->async.callback = NULL;
req->async.timeout = 600; /* 10 minutes */
ret = ldb_request(ldb, req);
/* do request and autostart a transaction */
ret = ldb_autotransaction_request(ldb, req);
talloc_free(req);
return ret;
@ -405,11 +518,16 @@ int ldb_modify(struct ldb_context *ldb,
return LDB_ERR_OPERATIONS_ERROR;
}
req->operation = LDB_REQ_MODIFY;
req->operation = LDB_ASYNC_MODIFY;
req->op.add.message = message;
req->controls = NULL;
req->creds = NULL;
req->async.context = NULL;
req->async.callback = NULL;
req->async.timeout = 600; /* 10 minutes */
ret = ldb_request(ldb, req);
/* do request and autostart a transaction */
ret = ldb_autotransaction_request(ldb, req);
talloc_free(req);
return ret;
@ -430,11 +548,16 @@ int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
return LDB_ERR_OPERATIONS_ERROR;
}
req->operation = LDB_REQ_DELETE;
req->operation = LDB_ASYNC_DELETE;
req->op.del.dn = dn;
req->controls = NULL;
req->creds = NULL;
req->async.context = NULL;
req->async.callback = NULL;
req->async.timeout = 600; /* 10 minutes */
ret = ldb_request(ldb, req);
/* do request and autostart a transaction */
ret = ldb_autotransaction_request(ldb, req);
talloc_free(req);
return ret;
@ -454,12 +577,17 @@ int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct
return LDB_ERR_OPERATIONS_ERROR;
}
req->operation = LDB_REQ_RENAME;
req->operation = LDB_ASYNC_RENAME;
req->op.rename.olddn = olddn;
req->op.rename.newdn = newdn;
req->controls = NULL;
req->creds = NULL;
req->async.context = NULL;
req->async.callback = NULL;
req->async.timeout = 600; /* 10 minutes */
ret = ldb_request(ldb, req);
/* do request and autostart a transaction */
ret = ldb_autotransaction_request(ldb, req);
talloc_free(req);
return ret;

View File

@ -82,8 +82,8 @@ vendorVersion: ${VERSION}
#
# Some Known ordering constraints:
# - rootdse must be first, as it makes redirects from "" -> cn=rootdse
# - password_hash must be before samldb, or else the template code in samldb breaks setting the pwdLastSet attribute
# - samldb must be before password_hash, because password_hash checks that the objectclass is of type person (filled in by samldb)
dn: @MODULES
@LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,asq,password_hash,samldb,operational,objectguid,rdn_name,objectclass
@LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,objectclass