#include "param/param.h"
#include "smbd/service_stream.h"
#include "dsdb/samdb/samdb.h"
-#include "lib/ldb/include/ldb_errors.h"
-#include "lib/ldb/include/ldb_module.h"
+#include <ldb_errors.h>
+#include <ldb_module.h>
#include "ldb_wrap.h"
-#define VALID_DN_SYNTAX(dn) do {\
- if (!(dn)) {\
- return NT_STATUS_NO_MEMORY;\
- } else if ( ! ldb_dn_validate(dn)) {\
- result = LDAP_INVALID_DN_SYNTAX;\
- map_ldb_error(local_ctx, LDB_ERR_INVALID_DN_SYNTAX, NULL,\
- &errstr);\
- goto reply;\
- }\
-} while(0)
-
static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
const char *add_err_string, const char **errstring)
{
}
*errstring = talloc_asprintf(mem_ctx, "%08X: %s", W_ERROR_V(err),
- ldb_strerror(ldb_err));
- if (add_err_string != NULL) {
- *errstring = talloc_asprintf(mem_ctx, "%s - %s", *errstring,
- add_err_string);
- }
-
+ add_err_string != NULL ? add_err_string : ldb_strerror(ldb_err));
+
/* result is 1:1 for now */
return ldb_err;
}
return NT_STATUS_OK;
}
-static int ldb_add_with_controls(struct ldb_context *ldb,
- const struct ldb_message *message,
- struct ldb_control **controls,
- void *context)
+static int ldapsrv_add_with_controls(struct ldapsrv_call *call,
+ const struct ldb_message *message,
+ struct ldb_control **controls,
+ void *context)
{
+ struct ldb_context *ldb = call->conn->ldb;
struct ldb_request *req;
int ret;
if (ret != LDB_SUCCESS) return ret;
+ if (call->conn->global_catalog) {
+ return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, "modify forbidden on global catalog port");
+ }
+ ldb_request_add_control(req, DSDB_CONTROL_NO_GLOBAL_CATALOG, false, NULL);
+
ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
return ret;
}
- ldb_req_mark_untrusted(req);
+ if (!call->conn->is_privileged) {
+ ldb_req_mark_untrusted(req);
+ }
LDB_REQ_SET_LOCATION(req);
}
/* create and execute a modify request */
-static int ldb_mod_req_with_controls(struct ldb_context *ldb,
+static int ldapsrv_mod_with_controls(struct ldapsrv_call *call,
const struct ldb_message *message,
struct ldb_control **controls,
void *context)
{
+ struct ldb_context *ldb = call->conn->ldb;
struct ldb_request *req;
int ret;
return ret;
}
+ if (call->conn->global_catalog) {
+ return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, "modify forbidden on global catalog port");
+ }
+ ldb_request_add_control(req, DSDB_CONTROL_NO_GLOBAL_CATALOG, false, NULL);
+
ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
return ret;
}
- ldb_req_mark_untrusted(req);
+ if (!call->conn->is_privileged) {
+ ldb_req_mark_untrusted(req);
+ }
LDB_REQ_SET_LOCATION(req);
}
/* create and execute a delete request */
-static int ldb_del_req_with_controls(struct ldb_context *ldb,
+static int ldapsrv_del_with_controls(struct ldapsrv_call *call,
struct ldb_dn *dn,
struct ldb_control **controls,
void *context)
{
+ struct ldb_context *ldb = call->conn->ldb;
struct ldb_request *req;
int ret;
if (ret != LDB_SUCCESS) return ret;
+ if (call->conn->global_catalog) {
+ return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, "modify forbidden on global catalog port");
+ }
+ ldb_request_add_control(req, DSDB_CONTROL_NO_GLOBAL_CATALOG, false, NULL);
+
ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
return ret;
}
- ldb_req_mark_untrusted(req);
+ if (!call->conn->is_privileged) {
+ ldb_req_mark_untrusted(req);
+ }
LDB_REQ_SET_LOCATION(req);
return ret;
}
-int ldb_rename_with_controls(struct ldb_context *ldb,
- struct ldb_dn *olddn,
- struct ldb_dn *newdn,
- struct ldb_control **controls,
- void *context)
+static int ldapsrv_rename_with_controls(struct ldapsrv_call *call,
+ struct ldb_dn *olddn,
+ struct ldb_dn *newdn,
+ struct ldb_control **controls,
+ void *context)
{
+ struct ldb_context *ldb = call->conn->ldb;
struct ldb_request *req;
int ret;
if (ret != LDB_SUCCESS) return ret;
+ if (call->conn->global_catalog) {
+ return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, "modify forbidden on global catalog port");
+ }
+ ldb_request_add_control(req, DSDB_CONTROL_NO_GLOBAL_CATALOG, false, NULL);
+
ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
return ret;
}
- ldb_req_mark_untrusted(req);
+ if (!call->conn->is_privileged) {
+ ldb_req_mark_untrusted(req);
+ }
LDB_REQ_SET_LOCATION(req);
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
basedn = ldb_dn_new(local_ctx, samdb, req->basedn);
- VALID_DN_SYNTAX(basedn);
+ NT_STATUS_HAVE_NO_MEMORY(basedn);
DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn));
DEBUG(10, ("SearchRequest: filter: [%s]\n", ldb_filter_from_tree(call, req->tree)));
search_options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
ldb_request_add_control(lreq, LDB_CONTROL_SEARCH_OPTIONS_OID, false, search_options);
}
+ } else {
+ ldb_request_add_control(lreq, DSDB_CONTROL_NO_GLOBAL_CATALOG, false, NULL);
}
extended_dn_control = ldb_request_get_control(lreq, LDB_CONTROL_EXTENDED_DN_OID);
}
}
- ldb_request_add_control(lreq, DSDB_CONTROL_SEARCH_APPLY_ACCESS, false, NULL);
ldb_set_timeout(samdb, lreq, req->timelimit);
- ldb_req_mark_untrusted(lreq);
+ if (!call->conn->is_privileged) {
+ ldb_req_mark_untrusted(lreq);
+ }
LDB_REQ_SET_LOCATION(lreq);
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn);
+ NT_STATUS_HAVE_NO_MEMORY(dn);
DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
if (result == LDAP_SUCCESS) {
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);
+ ldb_ret = ldapsrv_mod_with_controls(call, msg, call->request->controls, res);
result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
&errstr);
}
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn);
+ NT_STATUS_HAVE_NO_MEMORY(dn);
DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn));
}
}
-reply:
add_reply = ldapsrv_init_reply(call, LDAP_TAG_AddResponse);
NT_STATUS_HAVE_NO_MEMORY(add_reply);
if (result == LDAP_SUCCESS) {
res = talloc_zero(local_ctx, struct ldb_result);
NT_STATUS_HAVE_NO_MEMORY(res);
- ldb_ret = ldb_add_with_controls(samdb, msg, call->request->controls, res);
+ ldb_ret = ldapsrv_add_with_controls(call, msg, call->request->controls, res);
result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
&errstr);
}
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn);
+ NT_STATUS_HAVE_NO_MEMORY(dn);
DEBUG(10, ("DelRequest: dn: [%s]\n", req->dn));
-reply:
del_reply = ldapsrv_init_reply(call, LDAP_TAG_DelResponse);
NT_STATUS_HAVE_NO_MEMORY(del_reply);
if (result == LDAP_SUCCESS) {
res = talloc_zero(local_ctx, struct ldb_result);
NT_STATUS_HAVE_NO_MEMORY(res);
- ldb_ret = ldb_del_req_with_controls(samdb, dn, call->request->controls, res);
+ ldb_ret = ldapsrv_del_with_controls(call, dn, call->request->controls, res);
result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
&errstr);
}
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
olddn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(olddn);
+ NT_STATUS_HAVE_NO_MEMORY(olddn);
newrdn = ldb_dn_new(local_ctx, samdb, req->newrdn);
- VALID_DN_SYNTAX(newrdn);
+ NT_STATUS_HAVE_NO_MEMORY(newrdn);
DEBUG(10, ("ModifyDNRequest: olddn: [%s]\n", req->dn));
DEBUG(10, ("ModifyDNRequest: newrdn: [%s]\n", req->newrdn));
}
if (req->newsuperior) {
- parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior);
- VALID_DN_SYNTAX(parentdn);
DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior));
+ parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior);
}
if (!parentdn) {
if (result == LDAP_SUCCESS) {
res = talloc_zero(local_ctx, struct ldb_result);
NT_STATUS_HAVE_NO_MEMORY(res);
- ldb_ret = ldb_rename_with_controls(samdb, olddn, newdn, call->request->controls, res);
+ ldb_ret = ldapsrv_rename_with_controls(call, olddn, newdn, call->request->controls, res);
result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
&errstr);
}
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn);
+ NT_STATUS_HAVE_NO_MEMORY(dn);
DEBUG(10, ("CompareRequest: dn: [%s]\n", req->dn));
filter = talloc_asprintf(local_ctx, "(%s=%*s)", req->attribute,
attrs[0] = NULL;
-reply:
compare_r = ldapsrv_init_reply(call, LDAP_TAG_CompareResponse);
NT_STATUS_HAVE_NO_MEMORY(compare_r);
{
unsigned int i;
struct ldap_message *msg = call->request;
+ struct ldb_context *samdb = call->conn->ldb;
+ NTSTATUS status;
+ time_t *lastts;
/* Check for undecoded critical extensions */
for (i=0; msg->controls && msg->controls[i]; i++) {
if (!msg->controls_decoded[i] &&
case LDAP_TAG_SearchRequest:
return ldapsrv_SearchRequest(call);
case LDAP_TAG_ModifyRequest:
- return ldapsrv_ModifyRequest(call);
+ status = ldapsrv_ModifyRequest(call);
+ break;
case LDAP_TAG_AddRequest:
- return ldapsrv_AddRequest(call);
+ status = ldapsrv_AddRequest(call);
+ break;
case LDAP_TAG_DelRequest:
return ldapsrv_DelRequest(call);
case LDAP_TAG_ModifyDNRequest:
default:
return ldapsrv_unwilling(call, LDAP_PROTOCOL_ERROR);
}
+
+ if (NT_STATUS_IS_OK(status)) {
+ lastts = (time_t *)ldb_get_opaque(samdb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME);
+ if (lastts && !*lastts) {
+ DEBUG(10, ("Schema update now was requested, fullfilling the request ts = %d\n", lastts));
+ /*
+ * Just requesting the schema will do the trick
+ * as the delay for reload is experied, we will have a reload
+ * from the schema as expected as we are not yet in a transaction!
+ */
+ dsdb_get_schema(samdb, NULL);
+ *lastts = time(NULL);
+ ldb_set_opaque(samdb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME, lastts);
+ }
+ }
+ return status;
}