This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "lib/ldb/include/ldb_errors.h"
#include "dsdb/common/flags.h"
#include "dsdb/samdb/samdb.h"
-#include "libcli/ldap/ldap.h"
+#include "libcli/ldap/ldap_ndr.h"
#include "libcli/security/security.h"
#include "rpc_server/samr/proto.h"
-#include "db_wrap.h"
+#include "../lib/util/util_ldb.h"
+#include "param/param.h"
-/* these query macros make samr_Query[User|Group]Info a bit easier to read */
+/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
#define QUERY_STRING(msg, field, attr) \
- r->out.info->field = samdb_result_string(msg, attr, "");
+ info->field.string = samdb_result_string(msg, attr, "");
#define QUERY_UINT(msg, field, attr) \
- r->out.info->field = samdb_result_uint(msg, attr, 0);
+ info->field = samdb_result_uint(msg, attr, 0);
#define QUERY_RID(msg, field, attr) \
- r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
-#define QUERY_NTTIME(msg, field, attr) \
- r->out.info->field = samdb_result_nttime(msg, attr, 0);
+ info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
+#define QUERY_UINT64(msg, field, attr) \
+ info->field = samdb_result_uint64(msg, attr, 0);
#define QUERY_APASSC(msg, field, attr) \
- r->out.info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg, attr);
+ info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg, attr);
#define QUERY_FPASSC(msg, field, attr) \
- r->out.info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg);
+ info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg);
#define QUERY_LHOURS(msg, field, attr) \
- r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
+ info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
#define QUERY_AFLAGS(msg, field, attr) \
- r->out.info->field = samdb_result_acct_flags(msg, attr);
+ info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+#define QUERY_PARAMETERS(msg, field, attr) \
+ info->field = samdb_result_parameters(mem_ctx, msg, attr);
/* these are used to make the Set[User|Group]Info code easier to follow */
-#define SET_STRING(mod, field, attr) do { \
- if (r->in.info->field == NULL) return NT_STATUS_INVALID_PARAMETER; \
- if (samdb_msg_add_string(sam_ctx, mem_ctx, mod, attr, r->in.info->field) != 0) { \
- return NT_STATUS_NO_MEMORY; \
- } \
+#define SET_STRING(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (r->in.info->field.string == NULL) return NT_STATUS_INVALID_PARAMETER; \
+ if (r->in.info->field.string[0] == '\0') { \
+ if (ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, NULL)) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ } \
+ if (ldb_msg_add_string(msg, attr, r->in.info->field.string) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
} while (0)
-#define SET_UINT(mod, field, attr) do { \
- if (samdb_msg_add_uint(sam_ctx, mem_ctx, mod, attr, r->in.info->field) != 0) { \
- return NT_STATUS_NO_MEMORY; \
- } \
-} while (0)
-
-#define SET_INT64(mod, field, attr) do { \
- if (samdb_msg_add_int64(sam_ctx, mem_ctx, mod, attr, r->in.info->field) != 0) { \
- return NT_STATUS_NO_MEMORY; \
- } \
-} while (0)
-
-#define SET_UINT64(mod, field, attr) do { \
- if (samdb_msg_add_uint64(sam_ctx, mem_ctx, mod, attr, r->in.info->field) != 0) { \
- return NT_STATUS_NO_MEMORY; \
- } \
+#define SET_UINT(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_uint(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+#define SET_INT64(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_int64(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+#define SET_UINT64(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+#define CHECK_FOR_MULTIPLES(value, flag, poss_flags) \
+ do { \
+ if ((value & flag) && ((value & flag) != (value & (poss_flags)))) { \
+ return NT_STATUS_INVALID_PARAMETER; \
+ } \
+ } while (0) \
+
+/* Set account flags, discarding flags that cannot be set with SAMR */
+#define SET_AFLAGS(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if ((r->in.info->field & (ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST)) == 0) { \
+ return NT_STATUS_INVALID_PARAMETER; \
+ } \
+ CHECK_FOR_MULTIPLES(r->in.info->field, ACB_NORMAL, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+ CHECK_FOR_MULTIPLES(r->in.info->field, ACB_DOMTRUST, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+ CHECK_FOR_MULTIPLES(r->in.info->field, ACB_WSTRUST, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+ CHECK_FOR_MULTIPLES(r->in.info->field, ACB_SVRTRUST, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+ if (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, (r->in.info->field & ~(ACB_AUTOLOCK|ACB_PW_EXPIRED))) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+#define SET_LHOURS(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_logon_hours(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
} while (0)
-#define SET_AFLAGS(msg, field, attr) do { \
- if (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \
- return NT_STATUS_NO_MEMORY; \
- } \
+#define SET_PARAMETERS(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (r->in.info->field.length != 0) { \
+ if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+ } \
} while (0)
-#define SET_LHOURS(msg, field, attr) do { \
- if (samdb_msg_add_logon_hours(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
- return NT_STATUS_NO_MEMORY; \
- } \
-} while (0)
/*
}
/* make sure the sam database is accessible */
- c_state->sam_ctx = samdb_connect(c_state, 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 dcesrv_handle *h;
struct sec_desc_buf *sd;
- r->out.sdbuf = NULL;
+ *r->out.sdbuf = NULL;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
sd->sd = samdb_default_security_descriptor(mem_ctx);
- r->out.sdbuf = sd;
+ *r->out.sdbuf = sd;
return NT_STATUS_OK;
}
struct dcesrv_handle *h;
struct dom_sid *sid;
const char * const dom_attrs[] = { "objectSid", NULL};
- const char * const ref_attrs[] = { "ncName", NULL};
struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
int ret;
- struct ldb_dn *partitions_basedn;
- r->out.sid = NULL;
+ *r->out.sid = NULL;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
return NT_STATUS_INVALID_PARAMETER;
}
- partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
-
if (strcasecmp(r->in.domain_name->string, "BUILTIN") == 0) {
ret = gendb_search(c_state->sam_ctx,
mem_ctx, NULL, &dom_msgs, dom_attrs,
"(objectClass=builtinDomain)");
- } else {
- ret = gendb_search(c_state->sam_ctx,
- mem_ctx, partitions_basedn, &ref_msgs, ref_attrs,
- "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))",
- ldb_binary_encode_string(mem_ctx, r->in.domain_name->string));
- if (ret != 1) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
-
- ret = gendb_search_dn(c_state->sam_ctx, mem_ctx,
- samdb_result_dn(c_state->sam_ctx, mem_ctx,
- ref_msgs[0], "ncName", NULL),
+ } else if (strcasecmp_m(r->in.domain_name->string, lp_sam_name(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
+ ret = gendb_search_dn(c_state->sam_ctx,
+ mem_ctx, ldb_get_default_basedn(c_state->sam_ctx),
&dom_msgs, dom_attrs);
+ } else {
+ return NT_STATUS_NO_SUCH_DOMAIN;
}
-
if (ret != 1) {
return NT_STATUS_NO_SUCH_DOMAIN;
}
return NT_STATUS_NO_SUCH_DOMAIN;
}
- r->out.sid = sid;
+ *r->out.sid = sid;
return NT_STATUS_OK;
}
struct samr_connect_state *c_state;
struct dcesrv_handle *h;
struct samr_SamArray *array;
- int count, i, start_i;
- 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_dn *partitions_basedn;
+ int i, start_i;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
c_state = h->data;
- 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"));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- *r->out.resume_handle = count;
+ *r->out.resume_handle = 2;
start_i = *r->in.resume_handle;
- if (start_i >= count) {
+ if (start_i >= 2) {
/* 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, 2 - 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<2-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);
+ if (i == 0) {
+ array->entries[i].name.string = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
} else {
- array->entries[i].name.string = samdb_result_string(dom_msgs[i], "cn", NULL);
+ array->entries[i].name.string = "BUILTIN";
}
}
- r->out.sam = array;
- r->out.num_entries = i;
- array->count = r->out.num_entries;
+ *r->out.sam = array;
+ *r->out.num_entries = i;
+ array->count = *r->out.num_entries;
return NT_STATUS_OK;
}
struct samr_OpenDomain *r)
{
struct dcesrv_handle *h_conn, *h_domain;
- const char *domain_name;
struct samr_connect_state *c_state;
struct samr_domain_state *d_state;
const char * const dom_attrs[] = { "cn", NULL};
- const char * const ref_attrs[] = { "nETBIOSName", NULL};
struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
int ret;
- struct ldb_dn *partitions_basedn;
ZERO_STRUCTP(r->out.domain_handle);
return NT_STATUS_INVALID_PARAMETER;
}
- partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
+ d_state = talloc(c_state, struct samr_domain_state);
+ if (!d_state) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ d_state->domain_sid = talloc_steal(d_state, r->in.sid);
+
+ if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+ d_state->builtin = true;
+ d_state->domain_name = "BUILTIN";
+ } else {
+ d_state->builtin = false;
+ d_state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
+ }
ret = gendb_search(c_state->sam_ctx,
- mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(&(objectSid=%s)(&(|(objectclass=domain)(objectClass=builtinDomain))))",
+ mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), &dom_msgs, dom_attrs,
+ "(objectSid=%s)",
ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
+
if (ret == 0) {
+ talloc_free(d_state);
return NT_STATUS_NO_SUCH_DOMAIN;
} else if (ret > 1) {
+ talloc_free(d_state);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else if (ret == -1) {
+ talloc_free(d_state);
DEBUG(1, ("Failed to open domain %s: %s\n", dom_sid_string(mem_ctx, r->in.sid), ldb_errstring(c_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
- } else {
- ret = gendb_search(c_state->sam_ctx,
- mem_ctx, partitions_basedn, &ref_msgs, ref_attrs,
- "(&(&(nETBIOSName=*)(objectclass=crossRef))(ncName=%s))",
- ldb_dn_get_linearized(dom_msgs[0]->dn));
- if (ret == 0) {
- domain_name = ldb_msg_find_attr_as_string(dom_msgs[0], "cn", NULL);
- if (domain_name == NULL) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else if (ret == 1) {
-
- domain_name = ldb_msg_find_attr_as_string(ref_msgs[0], "nETBIOSName", NULL);
- if (domain_name == NULL) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- }
-
- d_state = talloc(c_state, struct samr_domain_state);
- if (!d_state) {
- return NT_STATUS_NO_MEMORY;
}
+ d_state->domain_dn = talloc_steal(d_state, dom_msgs[0]->dn);
+ d_state->role = lp_server_role(dce_call->conn->dce_ctx->lp_ctx);
d_state->connect_state = talloc_reference(d_state, c_state);
d_state->sam_ctx = c_state->sam_ctx;
- d_state->domain_sid = dom_sid_dup(d_state, r->in.sid);
- d_state->domain_name = talloc_strdup(d_state, domain_name);
- d_state->domain_dn = ldb_dn_copy(d_state, dom_msgs[0]->dn);
- if (!d_state->domain_sid || !d_state->domain_name || !d_state->domain_dn) {
- talloc_free(d_state);
- return NT_STATUS_NO_MEMORY;
- }
d_state->access_mask = r->in.access_mask;
+ 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)
{
- enum server_role role = lp_server_role();
-
/* 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",
0);
- switch (role) {
+ switch (state->role) {
case ROLE_DOMAIN_CONTROLLER:
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
break;
}
- /* TODO: Should these filter on SID, to avoid counting BUILTIN? */
+ /* No users in BUILTIN, and the LOCAL group types are only in builtin, and the global group type is never in BUILTIN */
info->num_users = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,
"(objectClass=user)");
info->num_groups = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,
/*
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;
}
struct samr_DomInfo7 *info)
{
- enum server_role role = lp_server_role();
-
- switch (role) {
+ switch (state->role) {
case ROLE_DOMAIN_CONTROLLER:
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
struct ldb_message **dom_msgs,
struct samr_DomInfo9 *info)
{
- info->unknown = 1;
+ info->domain_server_state = DOMAIN_SERVER_ENABLED;
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;
}
info->domain_create_time = ldb_msg_find_attr_as_uint(dom_msgs[0], "creationTime",
0x0LL);
- info->unknown1 = 0;
- info->unknown2 = 0;
+ info->modified_count_at_last_promotion = 0;
return NT_STATUS_OK;
}
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
+ union samr_DomainInfo *info;
struct ldb_message **dom_msgs;
const char * const *attrs = NULL;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
d_state = h->data;
- r->out.info = talloc(mem_ctx, union samr_DomainInfo);
- if (!r->out.info) {
+ info = talloc(mem_ctx, union samr_DomainInfo);
+ if (!info) {
return NT_STATUS_NO_MEMORY;
}
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",
}
}
- ZERO_STRUCTP(r->out.info);
+ *r->out.info = info;
+
+ ZERO_STRUCTP(info);
switch (r->in.level) {
case 1:
return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs,
- &r->out.info->info1);
+ &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,
+ &info->general);
case 3:
return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs,
- &r->out.info->info3);
+ &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,
+ &info->oem);
case 5:
return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs,
- &r->out.info->info5);
+ &info->info5);
case 6:
return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs,
- &r->out.info->info6);
+ &info->info6);
case 7:
return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs,
- &r->out.info->info7);
+ &info->info7);
case 8:
return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs,
- &r->out.info->info8);
+ &info->info8);
case 9:
return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs,
- &r->out.info->info9);
+ &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,
+ &info->general2);
case 12:
return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs,
- &r->out.info->info12);
+ &info->info12);
case 13:
return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs,
- &r->out.info->info13);
+ &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.string, "comment");
+ SET_STRING(msg, oem.oem_information, "oEMInformation");
break;
case 6:
}
/* modify the samdb record */
- ret = samdb_replace(sam_ctx, mem_ctx, msg);
+ ret = ldb_modify(sam_ctx, msg);
if (ret != 0) {
DEBUG(1,("Failed to modify record %s: %s\n",
ldb_dn_get_linearized(d_state->domain_dn),
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) {
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", "group");
/* create the group */
- ret = samdb_add(d_state->sam_ctx, mem_ctx, msg);
+ ret = ldb_add(d_state->sam_ctx, msg);
switch (ret) {
case LDB_SUCCESS:
break;
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
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;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < count - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a user in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ } else if (r->in.acct_flags == ACB_DOMTRUST) {
+ /* Domain trust accounts must be created by the LSA calls */
+ return NT_STATUS_ACCESS_DENIED;
+ }
account_name = r->in.account_name->string;
if (account_name == NULL) {
return NT_STATUS_INVALID_PARAMETER;
}
+ /*
+ * Start a transaction, so we can query and do a subsequent atomic
+ * modify
+ */
+
ret = ldb_transaction_start(d_state->sam_ctx);
if (ret != 0) {
DEBUG(0,("Failed to start a transaction for user creation: %s\n",
/* This must be one of these values *only* */
if (r->in.acct_flags == ACB_NORMAL) {
- container = "Users";
+ container = "CN=Users";
obj_class = "user";
} else if (r->in.acct_flags == ACB_WSTRUST) {
if (cn_name[cn_name_len - 1] != '$') {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_FOOBAR;
}
cn_name[cn_name_len - 1] = '\0';
- container = "Computers";
+ container = "CN=Computers";
obj_class = "computer";
+ samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "primaryGroupID", DOMAIN_RID_DOMAIN_MEMBERS);
} else if (r->in.acct_flags == ACB_SVRTRUST) {
if (cn_name[cn_name_len - 1] != '$') {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_FOOBAR;
}
cn_name[cn_name_len - 1] = '\0';
- container = "Domain Controllers";
+ container = "OU=Domain Controllers";
obj_class = "computer";
-
- } else if (r->in.acct_flags == ACB_DOMTRUST) {
- container = "Users";
- obj_class = "user";
-
+ samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "primaryGroupID", DOMAIN_RID_DCS);
} else {
ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_INVALID_PARAMETER;
/* add core elements to the ldb_message for the user */
msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn);
- if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container)) {
+ if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_FOOBAR;
}
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", account_name);
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", obj_class);
-
- /* Start a transaction, so we can query and do a subsequent atomic modify */
-
+
/* create the user */
- ret = samdb_add(d_state->sam_ctx, mem_ctx, msg);
+ 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, i, first;
+ struct ldb_result *res;
+ int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
- const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
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(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;
}
- for (i=0;i<count;i++) {
- entries[i].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
- entries[i].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+ num_filtered_entries = 0;
+ 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->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->msgs[i], "objectSid", 0);
+ entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", "");
+ num_filtered_entries++;
}
/* sort the results by rid */
- qsort(entries, count, sizeof(struct samr_SamEntry),
+ qsort(entries, num_filtered_entries, sizeof(struct samr_SamEntry),
(comparison_fn_t)compare_SamEntry);
/* find the first entry to return */
for (first=0;
- first<count && entries[first].idx <= *r->in.resume_handle;
+ first<num_filtered_entries && 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;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = num_filtered_entries - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
- if (r->out.num_entries < count - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ *r->out.sam = sam;
+
+ if (first == num_filtered_entries) {
+ return NT_STATUS_OK;
+ }
+
+ if (*r->out.num_entries < num_filtered_entries - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_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) {
samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
/* create the alias */
- ret = samdb_add(d_state->sam_ctx, mem_ctx, msg);
+ ret = ldb_add(d_state->sam_ctx, msg);
switch (ret) {
case LDB_SUCCESS:
break;
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
return NT_STATUS_OK;
}
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries, 1000);
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries, 1000);
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
+ if (*r->out.num_entries < count - first) {
*r->out.resume_handle =
- entries[first+r->out.num_entries-1].idx;
+ entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
const char * const attrs[] = { "sAMAccountType", "objectSid", NULL };
int count;
- ZERO_STRUCT(r->out.rids);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.rids);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
return NT_STATUS_OK;
}
- r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- if (!r->out.rids.ids || !r->out.types.ids) {
+ r->out.rids->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ r->out.types->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ if (!r->out.rids->ids || !r->out.types->ids) {
return NT_STATUS_NO_MEMORY;
}
- r->out.rids.count = r->in.num_names;
- r->out.types.count = r->in.num_names;
+ r->out.rids->count = r->in.num_names;
+ r->out.types->count = r->in.num_names;
num_mapped = 0;
struct dom_sid *sid;
uint32_t atype, rtype;
- r->out.rids.ids[i] = 0;
- r->out.types.ids[i] = SID_NAME_UNKNOWN;
+ r->out.rids->ids[i] = 0;
+ r->out.types->ids[i] = SID_NAME_UNKNOWN;
count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
"sAMAccountName=%s",
continue;
}
- r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1];
- r->out.types.ids[i] = rtype;
+ r->out.rids->ids[i] = sid->sub_auths[sid->num_auths-1];
+ r->out.types->ids[i] = rtype;
num_mapped++;
}
struct lsa_String *names;
uint32_t *ids;
- ZERO_STRUCT(r->out.names);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.names);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
}
}
- r->out.names.names = names;
- r->out.names.count = r->in.num_rids;
+ r->out.names->names = names;
+ r->out.names->count = r->in.num_rids;
- r->out.types.ids = ids;
- r->out.types.count = r->in.num_rids;
+ r->out.types->ids = ids;
+ r->out.types->count = r->in.num_rids;
return status;
}
{
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;
+ union samr_GroupInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
a_state = h->data;
+
+ ret = ldb_search(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);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_GroupInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* Fill in the level */
switch (r->in.level) {
case GROUPINFOALL:
- QUERY_STRING(msg, all.name.string, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ QUERY_STRING(msg, all.name, "sAMAccountName");
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all.num_members, "numMembers")
- QUERY_STRING(msg, all.description.string, "description");
+ QUERY_STRING(msg, all.description, "description");
break;
case GROUPINFONAME:
- QUERY_STRING(msg, name.string, "sAMAccountName");
+ QUERY_STRING(msg, name, "sAMAccountName");
break;
case GROUPINFOATTRIBUTES:
- r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
break;
case GROUPINFODESCRIPTION:
- QUERY_STRING(msg, description.string, "description");
+ QUERY_STRING(msg, description, "description");
break;
case GROUPINFOALL2:
- QUERY_STRING(msg, all2.name.string, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ QUERY_STRING(msg, all2.name, "sAMAccountName");
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all2.num_members, "numMembers")
- QUERY_STRING(msg, all2.description.string, "description");
+ QUERY_STRING(msg, all2.description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
switch (r->in.level) {
case GROUPINFODESCRIPTION:
- SET_STRING(msg, description.string, "description");
+ SET_STRING(msg, description, "description");
break;
case GROUPINFONAME:
/* On W2k3 this does not change the name, it changes the
* sAMAccountName attribute */
- SET_STRING(msg, name.string, "sAMAccountName");
+ SET_STRING(msg, name, "sAMAccountName");
break;
case GROUPINFOATTRIBUTES:
/* This does not do anything obviously visible in W2k3 LDAP */
}
/* modify the samdb record */
- ret = samdb_replace(g_state->sam_ctx, mem_ctx, msg);
+ ret = ldb_modify(g_state->sam_ctx, msg);
if (ret != 0) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL;
/* In native mode, AD can also nest domain groups. Not sure yet
* whether this is also available via RPC. */
- ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res,
+ ret = ldb_search(d_state->sam_ctx, mem_ctx, &res,
d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs,
"(&(objectSid=%s)(objectclass=user))",
ldap_encode_ndr_dom_sid(mem_ctx, membersid));
memberdn) != 0)
return NT_STATUS_UNSUCCESSFUL;
- ret = samdb_modify(a_state->sam_ctx, mem_ctx, mod);
+ ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
case LDB_SUCCESS:
return NT_STATUS_OK;
a_state = h->data;
- ret = samdb_delete(a_state->sam_ctx, mem_ctx, a_state->account_dn);
+ ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != 0) {
return NT_STATUS_UNSUCCESSFUL;
}
/* In native mode, AD can also nest domain groups. Not sure yet
* whether this is also available via RPC. */
- ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res,
+ ret = ldb_search(d_state->sam_ctx, mem_ctx, &res,
d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs,
"(&(objectSid=%s)(objectclass=user))",
ldap_encode_ndr_dom_sid(mem_ctx, membersid));
return NT_STATUS_NO_MEMORY;
}
- ret = samdb_modify(a_state->sam_ctx, mem_ctx, mod);
+ ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
case LDB_SUCCESS:
return NT_STATUS_OK;
struct ldb_message **res2;
const char * const attrs2[2] = { "objectSid", NULL };
ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- ldb_dn_new(mem_ctx, a_state->sam_ctx, (const char *)el->values[i].data),
+ ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]),
&res2, attrs2);
if (ret != 1)
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_AliasInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_AliasInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_AliasInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
switch(r->in.level) {
case ALIASINFOALL:
- QUERY_STRING(msg, all.name.string, "sAMAccountName");
+ QUERY_STRING(msg, all.name, "sAMAccountName");
QUERY_UINT (msg, all.num_members, "numMembers");
- QUERY_STRING(msg, all.description.string, "description");
+ QUERY_STRING(msg, all.description, "description");
break;
case ALIASINFONAME:
- QUERY_STRING(msg, name.string, "sAMAccountName");
+ QUERY_STRING(msg, name, "sAMAccountName");
break;
case ALIASINFODESCRIPTION:
- QUERY_STRING(msg, description.string, "description");
+ QUERY_STRING(msg, description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
switch (r->in.level) {
case ALIASINFODESCRIPTION:
- SET_STRING(msg, description.string, "description");
+ SET_STRING(msg, description, "description");
break;
case ALIASINFONAME:
/* On W2k3 this does not change the name, it changes the
* sAMAccountName attribute */
- SET_STRING(msg, name.string, "sAMAccountName");
+ SET_STRING(msg, name, "sAMAccountName");
break;
default:
return NT_STATUS_INVALID_INFO_CLASS;
}
/* modify the samdb record */
- ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg);
+ ret = ldb_modify(a_state->sam_ctx, msg);
if (ret != 0) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL;
a_state = h->data;
- ret = samdb_delete(a_state->sam_ctx, mem_ctx, a_state->account_dn);
+ ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != 0) {
return NT_STATUS_UNSUCCESSFUL;
}
ldb_dn_alloc_linearized(mem_ctx, memberdn)) != 0)
return NT_STATUS_UNSUCCESSFUL;
- if (samdb_modify(a_state->sam_ctx, mem_ctx, mod) != 0)
+ if (ldb_modify(a_state->sam_ctx, mod) != 0)
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_OK;
memberdn) != 0)
return NT_STATUS_UNSUCCESSFUL;
- if (samdb_modify(a_state->sam_ctx, mem_ctx, mod) != 0)
+ if (ldb_modify(a_state->sam_ctx, mod) != 0)
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_OK;
ret = gendb_search_dn(d_state->sam_ctx, mem_ctx,
a_state->account_dn, &msgs, attrs);
- if (ret != 1)
+ if (ret == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ } else if (ret != 1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
r->out.sids->num_sids = 0;
r->out.sids->sids = NULL;
struct ldb_message **msgs2;
const char * const attrs2[2] = { "objectSid", NULL };
ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- ldb_dn_new(mem_ctx, a_state->sam_ctx, (const char *)el->values[i].data),
- &msgs2, attrs2);
+ ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]),
+ &msgs2, attrs2);
if (ret != 1)
return NT_STATUS_INTERNAL_DB_CORRUPTION;
a_state = h->data;
- ret = samdb_delete(a_state->sam_ctx, mem_ctx, a_state->account_dn);
+ ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
if (ret != 0) {
+ 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;
}
struct ldb_context *sam_ctx;
const char * const *attrs = NULL;
+ union samr_UserInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
case 1:
{
static const char * const attrs2[] = {"sAMAccountName", "displayName",
- "primaryGroupID", "description",
+ "primaryroupID", "description",
"comment", NULL};
attrs = attrs2;
break;
}
case 16:
{
- static const char * const attrs2[] = {"userAccountControl", NULL};
+ static const char * const attrs2[] = {"userAccountControl", "pwdLastSet", NULL};
attrs = attrs2;
break;
}
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_UserInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_UserInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* fill in the reply */
switch (r->in.level) {
case 1:
- QUERY_STRING(msg, info1.account_name.string, "sAMAccountName");
- QUERY_STRING(msg, info1.full_name.string, "displayName");
+ QUERY_STRING(msg, info1.account_name, "sAMAccountName");
+ QUERY_STRING(msg, info1.full_name, "displayName");
QUERY_UINT (msg, info1.primary_gid, "primaryGroupID");
- QUERY_STRING(msg, info1.description.string, "description");
- QUERY_STRING(msg, info1.comment.string, "comment");
+ QUERY_STRING(msg, info1.description, "description");
+ QUERY_STRING(msg, info1.comment, "comment");
break;
case 2:
- QUERY_STRING(msg, info2.comment.string, "comment");
+ QUERY_STRING(msg, info2.comment, "comment");
QUERY_UINT (msg, info2.country_code, "countryCode");
QUERY_UINT (msg, info2.code_page, "codePage");
break;
case 3:
- QUERY_STRING(msg, info3.account_name.string, "sAMAccountName");
- QUERY_STRING(msg, info3.full_name.string, "displayName");
+ QUERY_STRING(msg, info3.account_name, "sAMAccountName");
+ QUERY_STRING(msg, info3.full_name, "displayName");
QUERY_RID (msg, info3.rid, "objectSid");
QUERY_UINT (msg, info3.primary_gid, "primaryGroupID");
- QUERY_STRING(msg, info3.home_directory.string, "homeDirectory");
- QUERY_STRING(msg, info3.home_drive.string, "homeDrive");
- QUERY_STRING(msg, info3.logon_script.string, "scriptPath");
- QUERY_STRING(msg, info3.profile_path.string, "profilePath");
- QUERY_STRING(msg, info3.workstations.string, "userWorkstations");
- QUERY_NTTIME(msg, info3.last_logon, "lastLogon");
- QUERY_NTTIME(msg, info3.last_logoff, "lastLogoff");
- QUERY_NTTIME(msg, info3.last_password_change, "pwdLastSet");
+ QUERY_STRING(msg, info3.home_directory, "homeDirectory");
+ QUERY_STRING(msg, info3.home_drive, "homeDrive");
+ QUERY_STRING(msg, info3.logon_script, "scriptPath");
+ QUERY_STRING(msg, info3.profile_path, "profilePath");
+ QUERY_STRING(msg, info3.workstations, "userWorkstations");
+ QUERY_UINT64(msg, info3.last_logon, "lastLogon");
+ QUERY_UINT64(msg, info3.last_logoff, "lastLogoff");
+ QUERY_UINT64(msg, info3.last_password_change, "pwdLastSet");
QUERY_APASSC(msg, info3.allow_password_change, "pwdLastSet");
QUERY_FPASSC(msg, info3.force_password_change, "pwdLastSet");
QUERY_LHOURS(msg, info3.logon_hours, "logonHours");
break;
case 5:
- QUERY_STRING(msg, info5.account_name.string, "sAMAccountName");
- QUERY_STRING(msg, info5.full_name.string, "displayName");
+ QUERY_STRING(msg, info5.account_name, "sAMAccountName");
+ QUERY_STRING(msg, info5.full_name, "displayName");
QUERY_RID (msg, info5.rid, "objectSid");
QUERY_UINT (msg, info5.primary_gid, "primaryGroupID");
- QUERY_STRING(msg, info5.home_directory.string, "homeDirectory");
- QUERY_STRING(msg, info5.home_drive.string, "homeDrive");
- QUERY_STRING(msg, info5.logon_script.string, "scriptPath");
- QUERY_STRING(msg, info5.profile_path.string, "profilePath");
- QUERY_STRING(msg, info5.description.string, "description");
- QUERY_STRING(msg, info5.workstations.string, "userWorkstations");
- QUERY_NTTIME(msg, info5.last_logon, "lastLogon");
- QUERY_NTTIME(msg, info5.last_logoff, "lastLogoff");
+ QUERY_STRING(msg, info5.home_directory, "homeDirectory");
+ QUERY_STRING(msg, info5.home_drive, "homeDrive");
+ QUERY_STRING(msg, info5.logon_script, "scriptPath");
+ QUERY_STRING(msg, info5.profile_path, "profilePath");
+ QUERY_STRING(msg, info5.description, "description");
+ QUERY_STRING(msg, info5.workstations, "userWorkstations");
+ QUERY_UINT64(msg, info5.last_logon, "lastLogon");
+ QUERY_UINT64(msg, info5.last_logoff, "lastLogoff");
QUERY_LHOURS(msg, info5.logon_hours, "logonHours");
QUERY_UINT (msg, info5.bad_password_count, "badPwdCount");
QUERY_UINT (msg, info5.logon_count, "logonCount");
- QUERY_NTTIME(msg, info5.last_password_change, "pwdLastSet");
- QUERY_NTTIME(msg, info5.acct_expiry, "accountExpires");
+ QUERY_UINT64(msg, info5.last_password_change, "pwdLastSet");
+ QUERY_UINT64(msg, info5.acct_expiry, "accountExpires");
QUERY_AFLAGS(msg, info5.acct_flags, "userAccountControl");
break;
case 6:
- QUERY_STRING(msg, info6.account_name.string, "sAMAccountName");
- QUERY_STRING(msg, info6.full_name.string, "displayName");
+ QUERY_STRING(msg, info6.account_name, "sAMAccountName");
+ QUERY_STRING(msg, info6.full_name, "displayName");
break;
case 7:
- QUERY_STRING(msg, info7.account_name.string, "sAMAccountName");
+ QUERY_STRING(msg, info7.account_name, "sAMAccountName");
break;
case 8:
- QUERY_STRING(msg, info8.full_name.string, "displayName");
+ QUERY_STRING(msg, info8.full_name, "displayName");
break;
case 9:
- QUERY_UINT (msg, info9.primary_gid, "primaryGroupID");
+ QUERY_UINT (msg, info9.primary_gid, "primaryGroupID");
break;
case 10:
- QUERY_STRING(msg, info10.home_directory.string,"homeDirectory");
- QUERY_STRING(msg, info10.home_drive.string, "homeDrive");
+ QUERY_STRING(msg, info10.home_directory,"homeDirectory");
+ QUERY_STRING(msg, info10.home_drive, "homeDrive");
break;
case 11:
- QUERY_STRING(msg, info11.logon_script.string, "scriptPath");
+ QUERY_STRING(msg, info11.logon_script, "scriptPath");
break;
case 12:
- QUERY_STRING(msg, info12.profile_path.string, "profilePath");
+ QUERY_STRING(msg, info12.profile_path, "profilePath");
break;
case 13:
- QUERY_STRING(msg, info13.description.string, "description");
+ QUERY_STRING(msg, info13.description, "description");
break;
case 14:
- QUERY_STRING(msg, info14.workstations.string, "userWorkstations");
+ QUERY_STRING(msg, info14.workstations, "userWorkstations");
break;
case 16:
- QUERY_AFLAGS(msg, info16.acct_flags, "userAccountControl");
+ QUERY_AFLAGS(msg, info16.acct_flags, "userAccountControl");
break;
case 17:
- QUERY_NTTIME(msg, info17.acct_expiry, "accountExpires");
+ QUERY_UINT64(msg, info17.acct_expiry, "accountExpires");
+ break;
case 20:
- QUERY_STRING(msg, info20.parameters.string, "userParameters");
+ QUERY_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
- QUERY_NTTIME(msg, info21.last_logon, "lastLogon");
- QUERY_NTTIME(msg, info21.last_logoff, "lastLogoff");
- QUERY_NTTIME(msg, info21.last_password_change, "pwdLastSet");
- QUERY_NTTIME(msg, info21.acct_expiry, "accountExpires");
+ QUERY_UINT64(msg, info21.last_logon, "lastLogon");
+ QUERY_UINT64(msg, info21.last_logoff, "lastLogoff");
+ QUERY_UINT64(msg, info21.last_password_change, "pwdLastSet");
+ QUERY_UINT64(msg, info21.acct_expiry, "accountExpires");
QUERY_APASSC(msg, info21.allow_password_change,"pwdLastSet");
QUERY_FPASSC(msg, info21.force_password_change,"pwdLastSet");
- QUERY_STRING(msg, info21.account_name.string, "sAMAccountName");
- QUERY_STRING(msg, info21.full_name.string, "displayName");
- QUERY_STRING(msg, info21.home_directory.string,"homeDirectory");
- QUERY_STRING(msg, info21.home_drive.string, "homeDrive");
- QUERY_STRING(msg, info21.logon_script.string, "scriptPath");
- QUERY_STRING(msg, info21.profile_path.string, "profilePath");
- QUERY_STRING(msg, info21.description.string, "description");
- QUERY_STRING(msg, info21.workstations.string, "userWorkstations");
- QUERY_STRING(msg, info21.comment.string, "comment");
- QUERY_STRING(msg, info21.parameters.string, "userParameters");
+ QUERY_STRING(msg, info21.account_name, "sAMAccountName");
+ QUERY_STRING(msg, info21.full_name, "displayName");
+ QUERY_STRING(msg, info21.home_directory, "homeDirectory");
+ QUERY_STRING(msg, info21.home_drive, "homeDrive");
+ QUERY_STRING(msg, info21.logon_script, "scriptPath");
+ QUERY_STRING(msg, info21.profile_path, "profilePath");
+ QUERY_STRING(msg, info21.description, "description");
+ QUERY_STRING(msg, info21.workstations, "userWorkstations");
+ QUERY_STRING(msg, info21.comment, "comment");
+ QUERY_PARAMETERS(msg, info21.parameters, "userParameters");
QUERY_RID (msg, info21.rid, "objectSid");
QUERY_UINT (msg, info21.primary_gid, "primaryGroupID");
QUERY_AFLAGS(msg, info21.acct_flags, "userAccountControl");
- r->out.info->info21.fields_present = 0x00FFFFFF;
+ info->info21.fields_present = 0x00FFFFFF;
QUERY_LHOURS(msg, info21.logon_hours, "logonHours");
QUERY_UINT (msg, info21.bad_password_count, "badPwdCount");
QUERY_UINT (msg, info21.logon_count, "logonCount");
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
switch (r->in.level) {
case 2:
- SET_STRING(msg, info2.comment.string, "comment");
- SET_UINT (msg, info2.country_code, "countryCode");
- SET_UINT (msg, info2.code_page, "codePage");
+ SET_STRING(msg, info2.comment, "comment");
+ SET_UINT (msg, info2.country_code, "countryCode");
+ SET_UINT (msg, info2.code_page, "codePage");
break;
case 4:
- SET_LHOURS(msg, info4.logon_hours, "logonHours");
+ SET_LHOURS(msg, info4.logon_hours, "logonHours");
break;
case 6:
- SET_STRING(msg, info6.full_name.string, "displayName");
+ SET_STRING(msg, info6.full_name, "displayName");
break;
case 7:
- SET_STRING(msg, info7.account_name.string, "samAccountName");
+ SET_STRING(msg, info7.account_name, "samAccountName");
break;
case 8:
- SET_STRING(msg, info8.full_name.string, "displayName");
+ SET_STRING(msg, info8.full_name, "displayName");
break;
case 9:
- SET_UINT(msg, info9.primary_gid, "primaryGroupID");
+ SET_UINT(msg, info9.primary_gid, "primaryGroupID");
break;
case 10:
- SET_STRING(msg, info10.home_directory.string, "homeDirectory");
- SET_STRING(msg, info10.home_drive.string, "homeDrive");
+ SET_STRING(msg, info10.home_directory, "homeDirectory");
+ SET_STRING(msg, info10.home_drive, "homeDrive");
break;
case 11:
- SET_STRING(msg, info11.logon_script.string, "scriptPath");
+ SET_STRING(msg, info11.logon_script, "scriptPath");
break;
case 12:
- SET_STRING(msg, info12.profile_path.string, "profilePath");
+ SET_STRING(msg, info12.profile_path, "profilePath");
break;
case 13:
- SET_STRING(msg, info13.description.string, "description");
+ SET_STRING(msg, info13.description, "description");
break;
case 14:
- SET_STRING(msg, info14.workstations.string, "userWorkstations");
+ SET_STRING(msg, info14.workstations, "userWorkstations");
break;
case 16:
- SET_AFLAGS(msg, info16.acct_flags, "userAccountControl");
+ SET_AFLAGS(msg, info16.acct_flags, "userAccountControl");
break;
case 17:
- SET_UINT64(msg, info17.acct_expiry, "accountExpires");
+ SET_UINT64(msg, info17.acct_expiry, "accountExpires");
break;
case 20:
- SET_STRING(msg, info20.parameters.string, "userParameters");
+ SET_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
-#define IFSET(bit) if (bit & r->in.info->info21.fields_present)
+#define IFSET(bit) if (bit & r->in.info->info21.fields_present)
+ IFSET(SAMR_FIELD_ACCT_EXPIRY)
+ SET_UINT64(msg, info21.acct_expiry, "accountExpires");
IFSET(SAMR_FIELD_ACCOUNT_NAME)
- SET_STRING(msg, info21.account_name.string, "samAccountName");
+ SET_STRING(msg, info21.account_name, "samAccountName");
IFSET(SAMR_FIELD_FULL_NAME)
- SET_STRING(msg, info21.full_name.string, "displayName");
+ SET_STRING(msg, info21.full_name, "displayName");
IFSET(SAMR_FIELD_DESCRIPTION)
- SET_STRING(msg, info21.description.string, "description");
+ SET_STRING(msg, info21.description, "description");
IFSET(SAMR_FIELD_COMMENT)
- SET_STRING(msg, info21.comment.string, "comment");
+ SET_STRING(msg, info21.comment, "comment");
IFSET(SAMR_FIELD_LOGON_SCRIPT)
- SET_STRING(msg, info21.logon_script.string, "scriptPath");
+ SET_STRING(msg, info21.logon_script, "scriptPath");
IFSET(SAMR_FIELD_PROFILE_PATH)
- SET_STRING(msg, info21.profile_path.string, "profilePath");
+ SET_STRING(msg, info21.profile_path, "profilePath");
IFSET(SAMR_FIELD_HOME_DIRECTORY)
- SET_STRING(msg, info21.home_directory.string, "homeDirectory");
+ SET_STRING(msg, info21.home_directory, "homeDirectory");
IFSET(SAMR_FIELD_HOME_DRIVE)
- SET_STRING(msg, info21.home_drive.string, "homeDrive");
+ SET_STRING(msg, info21.home_drive, "homeDrive");
IFSET(SAMR_FIELD_WORKSTATIONS)
- SET_STRING(msg, info21.workstations.string, "userWorkstations");
+ SET_STRING(msg, info21.workstations, "userWorkstations");
IFSET(SAMR_FIELD_LOGON_HOURS)
- SET_LHOURS(msg, info21.logon_hours, "logonHours");
+ SET_LHOURS(msg, info21.logon_hours, "logonHours");
IFSET(SAMR_FIELD_ACCT_FLAGS)
- SET_AFLAGS(msg, info21.acct_flags, "userAccountControl");
+ SET_AFLAGS(msg, info21.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info21.parameters.string, "userParameters");
+ SET_PARAMETERS(msg, info21.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
- SET_UINT (msg, info21.country_code, "countryCode");
+ SET_UINT (msg, info21.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
- SET_UINT (msg, info21.code_page, "codePage");
-
-
- /* Any reason the rest of these can't be set? */
+ SET_UINT (msg, info21.code_page, "codePage");
#undef IFSET
break;
case 23:
#define IFSET(bit) if (bit & r->in.info->info23.info.fields_present)
+ IFSET(SAMR_FIELD_ACCT_EXPIRY)
+ SET_UINT64(msg, info23.info.acct_expiry, "accountExpires");
IFSET(SAMR_FIELD_ACCOUNT_NAME)
- SET_STRING(msg, info23.info.account_name.string, "samAccountName");
+ SET_STRING(msg, info23.info.account_name, "samAccountName");
IFSET(SAMR_FIELD_FULL_NAME)
- SET_STRING(msg, info23.info.full_name.string, "displayName");
+ SET_STRING(msg, info23.info.full_name, "displayName");
IFSET(SAMR_FIELD_DESCRIPTION)
- SET_STRING(msg, info23.info.description.string, "description");
+ SET_STRING(msg, info23.info.description, "description");
IFSET(SAMR_FIELD_COMMENT)
- SET_STRING(msg, info23.info.comment.string, "comment");
+ SET_STRING(msg, info23.info.comment, "comment");
IFSET(SAMR_FIELD_LOGON_SCRIPT)
- SET_STRING(msg, info23.info.logon_script.string, "scriptPath");
+ SET_STRING(msg, info23.info.logon_script, "scriptPath");
IFSET(SAMR_FIELD_PROFILE_PATH)
- SET_STRING(msg, info23.info.profile_path.string, "profilePath");
+ SET_STRING(msg, info23.info.profile_path, "profilePath");
IFSET(SAMR_FIELD_WORKSTATIONS)
- SET_STRING(msg, info23.info.workstations.string, "userWorkstations");
+ SET_STRING(msg, info23.info.workstations, "userWorkstations");
IFSET(SAMR_FIELD_LOGON_HOURS)
- SET_LHOURS(msg, info23.info.logon_hours, "logonHours");
+ SET_LHOURS(msg, info23.info.logon_hours, "logonHours");
IFSET(SAMR_FIELD_ACCT_FLAGS)
- SET_AFLAGS(msg, info23.info.acct_flags, "userAccountControl");
+ SET_AFLAGS(msg, info23.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info23.info.parameters.string, "userParameters");
+ SET_PARAMETERS(msg, info23.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
- SET_UINT (msg, info23.info.country_code, "countryCode");
+ SET_UINT (msg, info23.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
- SET_UINT (msg, info23.info.code_page, "codePage");
- IFSET(SAMR_FIELD_PASSWORD) {
+ SET_UINT (msg, info23.info.code_page, "codePage");
+ IFSET(SAMR_FIELD_NT_PASSWORD_PRESENT) {
status = samr_set_password(dce_call,
a_state->sam_ctx,
a_state->account_dn,
a_state->domain_state->domain_dn,
mem_ctx, msg,
&r->in.info->info23.password);
- } else IFSET(SAMR_FIELD_PASSWORD2) {
+ } else IFSET(SAMR_FIELD_LM_PASSWORD_PRESENT) {
status = samr_set_password(dce_call,
a_state->sam_ctx,
a_state->account_dn,
case 25:
#define IFSET(bit) if (bit & r->in.info->info25.info.fields_present)
+ IFSET(SAMR_FIELD_ACCT_EXPIRY)
+ SET_UINT64(msg, info25.info.acct_expiry, "accountExpires");
IFSET(SAMR_FIELD_ACCOUNT_NAME)
- SET_STRING(msg, info25.info.account_name.string, "samAccountName");
+ SET_STRING(msg, info25.info.account_name, "samAccountName");
IFSET(SAMR_FIELD_FULL_NAME)
- SET_STRING(msg, info25.info.full_name.string, "displayName");
+ SET_STRING(msg, info25.info.full_name, "displayName");
IFSET(SAMR_FIELD_DESCRIPTION)
- SET_STRING(msg, info25.info.description.string, "description");
+ SET_STRING(msg, info25.info.description, "description");
IFSET(SAMR_FIELD_COMMENT)
- SET_STRING(msg, info25.info.comment.string, "comment");
+ SET_STRING(msg, info25.info.comment, "comment");
IFSET(SAMR_FIELD_LOGON_SCRIPT)
- SET_STRING(msg, info25.info.logon_script.string, "scriptPath");
+ SET_STRING(msg, info25.info.logon_script, "scriptPath");
IFSET(SAMR_FIELD_PROFILE_PATH)
- SET_STRING(msg, info25.info.profile_path.string, "profilePath");
+ SET_STRING(msg, info25.info.profile_path, "profilePath");
IFSET(SAMR_FIELD_WORKSTATIONS)
- SET_STRING(msg, info25.info.workstations.string, "userWorkstations");
+ SET_STRING(msg, info25.info.workstations, "userWorkstations");
IFSET(SAMR_FIELD_LOGON_HOURS)
- SET_LHOURS(msg, info25.info.logon_hours, "logonHours");
+ SET_LHOURS(msg, info25.info.logon_hours, "logonHours");
IFSET(SAMR_FIELD_ACCT_FLAGS)
- SET_AFLAGS(msg, info25.info.acct_flags, "userAccountControl");
+ SET_AFLAGS(msg, info25.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info25.info.parameters.string, "userParameters");
+ SET_PARAMETERS(msg, info25.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
- SET_UINT (msg, info25.info.country_code, "countryCode");
+ SET_UINT (msg, info25.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
- SET_UINT (msg, info25.info.code_page, "codePage");
- IFSET(SAMR_FIELD_PASSWORD) {
+ SET_UINT (msg, info25.info.code_page, "codePage");
+ IFSET(SAMR_FIELD_NT_PASSWORD_PRESENT) {
status = samr_set_password_ex(dce_call,
a_state->sam_ctx,
a_state->account_dn,
a_state->domain_state->domain_dn,
mem_ctx, msg,
&r->in.info->info25.password);
- } else IFSET(SAMR_FIELD_PASSWORD2) {
+ } else IFSET(SAMR_FIELD_LM_PASSWORD_PRESENT) {
status = samr_set_password_ex(dce_call,
a_state->sam_ctx,
a_state->account_dn,
}
/* modify the samdb record */
- ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg);
+ ret = ldb_modify(a_state->sam_ctx, msg);
if (ret != 0) {
DEBUG(1,("Failed to modify record %s: %s\n",
ldb_dn_get_linearized(a_state->account_dn),
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
struct samr_domain_state *d_state;
struct ldb_message **res;
int ldb_cnt, count, i;
- const char * const attrs[4] = { "objectSid", "sAMAccountName",
- "description", NULL };
+ const char * const attrs[] = { "objectSid", "sAMAccountName", "displayName",
+ "description", "userAccountControl", "pwdLastSet", NULL };
struct samr_DispEntryFull *entriesFull = NULL;
struct samr_DispEntryFullGroup *entriesFullGroup = NULL;
struct samr_DispEntryAscii *entriesAscii = NULL;
entriesGeneral[count].rid =
objectsid->sub_auths[objectsid->num_auths-1];
entriesGeneral[count].acct_flags =
- samdb_result_acct_flags(res[i],
- "userAccountControl");
+ samdb_result_acct_flags(d_state->sam_ctx, mem_ctx,
+ res[i],
+ d_state->domain_dn);
entriesGeneral[count].account_name.string =
samdb_result_string(res[i],
"sAMAccountName", "");
entriesFull[count].idx = count + 1;
entriesFull[count].rid =
objectsid->sub_auths[objectsid->num_auths-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(res[i],
- "userAccountControl");
+ samdb_result_acct_flags(d_state->sam_ctx, mem_ctx,
+ res[i],
+ d_state->domain_dn) | ACB_NORMAL;
entriesFull[count].account_name.string =
samdb_result_string(res[i], "sAMAccountName",
"");
entriesFullGroup[count].idx = count + 1;
entriesFullGroup[count].rid =
objectsid->sub_auths[objectsid->num_auths-1];
- entriesFullGroup[count].acct_flags =
- samdb_result_acct_flags(res[i],
- "userAccountControl");
/* We get a "7" here for groups */
entriesFullGroup[count].acct_flags
= SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
count += 1;
}
- r->out.total_size = count;
+ *r->out.total_size = count;
if (r->in.start_idx >= count) {
- r->out.returned_size = 0;
+ *r->out.returned_size = 0;
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries = NULL;
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries = NULL;
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries = NULL;
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries = NULL;
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries = NULL;
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries = NULL;
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries = NULL;
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries = NULL;
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries = NULL;
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries = NULL;
break;
}
} else {
- r->out.returned_size = MIN(count - r->in.start_idx,
+ *r->out.returned_size = MIN(count - r->in.start_idx,
r->in.max_entries);
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries =
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries =
&(entriesGeneral[r->in.start_idx]);
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries =
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries =
&(entriesFull[r->in.start_idx]);
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries =
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries =
&(entriesFullGroup[r->in.start_idx]);
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries =
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries =
&(entriesAscii[r->in.start_idx]);
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries =
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries =
&(entriesAscii[r->in.start_idx]);
break;
}
}
- return (r->out.returned_size < (count - r->in.start_idx)) ?
+ return (*r->out.returned_size < (count - r->in.start_idx)) ?
STATUS_MORE_ENTRIES : NT_STATUS_OK;
}
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
a_state = h->data;
- r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->domain_state->domain_dn, "minPwdLength",
- NULL);
- r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->account_dn,
- "pwdProperties", NULL);
+ r->out.info->min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->domain_state->domain_dn, "minPwdLength",
+ NULL);
+ r->out.info->password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->account_dn,
+ "pwdProperties", NULL);
return NT_STATUS_OK;
}
"member", memberdn) != 0)
return NT_STATUS_NO_MEMORY;
- if (samdb_modify(d_state->sam_ctx, mem_ctx, mod) != 0)
+ if (ldb_modify(d_state->sam_ctx, mod) != 0)
return NT_STATUS_UNSUCCESSFUL;
talloc_free(mod);
ZERO_STRUCT(r1.out);
r1.in.domain_handle = r->in.domain_handle;
r1.in.level = r->in.level;
-
+ r1.out.info = r->out.info;
+
status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1);
- r->out.info = r1.out.info;
-
return status;
}
struct samr_QueryUserInfo r1;
NTSTATUS status;
- ZERO_STRUCT(r1.out);
r1.in.user_handle = r->in.user_handle;
r1.in.level = r->in.level;
+ r1.out.info = r->out.info;
status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1);
-
- r->out.info = r1.out.info;
return status;
}
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
struct ldb_context *sam_ctx;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
- sam_ctx = samdb_connect(mem_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;
}
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- r->out.info.min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
- r->out.info.password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
+ r->out.info->min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
+ r->out.info->password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
talloc_free(msgs);
status = dcesrv_samr_Connect(dce_call, mem_ctx, &c);
- r->out.info->info1.unknown1 = 3;
- r->out.info->info1.unknown2 = 0;
- r->out.level = r->in.level;
+ r->out.info_out->info1.client_version = SAMR_CONNECT_AFTER_W2K;
+ r->out.info_out->info1.unknown2 = 0;
+ *r->out.level_out = r->in.level_in;
return status;
}
d_state = h->data;
/* form the users SID */
- r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
- if (!r->out.sid) {
+ *r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
+ if (!*r->out.sid) {
return NT_STATUS_NO_MEMORY;
}