}
/* make sure the sam database is accessible */
- c_state->sam_ctx = samdb_connect(c_state, 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, dce_call->conn->auth_state.session_info);
if (c_state->sam_ctx == NULL) {
talloc_free(c_state);
return NT_STATUS_INVALID_SYSTEM_SERVICE;
struct samr_connect_state *c_state;
struct dcesrv_handle *h;
struct samr_SamArray *array;
- int count, i, start_i;
+ int i, start_i, ret;
const char * const dom_attrs[] = { "cn", NULL};
const char * const ref_attrs[] = { "nETBIOSName", NULL};
- struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
+ struct ldb_result *dom_res;
+ struct ldb_result *ref_res;
struct ldb_dn *partitions_basedn;
*r->out.resume_handle = 0;
partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
- count = gendb_search(c_state->sam_ctx,
- mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(objectClass=domain)");
- if (count == -1) {
- DEBUG(0,("samdb: no domains found in EnumDomains\n"));
+ ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &dom_res, ldb_get_default_basedn(c_state->sam_ctx),
+ LDB_SCOPE_SUBTREE, dom_attrs, "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- *r->out.resume_handle = count;
+ *r->out.resume_handle = dom_res->count;
start_i = *r->in.resume_handle;
- if (start_i >= count) {
+ if (start_i >= dom_res->count) {
/* search past end of list is not an error for this call */
return NT_STATUS_OK;
}
array->count = 0;
array->entries = NULL;
- array->entries = talloc_array(mem_ctx, struct samr_SamEntry, count - start_i);
+ array->entries = talloc_array(mem_ctx, struct samr_SamEntry, dom_res->count - start_i);
if (array->entries == NULL) {
return NT_STATUS_NO_MEMORY;
}
- for (i=0;i<count-start_i;i++) {
- int ret;
+ for (i=0;i<dom_res->count-start_i;i++) {
array->entries[i].idx = start_i + i;
/* try and find the domain */
- ret = gendb_search(c_state->sam_ctx, mem_ctx, partitions_basedn,
- &ref_msgs, ref_attrs,
- "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(dom_msgs[i]->dn));
- if (ret == 1) {
- array->entries[i].name.string = samdb_result_string(ref_msgs[0], "nETBIOSName", NULL);
+ ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &ref_res, partitions_basedn,
+ LDB_SCOPE_SUBTREE, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))",
+ ldb_dn_get_linearized(dom_res->msgs[i]->dn));
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (ref_res->count == 1) {
+ array->entries[i].name.string = samdb_result_string(ref_res->msgs[0], "nETBIOSName", NULL);
} else {
- array->entries[i].name.string = samdb_result_string(dom_msgs[i], "cn", NULL);
+ array->entries[i].name.string = samdb_result_string(dom_res->msgs[i], "cn", NULL);
}
}
ret = gendb_search(c_state->sam_ctx,
mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(&(objectSid=%s)(&(|(objectclass=domain)(objectClass=builtinDomain))))",
+ "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
if (ret == 0) {
return NT_STATUS_NO_SUCH_DOMAIN;
}
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);
/*
return DomInfo2
*/
-static NTSTATUS dcesrv_samr_info_DomInfo2(struct samr_domain_state *state,
- TALLOC_CTX *mem_ctx,
- struct ldb_message **dom_msgs,
- struct samr_DomInfo2 *info)
+static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state *state,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_message **dom_msgs,
+ struct samr_DomGeneralInformation *info)
{
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
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);
- info->comment.string = samdb_result_string(dom_msgs[0], "comment", NULL);
+ info->oem_information.string = samdb_result_string(dom_msgs[0], "oEMInformation", NULL);
info->domain_name.string = state->domain_name;
info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount",
/*
return DomInfo4
*/
-static NTSTATUS dcesrv_samr_info_DomInfo4(struct samr_domain_state *state,
+static NTSTATUS dcesrv_samr_info_DomOEMInformation(struct samr_domain_state *state,
TALLOC_CTX *mem_ctx,
struct ldb_message **dom_msgs,
- struct samr_DomInfo4 *info)
+ struct samr_DomOEMInformation *info)
{
- info->comment.string = samdb_result_string(dom_msgs[0], "comment", NULL);
+ info->oem_information.string = samdb_result_string(dom_msgs[0], "oEMInformation", NULL);
return NT_STATUS_OK;
}
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;
}
/*
return DomInfo11
*/
-static NTSTATUS dcesrv_samr_info_DomInfo11(struct samr_domain_state *state,
+static NTSTATUS dcesrv_samr_info_DomGeneralInformation2(struct samr_domain_state *state,
TALLOC_CTX *mem_ctx,
struct ldb_message **dom_msgs,
- struct samr_DomInfo11 *info)
+ struct samr_DomGeneralInformation2 *info)
{
NTSTATUS status;
- status = dcesrv_samr_info_DomInfo2(state, mem_ctx, dom_msgs, &info->info2);
+ status = dcesrv_samr_info_DomGeneralInformation(state, mem_ctx, dom_msgs, &info->general);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case 2:
{
static const char * const attrs2[] = {"forceLogoff",
- "comment",
+ "oEMInformation",
"modifiedCount",
"fSMORoleOwner",
NULL};
}
case 4:
{
- static const char * const attrs2[] = {"comment",
+ static const char * const attrs2[] = {"oEMInformation",
NULL};
attrs = attrs2;
break;
break;
case 11:
{
- static const char * const attrs2[] = { "comment", "forceLogoff",
+ static const char * const attrs2[] = { "oEMInformation", "forceLogoff",
"modifiedCount",
"lockoutDuration",
"lockOutObservationWindow",
switch (r->in.level) {
case 1:
return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs,
- &r->out.info->info1);
+ &r->out.info->info1);
case 2:
- return dcesrv_samr_info_DomInfo2(d_state, mem_ctx, dom_msgs,
- &r->out.info->info2);
+ return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs,
+ &r->out.info->general);
case 3:
return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs,
- &r->out.info->info3);
+ &r->out.info->info3);
case 4:
- return dcesrv_samr_info_DomInfo4(d_state, mem_ctx, dom_msgs,
- &r->out.info->info4);
+ return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs,
+ &r->out.info->oem);
case 5:
return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs,
- &r->out.info->info5);
+ &r->out.info->info5);
case 6:
return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs,
- &r->out.info->info6);
+ &r->out.info->info6);
case 7:
return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs,
- &r->out.info->info7);
+ &r->out.info->info7);
case 8:
return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs,
- &r->out.info->info8);
+ &r->out.info->info8);
case 9:
return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs,
- &r->out.info->info9);
+ &r->out.info->info9);
case 11:
- return dcesrv_samr_info_DomInfo11(d_state, mem_ctx, dom_msgs,
- &r->out.info->info11);
+ return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs,
+ &r->out.info->general2);
case 12:
return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs,
- &r->out.info->info12);
+ &r->out.info->info12);
case 13:
return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs,
- &r->out.info->info13);
+ &r->out.info->info13);
}
-
+
return NT_STATUS_INVALID_INFO_CLASS;
}
SET_INT64 (msg, info1.min_password_age, "minPwdAge");
break;
case 3:
- SET_UINT64 (msg, info3.force_logoff_time, "forceLogoff");
+ SET_UINT64 (msg, info3.force_logoff_time, "forceLogoff");
break;
case 4:
- SET_STRING(msg, info4.comment, "comment");
+ SET_STRING(msg, oem.oem_information, "oEMInformation");
break;
case 6:
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) {
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);
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;
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) {
/* 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),
{
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 };
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++;
}
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) {
{
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- struct ldb_message *msg, **res;
+ struct ldb_message *msg;
+ struct ldb_result *res;
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
a_state = h->data;
+
+ ret = ldb_search_exp_fmt(a_state->sam_ctx, mem_ctx, &res, a_state->account_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=*");
+
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ return NT_STATUS_NO_SUCH_GROUP;
+ } else if (ret != LDB_SUCCESS) {
+ DEBUG(2, ("Error reading group info: %s\n", ldb_errstring(a_state->sam_ctx)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
- /* pull all the group attributes */
- ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- a_state->account_dn, &res, attrs);
- if (ret != 1) {
+ if (res->count != 1) {
+ DEBUG(2, ("Error finding group info, got %d entries\n", res->count));
+
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- msg = res[0];
+ msg = res->msgs[0];
/* allocate the info structure */
r->out.info = talloc(mem_ctx, union samr_GroupInfo);
case 1:
{
static const char * const attrs2[] = {"sAMAccountName", "displayName",
- "primaryGroupID", "description",
+ "primaryroupID", "description",
"comment", NULL};
attrs = attrs2;
break;
ZERO_STRUCT(r->out.info);
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}