#include "rpc_server/common/common.h"
#include "rpc_server/samr/dcesrv_samr.h"
#include "system/time.h"
-#include "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_errors.h"
+#include <ldb.h>
+#include <ldb_errors.h>
#include "../libds/common/flags.h"
#include "dsdb/samdb/samdb.h"
#include "dsdb/common/util.h"
#include "../lib/util/util_ldb.h"
#include "param/param.h"
#include "lib/util/tsort.h"
+#include "libds/common/flag_mapping.h"
/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount",
0);
switch (state->role) {
- case ROLE_DOMAIN_CONTROLLER:
+ case ROLE_ACTIVE_DIRECTORY_DC:
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
string */
info->role = SAMR_ROLE_DOMAIN_BDC;
}
break;
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ return NT_STATUS_INTERNAL_ERROR;
case ROLE_DOMAIN_MEMBER:
info->role = SAMR_ROLE_DOMAIN_MEMBER;
break;
{
switch (state->role) {
- case ROLE_DOMAIN_CONTROLLER:
+ case ROLE_ACTIVE_DIRECTORY_DC:
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
string */
info->role = SAMR_ROLE_DOMAIN_BDC;
}
break;
+ case ROLE_DOMAIN_PDC:
+ info->role = SAMR_ROLE_DOMAIN_PDC;
+ break;
case ROLE_DOMAIN_MEMBER:
info->role = SAMR_ROLE_DOMAIN_MEMBER;
break;
DEBUG(1,("Failed to modify record %s: %s\n",
ldb_dn_get_linearized(d_state->domain_dn),
ldb_errstring(sam_ctx)));
-
- /* we really need samdb.c to return NTSTATUS */
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
return NT_STATUS_OK;
return NT_STATUS_INVALID_PARAMETER;
}
- status = dsdb_add_user(d_state->sam_ctx, mem_ctx, account_name, r->in.acct_flags, &sid, &dn);
+ status = dsdb_add_user(d_state->sam_ctx, mem_ctx, account_name, r->in.acct_flags, NULL,
+ &sid, &dn);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
a_state = talloc(mem_ctx, struct samr_account_state);
if (!a_state) {
- ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_NO_MEMORY;
}
a_state->sam_ctx = d_state->sam_ctx;
/* modify the samdb record */
ret = ldb_modify(g_state->sam_ctx, msg);
if (ret != LDB_SUCCESS) {
- /* we really need samdb.c to return NTSTATUS */
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
return NT_STATUS_OK;
ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member",
memberdn);
if (ret != LDB_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
ret = ldb_modify(a_state->sam_ctx, mod);
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
return NT_STATUS_ACCESS_DENIED;
default:
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
}
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != LDB_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
talloc_free(h);
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
return NT_STATUS_ACCESS_DENIED;
default:
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
}
/* modify the samdb record */
ret = ldb_modify(a_state->sam_ctx, msg);
if (ret != LDB_SUCCESS) {
- /* we really need samdb.c to return NTSTATUS */
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
return NT_STATUS_OK;
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != LDB_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
talloc_free(h);
ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member",
ldb_dn_alloc_linearized(mem_ctx, memberdn));
if (ret != LDB_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
ret = ldb_modify(a_state->sam_ctx, mod);
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
return NT_STATUS_ACCESS_DENIED;
default:
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
}
ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member",
memberdn);
if (ret != LDB_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
ret = ldb_modify(a_state->sam_ctx, mod);
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
return NT_STATUS_ACCESS_DENIED;
default:
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
}
DEBUG(1, ("Failed to delete user: %s: %s\n",
ldb_dn_get_linearized(a_state->account_dn),
ldb_errstring(a_state->sam_ctx)));
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
talloc_free(h);
}
if (r->in.info->info26.password_expired > 0) {
+ NTTIME t = 0;
struct ldb_message_element *set_el;
- if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, "pwdLastSet", 0) != LDB_SUCCESS) {
+ if (r->in.info->info26.password_expired
+ == PASS_DONT_CHANGE_AT_NEXT_LOGON) {
+ unix_to_nt_time(&t, time(NULL));
+ }
+ if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg,
+ "pwdLastSet", t) != LDB_SUCCESS) {
return NT_STATUS_NO_MEMORY;
}
set_el = ldb_msg_find_element(msg, "pwdLastSet");
ldb_dn_get_linearized(a_state->account_dn),
ldb_errstring(a_state->sam_ctx)));
- /* we really need samdb.c to return NTSTATUS */
- return NT_STATUS_UNSUCCESSFUL;
+ return dsdb_ldb_err_to_ntstatus(ret);
}
}
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
- struct ldb_message **res;
- int i, ldb_cnt;
+ struct ldb_result *res;
+ unsigned int i;
uint32_t count;
const char * const attrs[] = { "objectSid", "sAMAccountName",
"displayName", "description", "userAccountControl",
struct samr_DispEntryAscii *entriesAscii = NULL;
struct samr_DispEntryGeneral *entriesGeneral = NULL;
const char *filter;
+ int ret;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
return NT_STATUS_INVALID_INFO_CLASS;
}
- /* search for all requested objects in this domain. This could
+ /* search for all requested objects in all domains. This could
possibly be cached and resumed based on resume_key */
- ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
- d_state->domain_dn, &res, attrs,
- d_state->domain_sid, "%s", filter);
- if (ldb_cnt == -1) {
+ ret = dsdb_search(d_state->sam_ctx, mem_ctx, &res, ldb_get_default_basedn(d_state->sam_ctx),
+ LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (ldb_cnt == 0 || r->in.max_entries == 0) {
+ if ((res->count == 0) || (r->in.max_entries == 0)) {
return NT_STATUS_OK;
}
switch (r->in.level) {
case 1:
entriesGeneral = talloc_array(mem_ctx,
- struct samr_DispEntryGeneral,
- ldb_cnt);
+ struct samr_DispEntryGeneral,
+ res->count);
break;
case 2:
entriesFull = talloc_array(mem_ctx,
- struct samr_DispEntryFull,
- ldb_cnt);
+ struct samr_DispEntryFull,
+ res->count);
break;
case 3:
entriesFullGroup = talloc_array(mem_ctx,
- struct samr_DispEntryFullGroup,
- ldb_cnt);
+ struct samr_DispEntryFullGroup,
+ res->count);
break;
case 4:
case 5:
entriesAscii = talloc_array(mem_ctx,
- struct samr_DispEntryAscii,
- ldb_cnt);
+ struct samr_DispEntryAscii,
+ res->count);
break;
}
count = 0;
- for (i=0; i<ldb_cnt; i++) {
+ for (i = 0; i < res->count; i++) {
struct dom_sid *objectsid;
- objectsid = samdb_result_dom_sid(mem_ctx, res[i],
+ objectsid = samdb_result_dom_sid(mem_ctx, res->msgs[i],
"objectSid");
if (objectsid == NULL)
continue;
entriesGeneral[count].rid =
objectsid->sub_auths[objectsid->num_auths-1];
entriesGeneral[count].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);
entriesGeneral[count].account_name.string =
- ldb_msg_find_attr_as_string(res[i],
- "sAMAccountName", "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "sAMAccountName", "");
entriesGeneral[count].full_name.string =
- ldb_msg_find_attr_as_string(res[i], "displayName", "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "displayName", "");
entriesGeneral[count].description.string =
- ldb_msg_find_attr_as_string(res[i], "description", "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "description", "");
break;
case 2:
entriesFull[count].idx = count + 1;
/* No idea why we need to or in ACB_NORMAL here, but this is what Win2k3 seems to do... */
entriesFull[count].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) | ACB_NORMAL;
entriesFull[count].account_name.string =
- ldb_msg_find_attr_as_string(res[i], "sAMAccountName",
- "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "sAMAccountName", "");
entriesFull[count].description.string =
- ldb_msg_find_attr_as_string(res[i], "description", "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "description", "");
break;
case 3:
entriesFullGroup[count].idx = count + 1;
entriesFullGroup[count].acct_flags
= SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
entriesFullGroup[count].account_name.string =
- ldb_msg_find_attr_as_string(res[i], "sAMAccountName",
- "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "sAMAccountName", "");
entriesFullGroup[count].description.string =
- ldb_msg_find_attr_as_string(res[i], "description", "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "description", "");
break;
case 4:
case 5:
entriesAscii[count].idx = count + 1;
entriesAscii[count].account_name.string =
- ldb_msg_find_attr_as_string(res[i], "sAMAccountName",
- "");
+ ldb_msg_find_attr_as_string(res->msgs[i],
+ "sAMAccountName", "");
break;
}
for (i=0; i<count; i++) {
struct ldb_message *mod;
+ int ret;
mod = ldb_msg_new(mem_ctx);
if (mod == NULL) {
"member", memberdn) != LDB_SUCCESS)
return NT_STATUS_NO_MEMORY;
- if (ldb_modify(d_state->sam_ctx, mod) != LDB_SUCCESS)
- return NT_STATUS_UNSUCCESSFUL;
-
+ ret = ldb_modify(d_state->sam_ctx, mod);
talloc_free(mod);
+ if (ret != LDB_SUCCESS) {
+ return dsdb_ldb_err_to_ntstatus(ret);
+ }
}
return NT_STATUS_OK;
DATA_BLOB password;
enum samr_ValidationStatus res;
NTSTATUS status;
+ enum dcerpc_transport_t transport = dce_call->conn->endpoint->ep_description->transport;
+
+ if (transport != NCACN_IP_TCP && transport != NCALRPC) {
+ DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
+ }
(*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep);