#include "includes.h"
#include "rpc_server/dcerpc_server.h"
#include "dsdb/samdb/samdb.h"
-#include "libcli/security/dom_sid.h"
-#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
#include "libcli/security/security.h"
+#include "libcli/security/session.h"
#include "param/param.h"
-
-/*
- format a drsuapi_DsReplicaObjectIdentifier naming context as a string
- */
-char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx,
- struct drsuapi_DsReplicaObjectIdentifier *nc)
-{
- char *guid, *sid, *ret;
- guid = GUID_string(mem_ctx, &nc->guid);
- sid = dom_sid_string(mem_ctx, &nc->sid);
- ret = talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
- guid, sid, nc->dn);
- talloc_free(guid);
- talloc_free(sid);
- return ret;
-}
+#include "auth/session.h"
int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx,
struct ldb_dn *basedn,
enum ldb_scope scope,
const char * const *attrs,
- const char *sort_attrib,
const char *filter)
{
int ret;
return ret;
}
- ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
+ ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_RECYCLED_OID, true, NULL);
if (ret != LDB_SUCCESS) {
return ret;
}
- if (sort_attrib) {
- struct ldb_server_sort_control **sort_control;
- sort_control = talloc_array(req, struct ldb_server_sort_control *, 2);
- if (sort_control == NULL) {
- talloc_free(tmp_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- sort_control[0] = talloc(req, struct ldb_server_sort_control);
- sort_control[0]->attributeName = sort_attrib;
- sort_control[0]->orderingRule = NULL;
- sort_control[0]->reverse = 0;
- sort_control[1] = NULL;
-
- ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, sort_control);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
+ ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
-
ret = ldb_request(ldb, req);
if (ret == LDB_SUCCESS) {
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
return ret;
}
-WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, const char* call)
+WERROR drs_security_level_check(struct dcesrv_call_state *dce_call,
+ const char* call,
+ enum security_user_level minimum_level,
+ const struct dom_sid *domain_sid)
{
- if (lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL,
+ enum security_user_level level;
+
+ if (lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL,
"drs", "disable_sec_check", false)) {
return WERR_OK;
}
- if (security_session_user_level(dce_call->conn->auth_state.session_info) <
- SECURITY_DOMAIN_CONTROLLER) {
+ level = security_session_user_level(dce_call->conn->auth_state.session_info, domain_sid);
+ if (level < minimum_level) {
if (call) {
- DEBUG(0,("%s refused for security token\n", call));
+ DEBUG(0,("%s refused for security token (level=%u)\n",
+ call, (unsigned)level));
+ security_token_debug(0, 2, dce_call->conn->auth_state.session_info->security_token);
}
return WERR_DS_DRA_ACCESS_DENIED;
}
}
switch (attr->attid) {
- case DRSUAPI_ATTRIBUTE_dBCSPwd:
- case DRSUAPI_ATTRIBUTE_unicodePwd:
- case DRSUAPI_ATTRIBUTE_ntPwdHistory:
- case DRSUAPI_ATTRIBUTE_lmPwdHistory:
- case DRSUAPI_ATTRIBUTE_supplementalCredentials:
- case DRSUAPI_ATTRIBUTE_priorValue:
- case DRSUAPI_ATTRIBUTE_currentValue:
- case DRSUAPI_ATTRIBUTE_trustAuthOutgoing:
- case DRSUAPI_ATTRIBUTE_trustAuthIncoming:
- case DRSUAPI_ATTRIBUTE_initialAuthOutgoing:
- case DRSUAPI_ATTRIBUTE_initialAuthIncoming:
+ case DRSUAPI_ATTID_dBCSPwd:
+ case DRSUAPI_ATTID_unicodePwd:
+ case DRSUAPI_ATTID_ntPwdHistory:
+ case DRSUAPI_ATTID_lmPwdHistory:
+ case DRSUAPI_ATTID_supplementalCredentials:
+ case DRSUAPI_ATTID_priorValue:
+ case DRSUAPI_ATTID_currentValue:
+ case DRSUAPI_ATTID_trustAuthOutgoing:
+ case DRSUAPI_ATTID_trustAuthIncoming:
+ case DRSUAPI_ATTID_initialAuthOutgoing:
+ case DRSUAPI_ATTID_initialAuthIncoming:
/*set value to null*/
attr->value_ctr.num_values = 0;
talloc_free(attr->value_ctr.values);
default:
return;
}
- return;
+}
+
+
+/*
+ check security on a DN, with logging of errors
+ */
+static WERROR drs_security_access_check_log(struct ldb_context *sam_ctx,
+ TALLOC_CTX *mem_ctx,
+ struct security_token *token,
+ struct ldb_dn *dn,
+ const char *ext_right)
+{
+ int ret;
+ if (!dn) {
+ DEBUG(3,("drs_security_access_check: Null dn provided, access is denied for %s\n",
+ ext_right));
+ return WERR_DS_DRA_ACCESS_DENIED;
+ }
+ ret = dsdb_check_access_on_dn(sam_ctx,
+ mem_ctx,
+ dn,
+ token,
+ SEC_ADS_CONTROL_ACCESS,
+ ext_right);
+ if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+ DEBUG(3,("%s refused for security token on %s\n",
+ ext_right, ldb_dn_get_linearized(dn)));
+ security_token_debug(2, 0, token);
+ return WERR_DS_DRA_ACCESS_DENIED;
+ } else if (ret != LDB_SUCCESS) {
+ DEBUG(1,("Failed to perform access check on %s\n", ldb_dn_get_linearized(dn)));
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+ return WERR_OK;
+}
+
+
+/*
+ check security on a object identifier
+ */
+WERROR drs_security_access_check(struct ldb_context *sam_ctx,
+ TALLOC_CTX *mem_ctx,
+ struct security_token *token,
+ struct drsuapi_DsReplicaObjectIdentifier *nc,
+ const char *ext_right)
+{
+ struct ldb_dn *dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, nc);
+ WERROR werr;
+ werr = drs_security_access_check_log(sam_ctx, mem_ctx, token, dn, ext_right);
+ talloc_free(dn);
+ return werr;
+}
+
+/*
+ check security on the NC root of a object identifier
+ */
+WERROR drs_security_access_check_nc_root(struct ldb_context *sam_ctx,
+ TALLOC_CTX *mem_ctx,
+ struct security_token *token,
+ struct drsuapi_DsReplicaObjectIdentifier *nc,
+ const char *ext_right)
+{
+ struct ldb_dn *dn, *nc_root;
+ WERROR werr;
+ int ret;
+
+ dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, nc);
+ W_ERROR_HAVE_NO_MEMORY(dn);
+ ret = dsdb_find_nc_root(sam_ctx, dn, dn, &nc_root);
+ if (ret != LDB_SUCCESS) {
+ return WERR_DS_CANT_FIND_EXPECTED_NC;
+ }
+ werr = drs_security_access_check_log(sam_ctx, mem_ctx, token, nc_root, ext_right);
+ talloc_free(dn);
+ return werr;
}