#include "../lib/util/util_ldb.h"
#include "param/param.h"
#include "lib/util/tsort.h"
+#include "auth/auth.h"
+#include "auth/session.h"
/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
} \
} while (0)
-
+static NTSTATUS dcesrv_samr_access_check(struct dcesrv_call_state *dce_call)
+{
+ if (security_token_is_system(dce_call->conn->auth_state.session_info->security_token) ||
+ security_token_has_builtin_administrators(dce_call->conn->auth_state.session_info->security_token)) {
+ return NT_STATUS_OK;
+ } else {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+}
/*
samr_Connect
}
/* make sure the sam database is accessible */
- c_state->sam_ctx = samdb_connect(c_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ c_state->sam_ctx = samdb_connect(c_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
+ system_session(dce_call->conn->dce_ctx->lp_ctx));
if (c_state->sam_ctx == NULL) {
talloc_free(c_state);
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
handle->data = talloc_steal(handle, c_state);
-
c_state->access_mask = r->in.access_mask;
*r->out.connect_handle = handle->wire_handle;
struct ldb_message *msg;
int ret;
struct ldb_context *sam_ctx;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
return NT_STATUS_INVALID_INFO_CLASS;
}
+ /* writes are only allowed to system or administrator */
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
/* modify the samdb record */
ret = ldb_modify(sam_ctx, msg);
if (ret != LDB_SUCCESS) {
struct ldb_message *msg;
struct ldb_context *sam_ctx;
int ret;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
return NT_STATUS_INVALID_INFO_CLASS;
}
+/* writes are only allowed to system or administrator */
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* modify the samdb record */
ret = ldb_modify(g_state->sam_ctx, msg);
if (ret != LDB_SUCCESS) {
struct ldb_result *res;
const char * const attrs[] = { NULL };
int ret;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
return NT_STATUS_UNSUCCESSFUL;
}
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
case LDB_SUCCESS:
struct dcesrv_handle *h;
struct samr_account_state *a_state;
int ret;
+ NTSTATUS status;
*r->out.group_handle = *r->in.group_handle;
a_state = h->data;
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != LDB_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
struct ldb_result *res;
const char * const attrs[] = { NULL };
int ret;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
return NT_STATUS_NO_MEMORY;
}
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
case LDB_SUCCESS:
struct ldb_message *msg;
struct ldb_context *sam_ctx;
int ret;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
return NT_STATUS_INVALID_INFO_CLASS;
}
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
/* modify the samdb record */
ret = ldb_modify(a_state->sam_ctx, msg);
if (ret != LDB_SUCCESS) {
struct dcesrv_handle *h;
struct samr_account_state *a_state;
int ret;
+ NTSTATUS status;
*r->out.alias_handle = *r->in.alias_handle;
a_state = h->data;
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != LDB_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_UNSUCCESSFUL;
}
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
case LDB_SUCCESS:
struct ldb_message *mod;
const char *memberdn;
int ret;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
return NT_STATUS_UNSUCCESSFUL;
}
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
case LDB_SUCCESS:
struct dcesrv_handle *h;
struct samr_account_state *a_state;
int ret;
+ NTSTATUS status;
*r->out.user_handle = *r->in.user_handle;
a_state = h->data;
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != LDB_SUCCESS) {
DEBUG(1, ("Failed to delete user: %s: %s\n",
return status;
}
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* modify the samdb record */
if (msg->num_elements > 0) {
ret = ldb_modify(a_state->sam_ctx, msg);
struct ldb_message **res;
const char * const attrs[3] = { "distinguishedName", "objectSid", NULL };
int i, count;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
if (count < 0)
return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ status = dcesrv_samr_access_check(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
for (i=0; i<count; i++) {
struct ldb_message *mod;
sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
dce_call->conn->dce_ctx->lp_ctx,
- dce_call->conn->auth_state.session_info);
+ system_session(dce_call->conn->dce_ctx->lp_ctx));
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}