summaryrefslogtreecommitdiff
path: root/source4/rpc_server/samr/dcesrv_samr.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-03-14 12:26:03 +1100
committerAndrew Bartlett <abartlet@samba.org>2008-03-14 12:26:03 +1100
commit9a6422b6954242e5298653eef0d12a584f0d2811 (patch)
tree3da9e88d26aa760922f9ebb5c60ace1510fa9ea8 /source4/rpc_server/samr/dcesrv_samr.c
parent39f03829a626388e8396a14c265d2f95520b0e98 (diff)
downloadsamba-9a6422b6954242e5298653eef0d12a584f0d2811.tar.gz
samba-9a6422b6954242e5298653eef0d12a584f0d2811.tar.bz2
samba-9a6422b6954242e5298653eef0d12a584f0d2811.zip
Rework our SAMR test and SAMR server.
Now that we don't create users/domain groups/aliases in the builtin domain, we hit some bugs in the server-side implementation of the enumeration functions. In essence, it turns out to be: don't treat 0 as a special case. Also, fix up the PDC name to always be returned. I'm sure nothing actually uses it, particularly for BUILTIN... Andrew Bartlett (This used to be commit 353bb79f568f20c8469cb9458f7b14c24612ad23)
Diffstat (limited to 'source4/rpc_server/samr/dcesrv_samr.c')
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 0a5d7e1bc9..0aa4d65d8c 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -475,6 +475,14 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
}
d_state->access_mask = r->in.access_mask;
+ if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+ d_state->builtin = true;
+ } else {
+ d_state->builtin = false;
+ }
+
+ d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+
h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);
if (!h_domain) {
talloc_free(d_state);
@@ -523,6 +531,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo2(struct samr_domain_state *state,
string */
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, dom_msgs[0], "fSMORoleOwner");
+ if (!info->primary.string) {
+ info->primary.string = lp_netbios_name(state->lp_ctx);
+ }
+
info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff",
0x8000000000000000LL);
@@ -617,6 +629,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo6(struct samr_domain_state *state,
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx,
dom_msgs[0], "fSMORoleOwner");
+ if (!info->primary.string) {
+ info->primary.string = lp_netbios_name(state->lp_ctx);
+ }
+
return NT_STATUS_OK;
}
@@ -1007,6 +1023,11 @@ static NTSTATUS dcesrv_samr_CreateDomainGroup(struct dcesrv_call_state *dce_call
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a domain group in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
groupname = r->in.name->string;
if (groupname == NULL) {
@@ -1133,9 +1154,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
if (ldb_cnt == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (ldb_cnt == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to SamEntry format */
entries = talloc_array(mem_ctx, struct samr_SamEntry, ldb_cnt);
@@ -1169,10 +1187,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
first<count && entries[first].idx <= *r->in.resume_handle;
first++) ;
- if (first == count) {
- return NT_STATUS_OK;
- }
-
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
r->out.num_entries = count - first;
@@ -1237,6 +1251,10 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a user in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
account_name = r->in.account_name->string;
if (account_name == NULL) {
@@ -1321,15 +1339,16 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
/* create the user */
ret = ldb_add(d_state->sam_ctx, msg);
switch (ret) {
- case LDB_SUCCESS:
+ case LDB_SUCCESS:
break;
- case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_USER_EXISTS;
- case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ case LDB_ERR_UNWILLING_TO_PERFORM:
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
@@ -1469,8 +1488,8 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
- struct ldb_message **res;
- int count, num_filtered_entries, i, first;
+ struct ldb_result *res;
+ int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
@@ -1482,32 +1501,30 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
d_state = h->data;
- /* search for all users in this domain. This could possibly be cached and
- resumed based on resume_key */
- count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
- "objectclass=user");
- if (count == -1) {
+ /* don't have to worry about users in the builtin domain, as there are none */
+ ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=user");
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(3, ("Failed to search for Domain Users in %s: %s\n",
+ ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (count == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to SamEntry format */
- entries = talloc_array(mem_ctx, struct samr_SamEntry, count);
+ entries = talloc_array(mem_ctx, struct samr_SamEntry, res->count);
if (!entries) {
return NT_STATUS_NO_MEMORY;
}
num_filtered_entries = 0;
- for (i=0;i<count;i++) {
+ for (i=0;i<res->count;i++) {
/* Check if a mask has been requested */
if (r->in.acct_flags
- && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res[i],
+ && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res->msgs[i],
d_state->domain_dn) & r->in.acct_flags) == 0)) {
continue;
}
- entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
- entries[num_filtered_entries].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+ entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res->msgs[i], "objectSid", 0);
+ entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", "");
num_filtered_entries++;
}
@@ -1569,6 +1586,11 @@ static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, T
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a domain alias in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
alias_name = r->in.alias_name->string;
if (alias_name == NULL) {