#include "librpc/gen_ndr/ndr_lsa_c.h"
#include "param/param.h"
#include "libcli/security/security.h"
-#include "lib/ldb/include/ldb.h"
+#include <ldb.h>
#include "lib/util/util_ldb.h"
#include "ldb_wrap.h"
#include "lib/replace/system/network.h"
new_password.length = IVAL(password_buf.data, 512);
torture_comment(tctx,
- "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
+ "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
netlogon_creds_client_authenticator(creds, &credential);
NTSTATUS status;
struct netr_LogonSamLogon r;
struct netr_Authenticator auth, auth2;
+ static const struct netr_Authenticator auth_zero;
union netr_LogonLevel logon;
union netr_Validation validation;
uint8_t authoritative;
flags |= CLI_CRED_LANMAN_AUTH;
}
- if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
+ if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
flags |= CLI_CRED_NTLMv2_AUTH;
}
d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
- for (i=2;i<3;i++) {
+ for (i=2;i<=3;i++) {
ZERO_STRUCT(auth2);
netlogon_creds_client_authenticator(creds, &auth);
torture_assert(tctx, netlogon_creds_client_check(creds,
&r.out.return_authenticator->cred),
"Credential chaining failed");
+ torture_assert_int_equal(tctx, *r.out.authoritative, 1,
+ "LogonSamLogon invalid *r.out.authoritative");
+ }
+
+ /* this makes sure we get the unmarshalling right for invalid levels */
+ for (i=52;i<53;i++) {
+ ZERO_STRUCT(auth2);
+ /* the authenticator should be ignored by the server */
+ generate_random_buffer((uint8_t *) &auth, sizeof(auth));
+
+ r.in.validation_level = i;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
+ "LogonSamLogon failed");
+ torture_assert_ntstatus_equal(tctx, r.out.result,
+ NT_STATUS_INVALID_INFO_CLASS,
+ "LogonSamLogon failed");
+
+ torture_assert_int_equal(tctx, *r.out.authoritative, 1,
+ "LogonSamLogon invalid *r.out.authoritative");
+ torture_assert(tctx,
+ memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
+ "Return authenticator non zero");
+ }
+
+ for (i=2;i<=3;i++) {
+ ZERO_STRUCT(auth2);
+ netlogon_creds_client_authenticator(creds, &auth);
+
+ r.in.validation_level = i;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
+ "LogonSamLogon failed");
+ torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
+
+ torture_assert(tctx, netlogon_creds_client_check(creds,
+ &r.out.return_authenticator->cred),
+ "Credential chaining failed");
+ torture_assert_int_equal(tctx, *r.out.authoritative, 1,
+ "LogonSamLogon invalid *r.out.authoritative");
+ }
+
+ r.in.logon_level = 52;
+
+ for (i=2;i<=3;i++) {
+ ZERO_STRUCT(auth2);
+ /* the authenticator should be ignored by the server */
+ generate_random_buffer((uint8_t *) &auth, sizeof(auth));
+
+ r.in.validation_level = i;
+
+ torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
+ "LogonSamLogon failed");
+ torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
+ "LogonSamLogon expected INVALID_PARAMETER");
+
+ torture_assert(tctx,
+ memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
+ "Return authenticator non zero");
+ torture_assert_int_equal(tctx, *r.out.authoritative, 1,
+ "LogonSamLogon invalid *r.out.authoritative");
}
r.in.credential = NULL;
for (i=2;i<=3;i++) {
+ ZERO_STRUCT(auth2);
r.in.validation_level = i;
torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
"LogonSamLogon expected INVALID_PARAMETER");
+ torture_assert(tctx,
+ memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
+ "Return authenticator non zero");
+ torture_assert_int_equal(tctx, *r.out.authoritative, 1,
+ "LogonSamLogon invalid *r.out.authoritative");
+ }
+
+ r.in.logon_level = 2;
+ r.in.credential = &auth;
+
+ for (i=2;i<=3;i++) {
+ ZERO_STRUCT(auth2);
+ netlogon_creds_client_authenticator(creds, &auth);
+
+ r.in.validation_level = i;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
+ "LogonSamLogon failed");
+ torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
+
+ torture_assert(tctx, netlogon_creds_client_check(creds,
+ &r.out.return_authenticator->cred),
+ "Credential chaining failed");
+ torture_assert_int_equal(tctx, *r.out.authoritative, 1,
+ "LogonSamLogon invalid *r.out.authoritative");
}
return true;
return test_netlogon_ops_args(p, tctx, credentials, creds, false);
}
+/*
+ try a netlogon GetCapabilities
+*/
+bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
+ struct cli_credentials *credentials,
+ struct netlogon_creds_CredentialState *creds)
+{
+ NTSTATUS status;
+ struct netr_LogonGetCapabilities r;
+ union netr_Capabilities capabilities;
+ struct netr_Authenticator auth, return_auth;
+ struct netlogon_creds_CredentialState tmp_creds;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.computer_name = cli_credentials_get_workstation(credentials);
+ r.in.credential = &auth;
+ r.in.return_authenticator = &return_auth;
+ r.in.query_level = 1;
+ r.out.capabilities = &capabilities;
+ r.out.return_authenticator = &return_auth;
+
+ torture_comment(tctx, "Testing LogonGetCapabilities\n");
+
+ ZERO_STRUCT(return_auth);
+
+ /*
+ * we need to operate on a temporary copy of creds
+ * because dcerpc_netr_LogonGetCapabilities was
+ * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
+ * without looking a the authenticator.
+ */
+ tmp_creds = *creds;
+ netlogon_creds_client_authenticator(&tmp_creds, &auth);
+
+ status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
+ if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
+ return true;
+ }
+
+ *creds = tmp_creds;
+
+ torture_assert(tctx, netlogon_creds_client_check(creds,
+ &r.out.return_authenticator->cred),
+ "Credential chaining failed");
+
+ torture_assert_int_equal(tctx, creds->negotiate_flags,
+ capabilities.server_capabilities,
+ "negotiate flags");
+
+ return true;
+}
+
/*
try a netlogon SamLogon
*/
}
}
+ r.in.level = 52;
+ torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
+ status = dcerpc_netr_LogonControl_r(b, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
+
return true;
}
for (i=1;i<4;i++) {
r.in.level = i;
- torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
- i, r.in.function_code);
+ torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "LogonControl");
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
}
data.domain = lpcfg_workgroup(tctx->lp_ctx);
for (i=1;i<4;i++) {
r.in.level = i;
- torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
- i, r.in.function_code);
+ torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "LogonControl");
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
}
data.domain = lpcfg_workgroup(tctx->lp_ctx);
for (i=1;i<4;i++) {
r.in.level = i;
- torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
- i, r.in.function_code);
+ torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "LogonControl");
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
}
data.debug_level = ~0;
for (i=1;i<4;i++) {
r.in.level = i;
- torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
- i, r.in.function_code);
+ torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "LogonControl");
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
}
+ ZERO_STRUCT(data);
+ r.in.function_code = 52;
+ r.in.data = &data;
+
+ torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
+
+ status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
+
+ data.debug_level = ~0;
+
+ r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
+ r.in.data = &data;
+
+ r.in.level = 52;
+ torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
+ function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
+
+ status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
+
return true;
}
info->dc_site_name);
}
+/* This is a substitution for "samdb_server_site_name" which relies on the
+ * correct "lp_ctx" and therefore can't be used here. */
+static const char *server_site_name(struct torture_context *tctx,
+ struct ldb_context *ldb)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *dn, *server_dn;
+ const struct ldb_val *site_name_val;
+ const char *server_dn_str, *site_name;
+
+ tmp_ctx = talloc_new(ldb);
+ if (tmp_ctx == NULL) {
+ goto failed;
+ }
+
+ dn = ldb_dn_new(tmp_ctx, ldb, "");
+ if (dn == NULL) {
+ goto failed;
+ }
+
+ server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
+ NULL);
+ if (server_dn_str == NULL) {
+ goto failed;
+ }
+
+ server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
+ if (server_dn == NULL) {
+ goto failed;
+ }
+
+ /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
+ site_name_val = ldb_dn_get_component_val(server_dn, 2);
+ if (site_name_val == NULL) {
+ goto failed;
+ }
+
+ site_name = (const char *) site_name_val->data;
+
+ talloc_steal(tctx, site_name);
+ talloc_free(tmp_ctx);
+
+ return site_name;
+
+failed:
+ talloc_free(tmp_ctx);
+ return NULL;
+}
+
static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
"we should per default only get the default site");
if (sam_ctx != NULL) {
torture_assert_casestr_equal(tctx, ctr->sites[0].string,
- samdb_server_site_name(sam_ctx, tctx),
+ server_site_name(tctx, sam_ctx),
"didn't return default site");
}
for (i = 0; i < 3; i++) {
torture_assert_casestr_equal(tctx,
ctr->sitename[i].string,
- samdb_server_site_name(sam_ctx, tctx),
+ server_site_name(tctx, sam_ctx),
"didn't return default site");
}
for (i = 3; i < 6; i++) {
if (torture_setting_bool(tctx, "samba4", false)) {
torture_assert_casestr_equal(tctx,
ctr->sitename[i].string,
- samdb_server_site_name(sam_ctx, tctx),
+ server_site_name(tctx, sam_ctx),
"didn't return default site");
}
}
for (i = 0; i < 3; i++) {
torture_assert_casestr_equal(tctx,
ctr->sitename[i].string,
- samdb_server_site_name(sam_ctx, tctx),
+ server_site_name(tctx, sam_ctx),
"didn't return default site");
torture_assert(tctx, ctr->subnetname[i].string == NULL,
"subnet should be null");
if (torture_setting_bool(tctx, "samba4", false)) {
torture_assert_casestr_equal(tctx,
ctr->sitename[i].string,
- samdb_server_site_name(sam_ctx, tctx),
+ server_site_name(tctx, sam_ctx),
"didn't return default site");
}
torture_assert(tctx, ctr->subnetname[i].string == NULL,
info.domain_info->dns_hostname.string,
query.workstation_info->dns_hostname,
"In/Out 'DNS hostnames' don't match!");
+ old_dnsname = info.domain_info->dns_hostname.string;
/* Checks "workstation flags" */
torture_assert(tctx,
"Trusted domains have been requested!");
+ torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
+ netlogon_creds_client_authenticator(creds, &a);
+
+ query.workstation_info->dns_hostname = NULL;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
+ "LogonGetDomainInfo failed");
+ torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
+ torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
+
+ /* The old DNS hostname should stick */
+ torture_assert_str_equal(tctx,
+ info.domain_info->dns_hostname.string,
+ old_dnsname,
+ "'DNS hostname' changed!");
+
+
if (!torture_setting_bool(tctx, "dangerous", false)) {
- torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 6th call (no workstation info) - enable dangerous tests in order to do so\n");
+ torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 7th call (no workstation info) - enable dangerous tests in order to do so\n");
} else {
/* Try a call without the workstation information structure */
- torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no workstation info)\n");
+ torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (no workstation info)\n");
netlogon_creds_client_authenticator(creds, &a);
query.workstation_info = NULL;
/* even with this flush per request a w2k3 server seems to
clag with multiple outstanding requests. bleergh. */
- torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
- "event_loop_once failed");
+ torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
+ "tevent_loop_once failed");
}
for (i=0;i<ASYNC_COUNT;i++) {
struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
struct torture_rpc_tcase *tcase;
struct torture_test *test;
struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
struct torture_rpc_tcase *tcase;
tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-ADMIN");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
struct torture_rpc_tcase *tcase;
tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",