{
struct samr_Password *lm_pwd, *nt_pwd;
NTSTATUS nt_status;
- uint16_t acct_flags = samdb_result_acct_flags(msgs[0], "userAccountControl");
+ struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msgs_domain_ref[0], "nCName", NULL);
+
+ uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msgs[0], domain_dn);
/* Quit if the account was locked out. */
if (acct_flags & ACB_AUTOLOCK) {
NTTIME now;
DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
- acct_flags = samdb_result_acct_flags(msg, "userAccountControl");
+ acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx,
return NT_STATUS_ACCOUNT_EXPIRED;
}
- if (!(acct_flags & ACB_PWNOEXP)) {
- /* check for immediate expiry "must change at next logon" */
- if (must_change_time == 0 && last_set_time != 0) {
- DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n",
- name_for_logs));
- return NT_STATUS_PASSWORD_MUST_CHANGE;
- }
+ /* check for immediate expiry "must change at next logon" */
+ if (!(acct_flags & ACB_PWNOEXP) && (must_change_time == 0 && last_set_time != 0)) {
+ DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n",
+ name_for_logs));
+ return NT_STATUS_PASSWORD_MUST_CHANGE;
+ }
- /* check for expired password */
- if ((must_change_time != 0) && (must_change_time < now)) {
- DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n",
- name_for_logs));
- DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n",
- nt_time_string(mem_ctx, must_change_time)));
- return NT_STATUS_PASSWORD_EXPIRED;
- }
+ /* check for expired password (dynamicly gnerated in samdb_result_acct_flags) */
+ if (acct_flags & ACB_PW_EXPIRED) {
+ DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n",
+ name_for_logs));
+ DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n",
+ nt_time_string(mem_ctx, must_change_time)));
+ return NT_STATUS_PASSWORD_EXPIRED;
}
/* Test workstation. Workstation list is comma separated. */
struct dom_sid **groupSIDs = NULL;
struct dom_sid *account_sid;
struct dom_sid *primary_group_sid;
+ struct ldb_dn *domain_dn;
const char *str;
struct ldb_dn *ncname;
int i;
server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);
server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount", 0);
- server_info->acct_flags = samdb_result_acct_flags(msg, "userAccountControl");
+ domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
+
+ server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
+ msg, domain_dn);
server_info->user_session_key = user_sess_key;
server_info->lm_session_key = lm_sess_key;
/*
pull a set of account_flags from a result set.
+
+ This requires that the attributes:
+ pwdLastSet
+ userAccountControl
+ be included in 'msg'
*/
-uint16_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr)
-{
- uint_t userAccountControl = ldb_msg_find_attr_as_uint(msg, attr, 0);
- return samdb_uf2acb(userAccountControl);
+uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg, struct ldb_dn *domain_dn)
+{
+ uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
+ uint32_t acct_flags = samdb_uf2acb(userAccountControl);
+ if ((userAccountControl & UF_NORMAL_ACCOUNT) && !(userAccountControl & UF_DONT_EXPIRE_PASSWD)) {
+ NTTIME must_change_time;
+ NTTIME pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
+ if (pwdLastSet == 0) {
+ acct_flags |= ACB_PW_EXPIRED;
+ } else {
+ NTTIME now;
+
+ must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx,
+ domain_dn, msg);
+
+ /* Test account expire time */
+ unix_to_nt_time(&now, time(NULL));
+ /* check for expired password */
+ if ((must_change_time != 0) && (must_change_time < now)) {
+ acct_flags |= ACB_PW_EXPIRED;
+ }
+ }
+ }
+ return acct_flags;
}
struct ldb_message **ret_msg)
{
int ret;
+ unsigned int group_type;
char *name;
struct ldb_message *msg2;
struct ldb_dn *dom_dn;
}
}
+ if (ldb_msg_find_element(msg2, "sAMAccountType") != NULL) {
+ ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be specified");
+ talloc_free(mem_ctx);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ group_type = samdb_result_uint(msg2, "groupType", 0);
+ if (group_type == 0) {
+ ldb_asprintf_errstring(module->ldb, "groupType invalid");
+ talloc_free(mem_ctx);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ } else {
+ unsigned int account_type = samdb_gtype2atype(group_type);
+ ret = samdb_msg_add_uint(module->ldb, msg2, msg2,
+ "sAMAccountType",
+ account_type);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
/* Manage SID allocation, conflicts etc */
ret = samldb_handle_sid(module, mem_ctx, msg2, dom_dn);
const char *rdn_name;
TALLOC_CTX *mem_ctx = talloc_new(msg);
const char *errstr;
+ unsigned int user_account_control;
if (!mem_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
}
return LDB_ERR_OPERATIONS_ERROR;
}
- if (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL) {
-
- ret = samdb_copy_template(module->ldb, msg2,
- "computer",
- &errstr);
- if (ret) {
- ldb_asprintf_errstring(module->ldb,
- "samldb_fill_user_or_computer_object: "
- "Error copying computer template: %s",
- errstr);
- talloc_free(mem_ctx);
- return ret;
- }
- } else {
- ret = samdb_copy_template(module->ldb, msg2,
- "user",
- &errstr);
- if (ret) {
- ldb_asprintf_errstring(module->ldb,
- "samldb_fill_user_or_computer_object: Error copying user template: %s\n",
- errstr);
- talloc_free(mem_ctx);
- return ret;
- }
- /* readd user objectclass */
- ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "user");
- if (ret) {
- talloc_free(mem_ctx);
- return ret;
- }
+ ret = samdb_copy_template(module->ldb, msg2,
+ "user",
+ &errstr);
+ if (ret) {
+ ldb_asprintf_errstring(module->ldb,
+ "samldb_fill_user_or_computer_object: Error copying user template: %s\n",
+ errstr);
+ talloc_free(mem_ctx);
+ return ret;
}
rdn_name = ldb_dn_get_rdn_name(msg2->dn);
}
}
- /*
- TODO: useraccountcontrol: setting value 0 gives 0x200 for users
- */
+ if (ldb_msg_find_element(msg2, "sAMAccountType") != NULL) {
+ ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be specified");
+ talloc_free(mem_ctx);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ user_account_control = samdb_result_uint(msg2, "userAccountControl", 0);
+ if (user_account_control == 0) {
+ ldb_asprintf_errstring(module->ldb, "userAccountControl invalid");
+ talloc_free(mem_ctx);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ } else {
+ unsigned int account_type = samdb_uf2atype(user_account_control);
+ ret = samdb_msg_add_uint(module->ldb, msg2, msg2,
+ "sAMAccountType",
+ account_type);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
/* Manage SID allocation, conflicts etc */
ret = samldb_handle_sid(module, mem_ctx, msg2, dom_dn);
- /* TODO: objectCategory, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */
+ /* TODO: userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */
if (ret == 0) {
*ret_msg = msg2;
}
/* is user or computer? */
- if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != NULL) ||
+ if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != NULL) ||
(samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL)) {
/* add all relevant missing objects */
ret = samldb_fill_user_or_computer_object(module, msg, &msg2);
return ret;
}
+/* modify */
+static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
+{
+ struct ldb_message *msg;
+ struct ldb_message_element *el, *el2;
+ int ret;
+ unsigned int group_type, user_account_control, account_type;
+ if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) {
+ ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be specified");
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+
+ el = ldb_msg_find_element(req->op.mod.message, "groupType");
+ if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+ req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
+
+ group_type = strtoul((const char *)el->values[0].data, NULL, 0);
+ account_type = samdb_gtype2atype(group_type);
+ ret = samdb_msg_add_uint(module->ldb, msg, msg,
+ "sAMAccountType",
+ account_type);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ el2 = ldb_msg_find_element(msg, "sAMAccountType");
+ el2->flags = LDB_FLAG_MOD_REPLACE;
+ }
+
+ el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
+ if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+ req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
+
+ user_account_control = strtoul((const char *)el->values[0].data, NULL, 0);
+ account_type = samdb_uf2atype(user_account_control);
+ ret = samdb_msg_add_uint(module->ldb, msg, msg,
+ "sAMAccountType",
+ account_type);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ el2 = ldb_msg_find_element(msg, "sAMAccountType");
+ el2->flags = LDB_FLAG_MOD_REPLACE;
+ }
+ return ldb_next_request(module, req);
+}
+
+
static int samldb_init(struct ldb_module *module)
{
return ldb_next_init(module);
.name = "samldb",
.init_context = samldb_init,
.add = samldb_add,
+ .modify = samldb_modify
};
"RDN mismatch on %s: %s (%s)",
ldb_dn_get_linearized(msg->dn), rdn_name, rdn_val.data);
talloc_free(down_req);
- return LDB_ERR_OPERATIONS_ERROR;
+ /* Match AD's error here */
+ return LDB_ERR_INVALID_DN_SYNTAX;
}
}
#include "auth/auth.h"
#include "auth/auth_sam_reply.h"
#include "dsdb/samdb/samdb.h"
+#include "dsdb/common/flags.h"
#include "rpc_server/samr/proto.h"
#include "util/util_ldb.h"
#include "libcli/auth/libcli_auth.h"
struct creds_CredentialState *creds;
void *sam_ctx;
struct samr_Password *mach_pwd;
- uint16_t acct_flags;
+ uint32_t user_account_control;
int num_records;
struct ldb_message **msgs;
NTSTATUS nt_status;
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- acct_flags = samdb_result_acct_flags(msgs[0],
- "userAccountControl");
+
+ user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
- if (acct_flags & ACB_DISABLED) {
+ if (user_account_control & UF_ACCOUNTDISABLE) {
DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
return NT_STATUS_ACCESS_DENIED;
}
if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
- if (!(acct_flags & ACB_WSTRUST)) {
- DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
+ if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
+ DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
return NT_STATUS_ACCESS_DENIED;
}
} else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
- if (!(acct_flags & ACB_DOMTRUST)) {
- DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
+ if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
+ DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
+
return NT_STATUS_ACCESS_DENIED;
}
} else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
- if (!(acct_flags & ACB_SVRTRUST)) {
- DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
+ if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
+ DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
return NT_STATUS_ACCESS_DENIED;
}
} else {
#define QUERY_LHOURS(msg, field, attr) \
r->out.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);
+ r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
/* these are used to make the Set[User|Group]Info code easier to follow */
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 (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \
+ 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); \
for (i=0;i<count;i++) {
/* Check if a mask has been requested */
if (r->in.acct_flags
- && ((samdb_result_acct_flags(res[i],
- "userAccountControl") & r->in.acct_flags) == 0)) {
+ && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res[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);
}
case 16:
{
- static const char * const attrs2[] = {"userAccountControl", NULL};
+ static const char * const attrs2[] = {"userAccountControl", "pwdLastSet", NULL};
attrs = attrs2;
break;
}
struct ldb_message **res;
int ldb_cnt, count, i;
const char * const attrs[] = { "objectSid", "sAMAccountName", "displayName",
- "description", "userAccountControl", NULL };
+ "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", "");
/* 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") | ACB_NORMAL;
+ 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;
"server_sort",
"extended_dn",
"asq",
- "samldb",
"rdn_name",
"objectclass",
+ "samldb",
"kludge_acl",
"operational"]
tdb_modules_list = [
primaryGroupID: 516
accountExpires: 9223372036854775807
sAMAccountName: ${NETBIOSNAME}$
-sAMAccountType: 805306369
operatingSystem: Samba
operatingSystemVersion: 4.0
dNSHostName: ${DNSNAME}
userAccountControl: 514
accountExpires: 9223372036854775807
sAMAccountName: dns
-sAMAccountType: 805306368
servicePrincipalName: DNS/${DNSDOMAIN}
isCriticalSystemObject: TRUE
sambaPassword:: ${DNSPASS_B64}
description: Container for SAM account templates
dn: CN=TemplateUser,CN=Templates
-userAccountControl: 514
+userAccountControl: 546
badPwdCount: 0
codePage: 0
countryCode: 0
primaryGroupID: 513
accountExpires: -1
logonCount: 0
-sAMAccountType: 805306368
-
-dn: CN=TemplateComputer,CN=Templates
-userAccountControl: 4098
-badPwdCount: 0
-codePage: 0
-countryCode: 0
-badPasswordTime: 0
-lastLogoff: 0
-lastLogon: 0
-pwdLastSet: 0
-primaryGroupID: 513
-accountExpires: -1
-logonCount: 0
-sAMAccountType: 805306369
dn: CN=TemplateTrustingDomain,CN=Templates
userAccountControl: 2080
primaryGroupID: 513
accountExpires: -1
logonCount: 0
-sAMAccountType: 805306370
dn: CN=TemplateGroup,CN=Templates
groupType: -2147483646
-sAMAccountType: 268435456
-
-# Currently this isn't used, we don't have a way to detect it different from an incoming alias
-#
-# dn: CN=TemplateAlias,CN=Templates
-# cn: TemplateAlias
-# groupType: -2147483644
-# sAMAccountType: 268435456
dn: CN=TemplateForeignSecurityPrincipal,CN=Templates
adminCount: 1
accountExpires: 9223372036854775807
sAMAccountName: krbtgt
-sAMAccountType: 805306368
servicePrincipalName: kadmin/changepw
isCriticalSystemObject: TRUE
sambaPassword:: ${KRBTGTPASS_B64}
cn: Cert Publishers
description: Members of this group are permitted to publish certificates to the Active Directory
groupType: 2147483652
-sAMAccountType: 536870912
objectSid: ${DOMAINSID}-517
sAMAccountName: Cert Publishers
isCriticalSystemObject: TRUE
description: Servers in this group can access remote access properties of users
objectSid: ${DOMAINSID}-553
sAMAccountName: RAS and IAS Servers
-sAMAccountType: 536870912
groupType: 2147483652
isCriticalSystemObject: TRUE
objectSid: S-1-5-32-544
adminCount: 1
sAMAccountName: Administrators
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
member: CN=Domain Users,CN=Users,${DOMAINDN}
objectSid: S-1-5-32-545
sAMAccountName: Users
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
member: CN=Guest,CN=Users,${DOMAINDN}
objectSid: S-1-5-32-546
sAMAccountName: Guests
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
objectSid: S-1-5-32-550
adminCount: 1
sAMAccountName: Print Operators
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
objectSid: S-1-5-32-551
adminCount: 1
sAMAccountName: Backup Operators
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
objectSid: S-1-5-32-552
adminCount: 1
sAMAccountName: Replicator
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members in this group are granted the right to logon remotely
objectSid: S-1-5-32-555
sAMAccountName: Remote Desktop Users
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members in this group can have some administrative privileges to manage configuration of networking features
objectSid: S-1-5-32-556
sAMAccountName: Network Configuration Operators
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members of this group have remote access to monitor this computer
objectSid: S-1-5-32-558
sAMAccountName: Performance Monitor Users
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members of this group have remote access to schedule logging of performance counters on this computer
objectSid: S-1-5-32-559
sAMAccountName: Performance Log Users
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
objectSid: S-1-5-32-549
adminCount: 1
sAMAccountName: Server Operators
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
objectSid: S-1-5-32-548
adminCount: 1
sAMAccountName: Account Operators
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: A backward compatibility group which allows read access on all users and groups in the domain
objectSid: S-1-5-32-554
sAMAccountName: Pre-Windows 2000 Compatible Access
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members of this group can create incoming, one-way trusts to this forest
objectSid: S-1-5-32-557
sAMAccountName: Incoming Forest Trust Builders
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members of this group have access to the computed tokenGroupsGlobalAndUniversal attribute on User objects
objectSid: S-1-5-32-560
sAMAccountName: Windows Authorization Access Group
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Terminal Server License Servers
objectSid: S-1-5-32-561
sAMAccountName: Terminal Server License Servers
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
description: Members are allowed to launch, activate and use Distributed COM objects on this machine.
objectSid: S-1-5-32-562
sAMAccountName: Distributed COM Users
-sAMAccountType: 536870912
systemFlags: 2348810240
groupType: 2147483653
isCriticalSystemObject: TRUE
const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
+ const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL),
+ (ACB_NORMAL | ACB_PWNOEXP),
+ (ACB_NORMAL) };
const char *homedir, *homedrive, *logonscript;
struct timeval now;
int i, testfld;
- srandom((unsigned)time(NULL));
-
printf("Fields to change: [");
for (i = 0; i < num_changes && i < FIELDS_NUM; i++) {
case home_directory:
continue_if_field_set(r->in.home_directory);
- homedir = home_dirs[random() % (sizeof(home_dirs)/sizeof(char*))];
+ homedir = home_dirs[random() % ARRAY_SIZE(home_dirs)];
r->in.home_directory = talloc_strdup(mem_ctx, homedir);
fldname = "home_dir";
break;
case home_drive:
continue_if_field_set(r->in.home_drive);
- homedrive = home_drives[random() % (sizeof(home_drives)/sizeof(char*))];
+ homedrive = home_drives[random() % ARRAY_SIZE(home_drives)];
r->in.home_drive = talloc_strdup(mem_ctx, homedrive);
fldname = "home_drive";
break;
case logon_script:
continue_if_field_set(r->in.logon_script);
- logonscript = logon_scripts[random() % (sizeof(logon_scripts)/sizeof(char*))];
+ logonscript = logon_scripts[random() % ARRAY_SIZE(logon_scripts)];
r->in.logon_script = talloc_strdup(mem_ctx, logonscript);
fldname = "logon_script";
break;
fldname = "acct_expiry";
break;
+ case acct_flags:
+ continue_if_field_set(r->in.acct_flags);
+ r->in.acct_flags = flags[random() % ARRAY_SIZE(flags)];
+ fldname = "acct_flags";
+ break;
+
default:
fldname = "unknown_field";
}
case acct_flags:
continue_if_field_set(mod->in.change.acct_flags);
- mod->in.change.acct_flags = flags[random() % (sizeof(flags)/sizeof(uint32_t))];
+ mod->in.change.acct_flags = flags[random() % ARRAY_SIZE(flags)];
mod->in.change.fields |= USERMOD_FIELD_ACCT_FLAGS;
fldname = "acct_flags";
break;
TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
SAMR_FIELD_LOGON_HOURS);
- if (torture_setting_bool(tctx, "samba4", false)) {
- printf("skipping Set Account Flag tests against Samba4\n");
- return ret;
- }
-
TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
(base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
(base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
const char *base_acct_name, enum torture_samr_choice which_ops)
{
char *password = NULL;
+ struct samr_QueryUserInfo q;
+ NTSTATUS status;
bool ret = true;
int i;
+ uint32_t rid;
const uint32_t password_fields[] = {
SAMR_FIELD_PASSWORD,
SAMR_FIELD_PASSWORD2,
0
};
+ status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = false;
+ }
+
switch (which_ops) {
case TORTURE_SAMR_USER_ATTRIBUTES:
if (!test_QuerySecurity(p, tctx, user_handle)) {
ret = false;
}
+ q.in.user_handle = user_handle;
+ q.in.level = 5;
+
+ status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("QueryUserInfo level %u failed - %s\n",
+ q.in.level, nt_errstr(status));
+ ret = false;
+ } else {
+ uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
+ if ((q.out.info->info5.acct_flags) != expected_flags) {
+ printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
+ q.out.info->info5.acct_flags,
+ expected_flags);
+ ret = false;
+ }
+ if (q.out.info->info5.rid != rid) {
+ printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
+ q.out.info->info5.rid, rid);
+
+ }
+ }
+
break;
case TORTURE_SAMR_OTHER:
/* We just need the account to exist */
q.in.level, nt_errstr(status));
ret = false;
} else {
- if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
+ uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
+ if (acct_flags == ACB_NORMAL) {
+ expected_flags |= ACB_PW_EXPIRED;
+ }
+ if ((q.out.info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
q.out.info->info5.acct_flags,
- acct_flags);
+ expected_flags);
ret = false;
}
switch (acct_flags) {
for (j=0; j<num_names; j++) {
if (names[j] == NULL)
continue;
- /* Hmm. No strequal in samba4 */
if (strequal(names[j], name)) {
names[j] = NULL;
found = true;
{
println("Running basic tests");
+ ldb.del("cn=ldaptestcomputer,cn=computers," + base_dn);
+ ldb.del("cn=ldaptestcomputer3,cn=computers," + base_dn);
+ ldb.del("cn=ldaptest2computer,cn=computers," + base_dn);
ldb.del("cn=ldaptestuser,cn=users," + base_dn);
ldb.del("cn=ldaptestuser2,cn=users," + base_dn);
ldb.del("cn=ldaptestuser3,cn=users," + base_dn);
ldb.del("cn=ldaptestuser4,cn=users," + base_dn);
ldb.del("cn=ldaptestuser5,cn=users," + base_dn);
ldb.del("CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn);
+ ldb.del("cn=ldaptestuser7,cn=users," + base_dn);
ldb.del("CN=ldaptestcontainer2," + base_dn);
ldb.del("cn=ldaptestgroup,cn=users," + base_dn);
+ ldb.del("cn=ldaptestgroup2,cn=users," + base_dn);
println("Testing group add with invalid member");
var ok = ldb.add("
ok = ldb.del("cn=ldaptest2computer,cn=computers," + base_dn);
if (ok.error != 0) {
println(ok.errstr);
- assert(ok.error == 0);
+ // assert(ok.error == 0);
}
ok = ldb.add("
dn: cn=ldaptest2computer,cn=computers," + base_dn + "
}
}
+ var ok = ldb.add("
+dn: cn=ldaptestcomputer3,cn=computers," + base_dn + "
+objectClass: computer
+cn: LDAPtest2COMPUTER
+");
+ if (ok.error != 34) {
+ println("Did not reject invalid RDN compared with DN: " + ok.errstr);
+ assert(ok.error == 34);
+ }
+
+ var ok = ldb.add("
+dn: cn=ldaptestcomputer3,cn=computers," + base_dn + "
+objectClass: computer
+cn: LDAPtestCOMPUTER3
+sAMAccountType: 805306368
+");
+
+ if (ok.error != 53) {
+ println("Did not reject invalid 'sAMAccountType: 805306368': " + ok.errstr);
+ assert(ok.error == 53);
+ }
+
+ var ok = ldb.add("
+dn: cn=ldaptestcomputer3,cn=computers," + base_dn + "
+objectClass: computer
+cn: LDAPtestCOMPUTER3
+userAccountControl: 0
+");
+
+ if (ok.error != 53) {
+ println("Did not reject invalid 'userAccountControl: 0': " + ok.errstr);
+ assert(ok.error == 53);
+ }
+
+ var ok = ldb.add("
+dn: cn=ldaptestuser7,cn=users," + base_dn + "
+objectClass: user
+cn: LDAPtestuser7
+userAccountControl: 0
+");
+
+ if (ok.error != 53) {
+ println("Did not reject invalid 'userAccountControl: 0': " + ok.errstr);
+ assert(ok.error == 53);
+ }
+
+ var ok = ldb.add("
+dn: cn=ldaptestuser7,cn=users," + base_dn + "
+objectClass: user
+cn: LDAPtestuser7
+userAccountControl: 2
+");
+
+ if (ok.error != 0) {
+ println("Did not accept 'userAccountControl: 2': " + ok.errstr);
+ assert(ok.error == 0);
+ }
+
+ ldb.del("cn=ldaptestuser7,cn=users," + base_dn);
+
+ var ok = ldb.add("
+dn: cn=ldaptestcomputer3,cn=computers," + base_dn + "
+objectclass: computer
+cN: LDAPtestCOMPUTER3
+");
+ if (ok.error != 0) {
+ ok = ldb.del("cn=ldaptestcomputer3,cn=computers," + base_dn);
+ if (ok.error != 0) {
+ println(ok.errstr);
+ assert(ok.error == 0);
+ }
+ ok = ldb.add("
+dn: cn=ldaptestcomputer3,cn=computers," + base_dn + "
+objectClass: computer
+cn: LDAPtestCOMPUTER3
+");
+ if (ok.error != 0) {
+ println(ok.errstr);
+ assert(ok.error == 0);
+ }
+ }
+
+ println("Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))");
+ var res = ldb.search("(&(cn=ldaptestcomputer3)(objectClass=user))");
+ if (res.error != 0 || res.msgs.length != 1) {
+ println("Could not find (&(cn=ldaptestcomputer3)(objectClass=user))");
+ assert(res.error == 0);
+ assert(res.msgs.length == 1);
+ }
+
+ assert(res.msgs[0].dn == ("CN=ldaptestcomputer3,CN=Computers," + base_dn));
+ assert(res.msgs[0].cn == "ldaptestcomputer3");
+ assert(res.msgs[0].name == "ldaptestcomputer3");
+ assert(res.msgs[0].objectClass[0] == "top");
+ assert(res.msgs[0].objectClass[1] == "person");
+ assert(res.msgs[0].objectClass[2] == "organizationalPerson");
+ assert(res.msgs[0].objectClass[3] == "user");
+ assert(res.msgs[0].objectClass[4] == "computer");
+ assert(res.msgs[0].objectGUID != undefined);
+ assert(res.msgs[0].whenCreated != undefined);
+ assert(res.msgs[0].objectCategory == ("CN=Computer,CN=Schema,CN=Configuration," + base_dn));
+ assert(res.msgs[0].primaryGroupID == 513);
+ assert(res.msgs[0].sAMAccountType == 805306368);
+ assert(res.msgs[0].userAccountControl == 546);
+
+ ldb.del(res.msgs[0].dn);
+
println("Testing attribute or value exists behaviour");
ok = ldb.modify("
dn: cn=ldaptest2computer,cn=computers," + base_dn + "
assert(res.msgs.length == 2);
}
+ var res = ldb.search("(&(anr=testy ldap)(objectClass=user))");
+ if (res.error != 0 || res.msgs.length != 2) {
+ println("Found only " + res.msgs.length + " for (&(anr=\"testy ldap\")(objectClass=user))");
+ assert(res.error == 0);
+ assert(res.msgs.length == 2);
+ }
+
// Testing ldb.search for (&(anr=ldap)(objectClass=user))
var res = ldb.search("(&(anr=ldap)(objectClass=user))");
if (res.error != 0 || res.msgs.length != 4) {
assert(res.msgs[0].cn == "ldaptestUSER3");
assert(res.msgs[0].name == "ldaptestUSER3");
+ println("Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))");
+ var res = ldb.search("(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))");
+ if (res.error != 0 || res.msgs.length != 1) {
+ println("Could not find (&(cn=ldaptestuser3)(objectClass=user))");
+ assert(res.error == 0);
+ assert(res.msgs.length == 1);
+ }
+
+ assert(res.msgs[0].dn == ("CN=ldaptestUSER3,CN=Users," + base_dn));
+ assert(res.msgs[0].cn == "ldaptestUSER3");
+ assert(res.msgs[0].name == "ldaptestUSER3");
+
+ println("Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))");
+ var res = ldb.search("(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))");
+ if (res.error != 0 || res.msgs.length != 1) {
+ println("Could not find (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))");
+ assert(res.error == 0);
+ assert(res.msgs.length == 1);
+ }
+
+ assert(res.msgs[0].dn == ("CN=ldaptestUSER3,CN=Users," + base_dn));
+ assert(res.msgs[0].cn == "ldaptestUSER3");
+ assert(res.msgs[0].name == "ldaptestUSER3");
+
+ println("Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))");
+ var res = ldb.search("(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))");
+ if (res.error != 0 || res.msgs.length != 0) {
+ println("Should not find (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))");
+ assert(res.error == 0);
+ assert(res.msgs.length == 0);
+ }
+
// This is a Samba special, and does not exist in real AD
// println("Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + base_dn + ")");
// var res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + base_dn + ")");
assert(res.msgs[0].whenCreated != undefined);
assert(res.msgs[0].objectCategory == ("CN=Person,CN=Schema,CN=Configuration," + base_dn));
assert(res.msgs[0].sAMAccountType == 805306368);
-// assert(res[0].userAccountControl == 546);
+ assert(res.msgs[0].userAccountControl == 546);
assert(res.msgs[0].memberOf[0] == ("CN=ldaptestgroup2,CN=Users," + base_dn));
assert(res.msgs[0].memberOf.length == 1);
println("Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))");
var res = ldb.search("(&(cn=ldaptestcomputer)(objectClass=user))");
if (res.error != 0 || res.msgs.length != 1) {
- println("Could not find (&(cn=ldaptestuser)(objectClass=user))");
+ println("Could not find (&(cn=ldaptestcomputer)(objectClass=user))");
assert(res.error == 0);
assert(res.msgs.length == 1);
}
assert(res.msgs[0].objectClass[4] == "computer");
assert(res.msgs[0].objectGUID != undefined);
assert(res.msgs[0].whenCreated != undefined);
- assert(res.msgs[0].objectCategory == ("CN=Computer,CN=Schema,CN=Configuration," + base_dn));
- assert(res.msgs[0].primaryGroupID == 513);
-// assert(res.msgs[0].sAMAccountType == 805306368);
-// assert(res.msgs[0].userAccountControl == 546);
- assert(res.msgs[0].memberOf[0] == ("CN=ldaptestgroup2,CN=Users," + base_dn));
- assert(res.msgs[0].memberOf.length == 1);
+ assert(res.msgs[0].objectCategory == "cn=Computer,cn=Schema,cn=Configuration," + base_dn);
+ assert(res.msgs[0].sAMAccountType == 805306368);
+ assert(res.msgs[0].userAccountControl == 546);
println("Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + base_dn + "))");
var res2 = ldb.search("(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + base_dn + "))");
assert(res.msgs[0].whenCreated != undefined);
assert(res.msgs[0].objectCategory == "cn=Computer,cn=Schema,cn=Configuration," + base_dn);
assert(res.msgs[0].sAMAccountType == 805306369);
-// assert(res.msgs[0].userAccountControl == 4098);
+ assert(res.msgs[0].userAccountControl == 4096);
ok = ldb.del(res.msgs[0].dn);