mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
s4/rodc: Support read-only database
Check on modify if we are RODC and return referral. On the ldap backend side now we pass context and ldb_modify_default_callback to propagate the referral error to the client.
This commit is contained in:
parent
bcdaa23798
commit
f84aeea739
@ -2751,6 +2751,7 @@ int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *objectGUID, bo
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DEBUG(1,(("Failed to find our own NTDS Settings object by objectGUID=%s!\n"),
|
||||
GUID_string(tmp_ctx, objectGUID)));
|
||||
*is_rodc = false;
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
@ -167,8 +167,7 @@ static int partition_req_callback(struct ldb_request *req,
|
||||
|
||||
switch (ares->type) {
|
||||
case LDB_REPLY_REFERRAL:
|
||||
/* ignore referrals for now */
|
||||
break;
|
||||
return ldb_module_send_referral(ac->req, ares->referral);
|
||||
|
||||
case LDB_REPLY_ENTRY:
|
||||
if (ac->req->operation != LDB_SEARCH) {
|
||||
|
@ -1076,6 +1076,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
|
||||
*/
|
||||
static int replmd_update_rpmd(struct ldb_module *module,
|
||||
const struct dsdb_schema *schema,
|
||||
struct ldb_request *req,
|
||||
struct ldb_message *msg, uint64_t *seq_num,
|
||||
time_t t,
|
||||
bool *is_urgent)
|
||||
@ -1092,6 +1093,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_message_element *objectclass_el;
|
||||
enum urgent_situation situation;
|
||||
bool rodc;
|
||||
|
||||
ldb = ldb_module_get_ctx(module);
|
||||
|
||||
@ -1157,6 +1159,20 @@ static int replmd_update_rpmd(struct ldb_module *module,
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
/*we have elements that will be modified*/
|
||||
if (msg->num_elements > 0) {
|
||||
/*if we are RODC and this is a DRSR update then its ok*/
|
||||
if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
|
||||
ret = samdb_rodc(ldb, &rodc);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DEBUG(4, (__location__ ": unable to tell if we are an RODC\n"));
|
||||
} else if (rodc) {
|
||||
ldb_asprintf_errstring(ldb, "RODC modify is forbidden\n");
|
||||
return LDB_ERR_REFERRAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<msg->num_elements; i++) {
|
||||
struct ldb_message_element *old_el;
|
||||
old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name);
|
||||
@ -2043,6 +2059,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
time_t t = time(NULL);
|
||||
int ret;
|
||||
bool is_urgent = false;
|
||||
struct loadparm_context *lp_ctx;
|
||||
char *referral;
|
||||
|
||||
/* do not manipulate our control entries */
|
||||
if (ldb_dn_is_special(req->op.mod.message->dn)) {
|
||||
@ -2050,6 +2068,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
}
|
||||
|
||||
ldb = ldb_module_get_ctx(module);
|
||||
lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
|
||||
struct loadparm_context);
|
||||
|
||||
ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_modify\n");
|
||||
|
||||
@ -2069,7 +2089,18 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
ldb_msg_remove_attr(msg, "whenChanged");
|
||||
ldb_msg_remove_attr(msg, "uSNChanged");
|
||||
|
||||
ret = replmd_update_rpmd(module, ac->schema, msg, &ac->seq_num, t, &is_urgent);
|
||||
ret = replmd_update_rpmd(module, ac->schema, req, msg, &ac->seq_num, t, &is_urgent);
|
||||
if (ret == LDB_ERR_REFERRAL) {
|
||||
talloc_free(ac);
|
||||
|
||||
referral = talloc_asprintf(req,
|
||||
"ldap://%s/%s",
|
||||
lp_dnsdomain(lp_ctx),
|
||||
ldb_dn_get_linearized(msg->dn));
|
||||
ret = ldb_module_send_referral(req, referral);
|
||||
return ldb_module_done(req, NULL, NULL, ret);
|
||||
}
|
||||
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(ac);
|
||||
return ret;
|
||||
|
@ -141,6 +141,8 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
|
||||
const char *oid_attr = NULL;
|
||||
const char *oid = NULL;
|
||||
WERROR status;
|
||||
bool rodc;
|
||||
int ret;
|
||||
|
||||
ldb = ldb_module_get_ctx(module);
|
||||
|
||||
@ -159,7 +161,12 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return ldb_next_request(module, req);
|
||||
}
|
||||
|
||||
if (!schema->fsmo.we_are_master) {
|
||||
ret = samdb_rodc(ldb, &rodc);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DEBUG(4, (__location__ ": unable to tell if we are an RODC \n"));
|
||||
}
|
||||
|
||||
if (!schema->fsmo.we_are_master && !rodc) {
|
||||
ldb_debug_set(ldb, LDB_DEBUG_ERROR,
|
||||
"schema_data_add: we are not master: reject request\n");
|
||||
return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
|
@ -243,12 +243,18 @@ int dsdb_module_modify(struct ldb_module *module,
|
||||
int ret;
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(module);
|
||||
struct ldb_result *res;
|
||||
|
||||
res = talloc_zero(tmp_ctx, struct ldb_result);
|
||||
if (!res) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = ldb_build_mod_req(&mod_req, ldb, tmp_ctx,
|
||||
message,
|
||||
NULL,
|
||||
NULL,
|
||||
ldb_op_default_callback,
|
||||
res,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
@ -292,13 +298,19 @@ int dsdb_module_rename(struct ldb_module *module,
|
||||
int ret;
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(module);
|
||||
struct ldb_result *res;
|
||||
|
||||
res = talloc_zero(tmp_ctx, struct ldb_result);
|
||||
if (!res) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = ldb_build_rename_req(&req, ldb, tmp_ctx,
|
||||
olddn,
|
||||
newdn,
|
||||
NULL,
|
||||
NULL,
|
||||
ldb_op_default_callback,
|
||||
res,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
@ -340,12 +352,18 @@ int dsdb_module_add(struct ldb_module *module,
|
||||
int ret;
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(module);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(module);
|
||||
struct ldb_result *res;
|
||||
|
||||
res = talloc_zero(tmp_ctx, struct ldb_result);
|
||||
if (!res) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = ldb_build_add_req(&req, ldb, tmp_ctx,
|
||||
message,
|
||||
NULL,
|
||||
NULL,
|
||||
ldb_op_default_callback,
|
||||
res,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
@ -717,6 +735,7 @@ int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
|
||||
struct ldb_message *msg;
|
||||
struct dsdb_control_current_partition *p_ctrl;
|
||||
int ret;
|
||||
struct ldb_result *res;
|
||||
|
||||
msg = ldb_msg_new(module);
|
||||
if (msg == NULL) {
|
||||
@ -729,6 +748,11 @@ int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
res = talloc_zero(msg, struct ldb_result);
|
||||
if (!res) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = ldb_msg_add_fmt(msg, "uSNHighest", "%llu", (unsigned long long)uSN);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(msg);
|
||||
@ -754,11 +778,11 @@ int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
|
||||
}
|
||||
p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
|
||||
p_ctrl->dn = dn;
|
||||
|
||||
ret = ldb_build_mod_req(&req, ldb, msg,
|
||||
msg,
|
||||
NULL,
|
||||
NULL, ldb_op_default_callback,
|
||||
res,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
again:
|
||||
if (ret != LDB_SUCCESS) {
|
||||
@ -784,7 +808,8 @@ again:
|
||||
ret = ldb_build_add_req(&req, ldb, msg,
|
||||
msg,
|
||||
NULL,
|
||||
NULL, ldb_op_default_callback,
|
||||
res,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
goto again;
|
||||
}
|
||||
|
@ -174,7 +174,8 @@ static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
|
||||
/* create and execute a modify request */
|
||||
static int ldb_mod_req_with_controls(struct ldb_context *ldb,
|
||||
const struct ldb_message *message,
|
||||
struct ldb_control **controls)
|
||||
struct ldb_control **controls,
|
||||
void *context)
|
||||
{
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
@ -187,8 +188,8 @@ static int ldb_mod_req_with_controls(struct ldb_context *ldb,
|
||||
ret = ldb_build_mod_req(&req, ldb, ldb,
|
||||
message,
|
||||
controls,
|
||||
NULL,
|
||||
ldb_op_default_callback,
|
||||
context,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
|
||||
if (ret != LDB_SUCCESS) {
|
||||
@ -315,6 +316,124 @@ static NTSTATUS ldapsrv_unwilling(struct ldapsrv_call *call, int error)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
int ldb_add_with_context(struct ldb_context *ldb,
|
||||
const struct ldb_message *message,
|
||||
void *context)
|
||||
{
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
|
||||
ret = ldb_msg_sanity_check(ldb, message);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ldb_build_add_req(&req, ldb, ldb,
|
||||
message,
|
||||
NULL,
|
||||
context,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
|
||||
if (ret != LDB_SUCCESS) return ret;
|
||||
|
||||
ret = ldb_transaction_start(ldb);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ldb_request(ldb, req);
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
|
||||
}
|
||||
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_transaction_commit(ldb);
|
||||
}
|
||||
else {
|
||||
ldb_transaction_cancel(ldb);
|
||||
}
|
||||
|
||||
talloc_free(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ldb_delete_with_context(struct ldb_context *ldb,
|
||||
struct ldb_dn *dn,
|
||||
void *context)
|
||||
{
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
|
||||
ret = ldb_build_del_req(&req, ldb, ldb,
|
||||
dn,
|
||||
NULL,
|
||||
context,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
|
||||
if (ret != LDB_SUCCESS) return ret;
|
||||
|
||||
ret = ldb_transaction_start(ldb);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ldb_request(ldb, req);
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
|
||||
}
|
||||
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_transaction_commit(ldb);
|
||||
}
|
||||
else {
|
||||
ldb_transaction_cancel(ldb);
|
||||
}
|
||||
|
||||
talloc_free(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ldb_rename_with_context(struct ldb_context *ldb,
|
||||
struct ldb_dn *olddn,
|
||||
struct ldb_dn *newdn,
|
||||
void *context)
|
||||
{
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
|
||||
ret = ldb_build_rename_req(&req, ldb, ldb,
|
||||
olddn,
|
||||
newdn,
|
||||
NULL,
|
||||
context,
|
||||
ldb_modify_default_callback,
|
||||
NULL);
|
||||
|
||||
if (ret != LDB_SUCCESS) return ret;
|
||||
|
||||
ret = ldb_transaction_start(ldb);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ldb_request(ldb, req);
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
|
||||
}
|
||||
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_transaction_commit(ldb);
|
||||
}
|
||||
else {
|
||||
ldb_transaction_cancel(ldb);
|
||||
}
|
||||
|
||||
talloc_free(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
|
||||
{
|
||||
struct ldap_SearchRequest *req = &call->request->r.SearchRequest;
|
||||
@ -545,6 +664,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call)
|
||||
int result = LDAP_SUCCESS;
|
||||
int ldb_ret;
|
||||
unsigned int i,j;
|
||||
struct ldb_result *res = NULL;
|
||||
|
||||
DEBUG(10, ("ModifyRequest"));
|
||||
DEBUGADD(10, (" dn: %s", req->dn));
|
||||
@ -612,16 +732,24 @@ reply:
|
||||
NT_STATUS_HAVE_NO_MEMORY(modify_reply);
|
||||
|
||||
if (result == LDAP_SUCCESS) {
|
||||
ldb_ret = ldb_mod_req_with_controls(samdb, msg, call->request->controls);
|
||||
res = talloc_zero(local_ctx, struct ldb_result);
|
||||
NT_STATUS_HAVE_NO_MEMORY(res);
|
||||
ldb_ret = ldb_mod_req_with_controls(samdb, msg, call->request->controls, res);
|
||||
result = map_ldb_error(local_ctx, ldb_ret, &errstr);
|
||||
}
|
||||
|
||||
modify_result = &modify_reply->msg->r.AddResponse;
|
||||
modify_result->dn = NULL;
|
||||
modify_result->resultcode = result;
|
||||
modify_result->errormessage = (errstr?talloc_strdup(modify_reply, errstr):NULL);
|
||||
modify_result->referral = NULL;
|
||||
|
||||
if (res->refs != NULL) {
|
||||
modify_result->resultcode = map_ldb_error(local_ctx, LDB_ERR_REFERRAL, &errstr);
|
||||
modify_result->errormessage = (errstr?talloc_strdup(modify_reply, errstr):NULL);
|
||||
modify_result->referral = talloc_strdup(call, *res->refs);
|
||||
} else {
|
||||
modify_result->resultcode = result;
|
||||
modify_result->errormessage = (errstr?talloc_strdup(modify_reply, errstr):NULL);
|
||||
modify_result->referral = NULL;
|
||||
}
|
||||
talloc_free(local_ctx);
|
||||
|
||||
ldapsrv_queue_reply(call, modify_reply);
|
||||
@ -642,6 +770,7 @@ static NTSTATUS ldapsrv_AddRequest(struct ldapsrv_call *call)
|
||||
int result = LDAP_SUCCESS;
|
||||
int ldb_ret;
|
||||
unsigned int i,j;
|
||||
struct ldb_result *res = NULL;
|
||||
|
||||
DEBUG(10, ("AddRequest"));
|
||||
DEBUGADD(10, (" dn: %s", req->dn));
|
||||
@ -691,16 +820,23 @@ reply:
|
||||
NT_STATUS_HAVE_NO_MEMORY(add_reply);
|
||||
|
||||
if (result == LDAP_SUCCESS) {
|
||||
ldb_ret = ldb_add(samdb, msg);
|
||||
res = talloc_zero(local_ctx, struct ldb_result);
|
||||
NT_STATUS_HAVE_NO_MEMORY(res);
|
||||
ldb_ret = ldb_add_with_context(samdb, msg, res);
|
||||
result = map_ldb_error(local_ctx, ldb_ret, &errstr);
|
||||
}
|
||||
|
||||
add_result = &add_reply->msg->r.AddResponse;
|
||||
add_result->dn = NULL;
|
||||
add_result->resultcode = result;
|
||||
add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL);
|
||||
add_result->referral = NULL;
|
||||
|
||||
if (res->refs != NULL) {
|
||||
add_result->resultcode = map_ldb_error(local_ctx, LDB_ERR_REFERRAL, &errstr);
|
||||
add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL);
|
||||
add_result->referral = talloc_strdup(call, *res->refs);
|
||||
} else {
|
||||
add_result->resultcode = result;
|
||||
add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL);
|
||||
add_result->referral = NULL;
|
||||
}
|
||||
talloc_free(local_ctx);
|
||||
|
||||
ldapsrv_queue_reply(call, add_reply);
|
||||
@ -719,6 +855,7 @@ static NTSTATUS ldapsrv_DelRequest(struct ldapsrv_call *call)
|
||||
const char *errstr = NULL;
|
||||
int result = LDAP_SUCCESS;
|
||||
int ldb_ret;
|
||||
struct ldb_result *res = NULL;
|
||||
|
||||
DEBUG(10, ("DelRequest"));
|
||||
DEBUGADD(10, (" dn: %s", req->dn));
|
||||
@ -736,15 +873,23 @@ reply:
|
||||
NT_STATUS_HAVE_NO_MEMORY(del_reply);
|
||||
|
||||
if (result == LDAP_SUCCESS) {
|
||||
ldb_ret = ldb_delete(samdb, dn);
|
||||
res = talloc_zero(local_ctx, struct ldb_result);
|
||||
NT_STATUS_HAVE_NO_MEMORY(res);
|
||||
ldb_ret = ldb_delete_with_context(samdb, dn, res);
|
||||
result = map_ldb_error(local_ctx, ldb_ret, &errstr);
|
||||
}
|
||||
|
||||
del_result = &del_reply->msg->r.DelResponse;
|
||||
del_result->dn = NULL;
|
||||
del_result->resultcode = result;
|
||||
del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL);
|
||||
del_result->referral = NULL;
|
||||
if (res->refs != NULL) {
|
||||
del_result->resultcode = map_ldb_error(local_ctx, LDB_ERR_REFERRAL, &errstr);
|
||||
del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL);
|
||||
del_result->referral = talloc_strdup(call, *res->refs);
|
||||
} else {
|
||||
del_result->resultcode = result;
|
||||
del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL);
|
||||
del_result->referral = NULL;
|
||||
}
|
||||
|
||||
talloc_free(local_ctx);
|
||||
|
||||
@ -764,6 +909,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
|
||||
const char *errstr = NULL;
|
||||
int result = LDAP_SUCCESS;
|
||||
int ldb_ret;
|
||||
struct ldb_result *res = NULL;
|
||||
|
||||
DEBUG(10, ("ModifyDNRequest"));
|
||||
DEBUGADD(10, (" dn: %s", req->dn));
|
||||
@ -827,15 +973,23 @@ reply:
|
||||
NT_STATUS_HAVE_NO_MEMORY(modifydn_r);
|
||||
|
||||
if (result == LDAP_SUCCESS) {
|
||||
ldb_ret = ldb_rename(samdb, olddn, newdn);
|
||||
res = talloc_zero(local_ctx, struct ldb_result);
|
||||
NT_STATUS_HAVE_NO_MEMORY(res);
|
||||
ldb_ret = ldb_rename_with_context(samdb, olddn, newdn, res);
|
||||
result = map_ldb_error(local_ctx, ldb_ret, &errstr);
|
||||
}
|
||||
|
||||
modifydn = &modifydn_r->msg->r.ModifyDNResponse;
|
||||
modifydn->dn = NULL;
|
||||
modifydn->resultcode = result;
|
||||
modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
|
||||
modifydn->referral = NULL;
|
||||
if (res->refs != NULL) {
|
||||
modifydn->resultcode = map_ldb_error(local_ctx, LDB_ERR_REFERRAL, &errstr);;
|
||||
modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
|
||||
modifydn->referral = talloc_strdup(call, *res->refs);
|
||||
} else {
|
||||
modifydn->resultcode = result;
|
||||
modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
|
||||
modifydn->referral = NULL;
|
||||
}
|
||||
|
||||
talloc_free(local_ctx);
|
||||
|
||||
|
@ -903,6 +903,54 @@ int ldb_search_default_callback(struct ldb_request *req,
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares)
|
||||
{
|
||||
struct ldb_result *res;
|
||||
unsigned int n;
|
||||
int ret;
|
||||
|
||||
res = talloc_get_type(req->context, struct ldb_result);
|
||||
|
||||
if (!ares) {
|
||||
return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
|
||||
}
|
||||
|
||||
if (ares->error != LDB_SUCCESS) {
|
||||
ret = ares->error;
|
||||
talloc_free(ares);
|
||||
return ldb_request_done(req, ret);
|
||||
}
|
||||
|
||||
switch (ares->type) {
|
||||
case 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) {
|
||||
return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
|
||||
}
|
||||
|
||||
res->refs[n] = talloc_move(res->refs, &ares->referral);
|
||||
res->refs[n + 1] = NULL;
|
||||
break;
|
||||
|
||||
case LDB_REPLY_DONE:
|
||||
talloc_free(ares);
|
||||
return ldb_request_done(req, LDB_SUCCESS);
|
||||
default:
|
||||
talloc_free(ares);
|
||||
ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
|
||||
return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
|
||||
}
|
||||
|
||||
talloc_free(ares);
|
||||
return ldb_request_done(req, LDB_SUCCESS);
|
||||
}
|
||||
|
||||
int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1017,6 +1017,7 @@ int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares)
|
||||
*/
|
||||
int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares);
|
||||
|
||||
int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares);
|
||||
|
||||
/**
|
||||
Helper function to build a search request
|
||||
|
Loading…
Reference in New Issue
Block a user