diff options
author | Andrew Bartlett <abartlet@samba.org> | 2008-08-26 16:26:08 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2008-08-26 16:26:08 +1000 |
commit | f08786686c0bf2440e35ce29b8e0b1a2f116fe3a (patch) | |
tree | fd7ac6f7cd8528c550952731347f03397c70df77 /source4/torture | |
parent | b5a3f45f645204bcc3d6caa47993b7839c8e4c99 (diff) | |
parent | 4eba234a7352094e1640e8ff9d80a20f8d4705a3 (diff) | |
download | samba-f08786686c0bf2440e35ce29b8e0b1a2f116fe3a.tar.gz samba-f08786686c0bf2440e35ce29b8e0b1a2f116fe3a.tar.bz2 samba-f08786686c0bf2440e35ce29b8e0b1a2f116fe3a.zip |
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into pac-verify
(This used to be commit b706708210a05d6f10474a3cd2bbc550704d4356)
Diffstat (limited to 'source4/torture')
-rw-r--r-- | source4/torture/auth/pac.c | 97 | ||||
-rw-r--r-- | source4/torture/ldap/cldap.c | 146 | ||||
-rw-r--r-- | source4/torture/nbt/dgram.c | 4 | ||||
-rw-r--r-- | source4/torture/nbt/winsreplication.c | 12 | ||||
-rw-r--r-- | source4/torture/raw/offline.c | 19 | ||||
-rw-r--r-- | source4/torture/raw/open.c | 44 | ||||
-rw-r--r-- | source4/torture/rpc/atsvc.c | 4 | ||||
-rw-r--r-- | source4/torture/rpc/dssync.c | 15 | ||||
-rw-r--r-- | source4/torture/rpc/lsa.c | 151 | ||||
-rw-r--r-- | source4/torture/smb2/create.c | 101 |
10 files changed, 456 insertions, 137 deletions
diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c index 7fdd7e58bf..4e51c66950 100644 --- a/source4/torture/auth/pac.c +++ b/source4/torture/auth/pac.c @@ -279,7 +279,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) struct auth_serversupplied_info *server_info_out; krb5_keyblock server_keyblock; - krb5_keyblock krbtgt_keyblock; + krb5_keyblock krbtgt_keyblock, *krbtgt_keyblock_p; struct samr_Password *krbtgt_bytes, *krbsrv_bytes; krb5_error_code ret; @@ -309,9 +309,13 @@ static bool torture_pac_saved_check(struct torture_context *tctx) /* The krbtgt key in use when the above PAC was generated. * This is an arcfour-hmac-md5 key, extracted with our 'net * samdump' tool. */ - krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key); - if (!krbtgt_bytes) { - torture_fail(tctx, "(saved test) Could not interpret krbtgt key"); + if (*pac_kdc_key == 0) { + krbtgt_bytes = NULL; + } else { + krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key); + if (!krbtgt_bytes) { + torture_fail(tctx, "(saved test) Could not interpret krbtgt key"); + } } krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key); @@ -329,18 +333,23 @@ static bool torture_pac_saved_check(struct torture_context *tctx) smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); - ret = krb5_keyblock_init(smb_krb5_context->krb5_context, - ENCTYPE_ARCFOUR_HMAC, - krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash), - &krbtgt_keyblock); - if (ret) { - krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &server_keyblock); - torture_fail(tctx, - talloc_asprintf(tctx, - "(saved test) Server Keyblock encoding failed: %s", - smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); + if (krbtgt_bytes) { + ret = krb5_keyblock_init(smb_krb5_context->krb5_context, + ENCTYPE_ARCFOUR_HMAC, + krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash), + &krbtgt_keyblock); + if (ret) { + krb5_free_keyblock_contents(smb_krb5_context->krb5_context, + &server_keyblock); + torture_fail(tctx, + talloc_asprintf(tctx, + "(saved test) Server Keyblock encoding failed: %s", + smb_get_krb5_error_message(smb_krb5_context->krb5_context, + ret, mem_ctx))); + } + krbtgt_keyblock_p = &krbtgt_keyblock; + } else { + krbtgt_keyblock_p = NULL; } pac_file = torture_setting_string(tctx, "pac_file", NULL); @@ -363,7 +372,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &client_principal); if (ret) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, @@ -379,12 +388,12 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &pac_data, tmp_blob, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, client_principal, authtime, NULL); if (!NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -400,13 +409,13 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &logon_info, tmp_blob, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, client_principal, authtime, NULL); if (!NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -424,7 +433,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &server_info_out); if (!NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -440,7 +449,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) "S-1-5-21-3048156945-3961193616-3706469200-1005"), server_info_out->account_sid)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -452,17 +461,25 @@ static bool torture_pac_saved_check(struct torture_context *tctx) dom_sid_string(mem_ctx, server_info_out->account_sid))); } + if (krbtgt_bytes == NULL) { + torture_comment(tctx, "skipping PAC encoding tests as non kdc key\n"); + krb5_free_keyblock_contents(smb_krb5_context->krb5_context, + &server_keyblock); + krb5_free_principal(smb_krb5_context->krb5_context, client_principal); + return true; + } + ret = kerberos_encode_pac(mem_ctx, lp_iconv_convenience(tctx->lp_ctx), pac_data, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, &validate_blob); if (ret != 0) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -478,7 +495,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) */ if (tmp_blob.length != validate_blob.length) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -491,7 +508,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -508,14 +525,14 @@ static bool torture_pac_saved_check(struct torture_context *tctx) lp_iconv_convenience(tctx->lp_ctx), server_info_out, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, client_principal, authtime, &validate_blob); if (ret != 0) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -541,7 +558,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) NDR_PRINT_DEBUG(PAC_DATA, &pac_data2); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -563,7 +580,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) NDR_PRINT_DEBUG(PAC_DATA, &pac_data2); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -583,14 +600,14 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &pac_data, tmp_blob, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, client_principal, authtime + 1, NULL); if (NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); krb5_free_principal(smb_krb5_context->krb5_context, client_principal); @@ -608,7 +625,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx) if (ret) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, talloc_asprintf(tctx, @@ -621,13 +638,13 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &pac_data, tmp_blob, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, client_principal, authtime, NULL); if (NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal"); @@ -641,20 +658,20 @@ static bool torture_pac_saved_check(struct torture_context *tctx) &pac_data, tmp_blob, smb_krb5_context->krb5_context, - &krbtgt_keyblock, + krbtgt_keyblock_p, &server_keyblock, client_principal, authtime, NULL); if (NT_STATUS_IS_OK(nt_status)) { krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum"); } krb5_free_keyblock_contents(smb_krb5_context->krb5_context, - &krbtgt_keyblock); + krbtgt_keyblock_p); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &server_keyblock); return true; @@ -666,9 +683,7 @@ struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx) torture_suite_add_simple_test(suite, "self check", torture_pac_self_check); - torture_suite_add_simple_test(suite, "saved check", torture_pac_saved_check); - return suite; } diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c index 1631297793..3730193c86 100644 --- a/source4/torture/ldap/cldap.c +++ b/source4/torture/ldap/cldap.c @@ -228,6 +228,75 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) } /* + test cldap netlogon server type flags +*/ +static bool test_cldap_netlogon_flags(struct torture_context *tctx, + const char *dest) +{ + struct cldap_socket *cldap; + NTSTATUS status; + struct cldap_netlogon search; + struct netlogon_samlogon_response n1; + uint32_t server_type; + + cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + + printf("Printing out netlogon server type flags:\n"); + + ZERO_STRUCT(search); + search.in.dest_address = dest; + search.in.dest_port = lp_cldap_port(tctx->lp_ctx); + search.in.acct_control = -1; + search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + search.in.map_response = true; + + status = cldap_netlogon(cldap, tctx, &search); + CHECK_STATUS(status, NT_STATUS_OK); + + n1 = search.out.netlogon; + if (n1.ntver == NETLOGON_NT_VERSION_5) + server_type = n1.nt5.server_type; + else if (n1.ntver == NETLOGON_NT_VERSION_5EX) + server_type = n1.nt5_ex.server_type; + + printf("The word is: %i\n", server_type); + if (server_type & NBT_SERVER_PDC) + printf("NBT_SERVER_PDC "); + if (server_type & NBT_SERVER_GC) + printf("NBT_SERVER_GC "); + if (server_type & NBT_SERVER_LDAP) + printf("NBT_SERVER_LDAP "); + if (server_type & NBT_SERVER_DS) + printf("NBT_SERVER_DS "); + if (server_type & NBT_SERVER_KDC) + printf("NBT_SERVER_KDC "); + if (server_type & NBT_SERVER_TIMESERV) + printf("NBT_SERVER_TIMESERV "); + if (server_type & NBT_SERVER_CLOSEST) + printf("NBT_SERVER_CLOSEST "); + if (server_type & NBT_SERVER_WRITABLE) + printf("NBT_SERVER_WRITABLE "); + if (server_type & NBT_SERVER_GOOD_TIMESERV) + printf("NBT_SERVER_GOOD_TIMESERV "); + if (server_type & NBT_SERVER_NDNC) + printf("NBT_SERVER_NDNC "); + if (server_type & NBT_SERVER_SEL_SEC_DOM_6) + printf("NBT_SERVER_SEL_SEC_DOM_6 "); + if (server_type & NBT_SERVER_FUL_SEC_DOM_6) + printf("NBT_SERVER_FUL_SEC_DOM_6 "); + if (server_type & NBT_SERVER_DS_DNS_CONTR) + printf("NBT_SERVER_DS_DNS_CONTR "); + if (server_type & NBT_SERVER_DS_DNS_DOMAIN) + printf("NBT_SERVER_DS_DNS_DOMAIN "); + if (server_type & NBT_SERVER_DS_DNS_FOREST) + printf("NBT_SERVER_DS_DNS_FOREST "); + + printf("\n"); + + return true; +} + +/* convert a ldap result message to a ldb message. This allows us to use the convenient ldif dump routines in ldb to print out cldap search results @@ -266,6 +335,81 @@ static void cldap_dump_results(struct cldap_search *search) talloc_free(ldb); } + +/* + test cldap netlogon server type flag "NBT_SERVER_DS_DNS_FOREST" +*/ +static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx, + const char *dest) +{ + struct cldap_socket *cldap; + NTSTATUS status; + struct cldap_netlogon search; + uint32_t server_type; + struct netlogon_samlogon_response n1; + + bool result = true; + + cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + + printf("Testing netlogon server type flag NBT_SERVER_DS_DNS_FOREST: "); + + ZERO_STRUCT(search); + search.in.dest_address = dest; + search.in.dest_port = lp_cldap_port(tctx->lp_ctx); + search.in.acct_control = -1; + search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + search.in.map_response = true; + + status = cldap_netlogon(cldap, tctx, &search); + CHECK_STATUS(status, NT_STATUS_OK); + + n1 = search.out.netlogon; + if (n1.ntver == NETLOGON_NT_VERSION_5) + server_type = n1.nt5.server_type; + else if (n1.ntver == NETLOGON_NT_VERSION_5EX) + server_type = n1.nt5_ex.server_type; + + if (server_type & NBT_SERVER_DS_DNS_FOREST) { + struct cldap_search search2; + const char *attrs[] = { "defaultNamingContext", "rootDomainNamingContext", + NULL }; + struct ldb_context *ldb; + struct ldb_message *msg; + + /* Trying to fetch the attributes "defaultNamingContext" and + "rootDomainNamingContext" */ + ZERO_STRUCT(search2); + search2.in.dest_address = dest; + search2.in.dest_port = lp_cldap_port(tctx->lp_ctx); + search2.in.timeout = 10; + search2.in.retries = 3; + search2.in.filter = "(objectclass=*)"; + search2.in.attributes = attrs; + + status = cldap_search(cldap, tctx, &search2); + CHECK_STATUS(status, NT_STATUS_OK); + + ldb = ldb_init(NULL, NULL); + + msg = ldap_msg_to_ldb(ldb, ldb, search2.out.response); + + /* Try to compare the two attributes */ + if (ldb_msg_element_compare(ldb_msg_find_element(msg, attrs[0]), + ldb_msg_find_element(msg, attrs[1]))) + result = false; + + talloc_free(ldb); + } + + if (result) + printf("passed\n"); + else + printf("failed\n"); + + return result; +} + /* test generic cldap operations */ @@ -343,6 +487,8 @@ bool torture_cldap(struct torture_context *torture) const char *host = torture_setting_string(torture, "host", NULL); ret &= test_cldap_netlogon(torture, host); + ret &= test_cldap_netlogon_flags(torture, host); + ret &= test_cldap_netlogon_flag_ds_dns_forest(torture, host); ret &= test_cldap_generic(torture, host); return ret; diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index 665a08bd5c..eac2b1fe30 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -291,6 +291,10 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) join_ctx = torture_join_domain(tctx, TEST_NAME, ACB_WSTRUST, &machine_credentials); + torture_assert(tctx, join_ctx != NULL, + talloc_asprintf(tctx, "Failed to join domain %s as %s\n", + lp_workgroup(tctx->lp_ctx), TEST_NAME)); + dom_sid = torture_join_sid(join_ctx); /* setup (another) temporary mailslot listener for replies */ diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c index ee7a1510d5..6b600bd7cd 100644 --- a/source4/torture/nbt/winsreplication.c +++ b/source4/torture/nbt/winsreplication.c @@ -6701,7 +6701,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, /* * unique vs. unique section */ -#if METZE_NEEDS_TO_LOOK_AT_THIS_ONE /* * unique,active vs. unique,active with same ip(s), unchecked */ @@ -6728,7 +6727,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, .apply_expected = true }, }, -#endif /* * unique,active vs. unique,active with different ip(s), positive response */ @@ -8967,7 +8965,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, .sgroup_merge = true }, }, -#if 0 /* * sgroup,active vs. sgroup,active with same ip(s) */ @@ -9157,7 +9154,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx, .apply_expected = false }, }, -#endif }; if (!ctx->nbtsock_srv) { @@ -9543,7 +9539,9 @@ static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_ talloc_free(rep_packet); /* make sure we push the reply to the wire */ - event_loop_once(nbtsock->event_ctx); + while (nbtsock->send_queue) { + event_loop_once(nbtsock->event_ctx); + } msleep(1000); rec->defend.timeout = 0; @@ -9598,7 +9596,9 @@ static void test_conflict_owned_active_vs_replica_handler_release( talloc_free(rep_packet); /* make sure we push the reply to the wire */ - event_loop_once(nbtsock->event_ctx); + while (nbtsock->send_queue) { + event_loop_once(nbtsock->event_ctx); + } msleep(1000); rec->defend.timeout = 0; diff --git a/source4/torture/raw/offline.c b/source4/torture/raw/offline.c index 9c66c3be9c..f2f0bf5d27 100644 --- a/source4/torture/raw/offline.c +++ b/source4/torture/raw/offline.c @@ -108,8 +108,11 @@ static void loadfile_callback(struct composite_context *ctx) } for (i=0;i<FILE_SIZE;i++) { - if (state->loadfile->out.data[i] != state->fnumber % 256) { - printf("Bad data in file %u\n", state->fnumber); + if (state->loadfile->out.data[i] != 1+(state->fnumber % 255)) { + printf("Bad data in file %u (got %u expected %u)\n", + state->fnumber, + state->loadfile->out.data[i], + 1+(state->fnumber % 255)); test_failed++; return; } @@ -253,7 +256,7 @@ static void test_offline(struct offline_state *state) state->savefile->in.fname = state->fname; state->savefile->in.data = talloc_size(state->savefile, FILE_SIZE); state->savefile->in.size = FILE_SIZE; - memset(state->savefile->in.data, state->fnumber, FILE_SIZE); + memset(state->savefile->in.data, 1+(state->fnumber%255), FILE_SIZE); ctx = smb_composite_savefile_send(state->tree, state->savefile); if (ctx == NULL) { @@ -344,12 +347,16 @@ static void report_rate(struct event_context *ev, struct timed_event *te, total_online += state[i].online_count; total_offline += state[i].offline_count; } - printf("ops/s=%4u offline=%5u online=%4u set_lat=%.1f get_lat=%.1f save_lat=%.1f load_lat=%.1f\r", + printf("ops/s=%4u offline=%5u online=%4u set_lat=%.1f/%.1f get_lat=%.1f/%.1f save_lat=%.1f/%.1f load_lat=%.1f/%.1f\n", total, total_offline, total_online, latencies[OP_SETOFFLINE], + worst_latencies[OP_SETOFFLINE], latencies[OP_GETOFFLINE], + worst_latencies[OP_GETOFFLINE], latencies[OP_SAVEFILE], - latencies[OP_LOADFILE]); + worst_latencies[OP_SAVEFILE], + latencies[OP_LOADFILE], + worst_latencies[OP_LOADFILE]); fflush(stdout); event_add_timed(ev, state, timeval_current_ofs(1, 0), report_rate, state); @@ -436,7 +443,7 @@ bool torture_test_offline(struct torture_context *torture) char buf[FILE_SIZE]; NTSTATUS status; - memset(buf, i % 256, sizeof(buf)); + memset(buf, 1+(i % 255), sizeof(buf)); fnum = smbcli_open(state[0].tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c index b6979fa0d9..f3494ea3d0 100644 --- a/source4/torture/raw/open.c +++ b/source4/torture/raw/open.c @@ -844,6 +844,8 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context int fnum = -1; bool ret = true; int i; + uint32_t ok_mask, not_supported_mask, invalid_parameter_mask; + uint32_t not_a_directory_mask, unexpected_mask; struct { uint32_t open_disp; bool with_file; @@ -982,6 +984,10 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context } io.ntcreatex.in.create_options = create_option; status = smb_raw_open(cli->tree, tctx, &io); + if (!NT_STATUS_IS_OK(status)) { + printf("ntcreatex create option 0x%08x gave %s - should give NT_STATUS_OK\n", + create_option, nt_errstr(status)); + } CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; @@ -999,6 +1005,44 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context smbcli_close(cli->tree, fnum); } + io.ntcreatex.in.file_attr = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + + /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */ + ok_mask = 0; + not_supported_mask = 0; + invalid_parameter_mask = 0; + not_a_directory_mask = 0; + unexpected_mask = 0; + for (i=0; i < 32; i++) { + uint32_t create_option = 1<<i; + if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + continue; + } + io.ntcreatex.in.create_options = create_option; + status = smb_raw_open(cli->tree, tctx, &io); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + not_supported_mask |= create_option; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + ok_mask |= create_option; + smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { + invalid_parameter_mask |= create_option; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) { + not_a_directory_mask |= 1<<i; + } else { + unexpected_mask |= 1<<i; + printf("create option 0x%08x returned %s\n", create_option, nt_errstr(status)); + } + } + + CHECK_VAL(ok_mask, 0x00efcfce); + CHECK_VAL(not_a_directory_mask, 0x00000001); + CHECK_VAL(not_supported_mask, 0x00002000); + CHECK_VAL(invalid_parameter_mask, 0xff100030); + CHECK_VAL(unexpected_mask, 0x00000000); + smbcli_unlink(cli->tree, fname); diff --git a/source4/torture/rpc/atsvc.c b/source4/torture/rpc/atsvc.c index 25ace8ac49..23d76ae502 100644 --- a/source4/torture/rpc/atsvc.c +++ b/source4/torture/rpc/atsvc.c @@ -65,7 +65,8 @@ static bool test_JobEnum(struct torture_context *tctx, struct dcerpc_pipe *p) NTSTATUS status; struct atsvc_JobEnum r; struct atsvc_enum_ctr ctr; - uint32_t resume_handle = 0, i; + uint32_t resume_handle = 0, i, total_entries = 0; + bool ret = true; r.in.servername = dcerpc_server_name(p); @@ -74,6 +75,7 @@ static bool test_JobEnum(struct torture_context *tctx, struct dcerpc_pipe *p) r.in.ctr = r.out.ctr = &ctr; r.in.preferred_max_len = 0xffffffff; r.in.resume_handle = r.out.resume_handle = &resume_handle; + r.out.total_entries = &total_entries; status = dcerpc_atsvc_JobEnum(p, tctx, &r); diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c index 2739081246..e9346f9605 100644 --- a/source4/torture/rpc/dssync.c +++ b/source4/torture/rpc/dssync.c @@ -747,9 +747,10 @@ static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx) if (ret == true && *r.out.level == 1) { out_level = 1; ctr1 = &r.out.ctr.ctr1; - } else if (ret == true && *r.out.level == 2) { + } else if (ret == true && *r.out.level == 2 && + r.out.ctr.ctr2.mszip1.ts) { out_level = 1; - ctr1 = r.out.ctr.ctr2.mszip1.ctr1; + ctr1 = &r.out.ctr.ctr2.mszip1.ts->ctr1; } if (out_level == 1) { @@ -770,14 +771,16 @@ static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx) ctr6 = &r.out.ctr.ctr6; } else if (ret == true && *r.out.level == 7 && r.out.ctr.ctr7.level == 6 - && r.out.ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP) { + && r.out.ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP + && r.out.ctr.ctr7.ctr.mszip6.ts) { out_level = 6; - ctr6 = r.out.ctr.ctr7.ctr.mszip6.ctr6; + ctr6 = &r.out.ctr.ctr7.ctr.mszip6.ts->ctr6; } else if (ret == true && *r.out.level == 7 && r.out.ctr.ctr7.level == 6 - && r.out.ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS) { + && r.out.ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS + && r.out.ctr.ctr7.ctr.xpress6.ts) { out_level = 6; - ctr6 = r.out.ctr.ctr7.ctr.xpress6.ctr6; + ctr6 = &r.out.ctr.ctr7.ctr.xpress6.ts->ctr6; } if (out_level == 6) { diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 4fb459ea25..ec74426ac6 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -28,7 +28,6 @@ #include "libcli/auth/libcli_auth.h" #include "torture/rpc/rpc.h" #include "param/param.h" - #define TEST_MACHINENAME "lsatestmach" static void init_lsa_String(struct lsa_String *name, const char *s) @@ -614,7 +613,8 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, if (!test_LookupNames(p, mem_ctx, handle, &names)) { return false; } - } else { + } else if (p->conn->security_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL && + p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { struct lsa_LookupSids3 r; struct lsa_TransNameArray2 names; @@ -779,6 +779,7 @@ static bool test_LookupPrivName(struct dcerpc_pipe *p, static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + struct policy_handle *handle, struct policy_handle *acct_handle, struct lsa_LUID *luid) { @@ -801,7 +802,25 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status)); + + struct lsa_LookupPrivName r_name; + + r_name.in.handle = handle; + r_name.in.luid = luid; + + status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r_name); + if (!NT_STATUS_IS_OK(status)) { + printf("\nLookupPrivName failed - %s\n", nt_errstr(status)); + return false; + } + /* Windows 2008 does not allow this to be removed */ + if (strcmp("SeAuditPrivilege", r_name.out.name->string) == 0) { + return ret; + } + + printf("RemovePrivilegesFromAccount failed to remove %s - %s\n", + r_name.out.name->string, + nt_errstr(status)); return false; } @@ -864,7 +883,7 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, &r.out.privs->set[i].luid); } - ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, + ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, handle, acct_handle, &r.out.privs->set[0].luid); ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, &r.out.privs->set[0].luid); @@ -884,6 +903,26 @@ static bool test_Delete(struct dcerpc_pipe *p, r.in.handle = handle; status = dcerpc_lsa_Delete(p, mem_ctx, &r); + if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + printf("Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status)); + return false; + } + + return true; +} + +static bool test_DeleteObject(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle) +{ + NTSTATUS status; + struct lsa_DeleteObject r; + + printf("testing DeleteObject\n"); + + r.in.handle = handle; + r.out.handle = handle; + status = dcerpc_lsa_DeleteObject(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("Delete failed - %s\n", nt_errstr(status)); return false; @@ -912,7 +951,19 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, r.out.acct_handle = &acct_handle; status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + struct lsa_OpenAccount r_o; + r_o.in.handle = handle; + r_o.in.sid = newsid; + r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r_o.out.acct_handle = &acct_handle; + + status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r_o); + if (!NT_STATUS_IS_OK(status)) { + printf("OpenAccount failed - %s\n", nt_errstr(status)); + return false; + } + } else if (!NT_STATUS_IS_OK(status)) { printf("CreateAccount failed - %s\n", nt_errstr(status)); return false; } @@ -921,6 +972,10 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, return false; } + if (!test_DeleteObject(p, mem_ctx, &acct_handle)) { + return false; + } + return true; } @@ -948,6 +1003,10 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p, return false; } + if (!test_DeleteObject(p, mem_ctx, &trustdom_handle)) { + return false; + } + return true; } @@ -986,7 +1045,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, struct lsa_SetSecret r7; struct lsa_QuerySecret r8; struct policy_handle sec_handle, sec_handle2, sec_handle3; - struct lsa_Delete d; + struct lsa_DeleteObject d_o; struct lsa_DATA_BUF buf1; struct lsa_DATA_BUF_PTR bufp1; struct lsa_DATA_BUF_PTR bufp2; @@ -1121,7 +1180,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, &blob1, &session_key); if (strcmp(secret1, secret2) != 0) { - printf("Returned secret '%s' doesn't match '%s'\n", + printf("Returned secret (r4) '%s' doesn't match '%s'\n", secret2, secret1); ret = false; } @@ -1136,7 +1195,9 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, r5.in.new_val->data = enc_key.data; r5.in.new_val->length = enc_key.length; r5.in.new_val->size = enc_key.length; - + + + msleep(200); printf("Testing SetSecret (existing value should move to old)\n"); status = dcerpc_lsa_SetSecret(p, mem_ctx, &r5); @@ -1200,8 +1261,10 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, } if (*r6.out.new_mtime == *r6.out.old_mtime) { - printf("Returned secret %s had same mtime for both secrets: %s\n", + printf("Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n", + i, secname[i], + nt_time_string(mem_ctx, *r6.out.old_mtime), nt_time_string(mem_ctx, *r6.out.new_mtime)); ret = false; } @@ -1245,35 +1308,16 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, if (!r8.out.new_val || !r8.out.old_val) { printf("in/out pointers not returned, despite being set on in for QuerySecret\n"); ret = false; - } else if (r8.out.new_val->buf == NULL) { - if (i != LOCAL) { - printf("NEW secret buffer not returned after GLOBAL OLD set\n"); - ret = false; - } + } else if (r8.out.new_val->buf != NULL) { + printf("NEW secret buffer must not be returned after OLD set\n"); + ret = false; } else if (r8.out.old_val->buf == NULL) { - printf("OLD secret buffer not returned after OLD set\n"); + printf("OLD secret buffer was not returned after OLD set\n"); ret = false; } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) { printf("Both times not returned after OLD set\n"); ret = false; } else { - if (i == LOCAL) { - printf("NEW secret buffer should not be returned after LOCAL OLD set\n"); - ret = false; - } - blob1.data = r8.out.new_val->buf->data; - blob1.length = r8.out.new_val->buf->length; - - blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length); - - secret6 = sess_decrypt_string(mem_ctx, - &blob1, &session_key); - - if (strcmp(secret3, secret4) != 0) { - printf("Returned NEW secret '%s' doesn't match '%s'\n", secret4, secret3); - ret = false; - } - blob1.data = r8.out.old_val->buf->data; blob1.length = r8.out.old_val->buf->size; @@ -1287,15 +1331,8 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, ret = false; } - if (*r8.out.new_mtime == *r8.out.old_mtime) { - if (i != GLOBAL) { - printf("Returned secret %s had same mtime for both secrets: %s\n", - secname[i], - nt_time_string(mem_ctx, *r8.out.new_mtime)); - ret = false; - } - } else { - printf("Returned secret %s should have had same mtime for both secrets: %s != %s\n", + if (*r8.out.new_mtime != *r8.out.old_mtime) { + printf("Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n", secname[i], nt_time_string(mem_ctx, *r8.out.old_mtime), nt_time_string(mem_ctx, *r8.out.new_mtime)); @@ -1308,8 +1345,13 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, ret = false; } - d.in.handle = &sec_handle2; - status = dcerpc_lsa_Delete(p, mem_ctx, &d); + if (!test_DeleteObject(p, mem_ctx, &sec_handle)) { + return false; + } + + d_o.in.handle = &sec_handle2; + d_o.out.handle = &sec_handle2; + status = dcerpc_lsa_DeleteObject(p, mem_ctx, &d_o); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status)); ret = false; @@ -1454,9 +1496,9 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p, return false; } - if (!test_LookupSids3(p, mem_ctx, &sids1)) { - return false; - } + /* Can't test lookupSids3 here, as clearly we must not + * be on schannel, or we would not be able to do the + * rest */ printf("testing all accounts\n"); for (i=0;i<sids1.num_sids;i++) { @@ -1667,8 +1709,8 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, struct policy_handle handle2; struct lsa_Close c; struct lsa_CloseTrustedDomainEx c_trust; - int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1}; + int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; + int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1}; if (domains->domains[i].sid) { trust.in.handle = handle; @@ -1912,8 +1954,6 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, r_ex.in.max_size, LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER, r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER); - ret = false; - exit(1); } } else if (!NT_STATUS_IS_OK(enum_status)) { printf("EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status)); @@ -2015,10 +2055,6 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, NTSTATUS status; int i; bool ret = true; - if (torture_setting_bool(tctx, "samba4", false)) { - printf("skipping QueryDomainInformationPolicy test against Samba4\n"); - return true; - } printf("\nTesting QueryDomainInformationPolicy\n"); @@ -2030,7 +2066,10 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r); - if (!NT_STATUS_IS_OK(status)) { + /* If the server does not support EFS, then this is the correct return */ + if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + continue; + } else if (!NT_STATUS_IS_OK(status)) { printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status)); ret = false; continue; @@ -2311,11 +2350,9 @@ bool torture_rpc_lsa(struct torture_context *tctx) ret = false; } -#if 0 if (!test_Delete(p, tctx, handle)) { ret = false; } -#endif if (!test_many_LookupSids(p, tctx, handle)) { ret = false; diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c index c23ff8b8ce..4d1b4a7ed0 100644 --- a/source4/torture/smb2/create.c +++ b/source4/torture/smb2/create.c @@ -52,7 +52,9 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre struct smb2_create io; NTSTATUS status; TALLOC_CTX *tmp_ctx = talloc_new(tree); - uint32_t access_mask, file_attributes, file_attributes_set, denied_mask; + uint32_t access_mask, file_attributes_set; + uint32_t ok_mask, not_supported_mask, invalid_parameter_mask; + uint32_t not_a_directory_mask, unexpected_mask; union smb_fileinfo q; ZERO_STRUCT(io); @@ -76,14 +78,6 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre status = smb2_create(tree, tmp_ctx, &io); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); - io.in.create_options = 0x00100000; - status = smb2_create(tree, tmp_ctx, &io); - CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED); - - io.in.create_options = 0xF0100000; - status = smb2_create(tree, tmp_ctx, &io); - CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED); - io.in.create_options = 0; io.in.file_attributes = FILE_ATTRIBUTE_DEVICE; @@ -108,6 +102,46 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre status = smb2_create(tree, tmp_ctx, &io); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); + io.in.file_attributes = 0; + io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + ok_mask = 0; + not_supported_mask = 0; + invalid_parameter_mask = 0; + not_a_directory_mask = 0; + unexpected_mask = 0; + { + int i; + for (i=0;i<32;i++) { + io.in.create_options = 1<<i; + if (io.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + continue; + } + status = smb2_create(tree, tmp_ctx, &io); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + not_supported_mask |= 1<<i; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { + invalid_parameter_mask |= 1<<i; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) { + not_a_directory_mask |= 1<<i; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + ok_mask |= 1<<i; + status = smb2_util_close(tree, io.out.file.handle); + CHECK_STATUS(status, NT_STATUS_OK); + } else { + unexpected_mask |= 1<<i; + printf("create option 0x%08x returned %s\n", 1<<i, nt_errstr(status)); + } + } + } + io.in.create_options = 0; + + CHECK_EQUAL(ok_mask, 0x00efcf7e); + CHECK_EQUAL(not_a_directory_mask, 0x00000001); + CHECK_EQUAL(not_supported_mask, 0x00102080); + CHECK_EQUAL(invalid_parameter_mask, 0xff000000); + CHECK_EQUAL(unexpected_mask, 0x00000000); + io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.in.file_attributes = 0; access_mask = 0; @@ -132,31 +166,58 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; io.in.file_attributes = 0; - file_attributes = 0; + ok_mask = 0; + invalid_parameter_mask = 0; + unexpected_mask = 0; file_attributes_set = 0; - denied_mask = 0; { int i; for (i=0;i<32;i++) { io.in.file_attributes = 1<<i; + if (io.in.file_attributes & FILE_ATTRIBUTE_ENCRYPTED) { + continue; + } smb2_deltree(tree, FNAME); status = smb2_create(tree, tmp_ctx, &io); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - file_attributes |= io.in.file_attributes; - } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { - denied_mask |= io.in.file_attributes; - } else { - CHECK_STATUS(status, NT_STATUS_OK); + invalid_parameter_mask |= 1<<i; + } else if (NT_STATUS_IS_OK(status)) { + uint32_t expected; + ok_mask |= 1<<i; + + expected = (io.in.file_attributes | FILE_ATTRIBUTE_ARCHIVE) & 0x00005127; + CHECK_EQUAL(io.out.file_attr, expected); + file_attributes_set |= io.out.file_attr; + status = smb2_util_close(tree, io.out.file.handle); CHECK_STATUS(status, NT_STATUS_OK); - file_attributes_set |= io.out.file_attr; + } else { + unexpected_mask |= 1<<i; + printf("file attribute 0x%08x returned %s\n", 1<<i, nt_errstr(status)); } } } - CHECK_EQUAL(file_attributes, 0xffff8048); - CHECK_EQUAL(denied_mask, 0x4000); - CHECK_EQUAL(file_attributes_set, 0x00001127); + CHECK_EQUAL(ok_mask, 0x00003fb7); + CHECK_EQUAL(invalid_parameter_mask, 0xffff8048); + CHECK_EQUAL(unexpected_mask, 0x00000000); + CHECK_EQUAL(file_attributes_set, 0x00001127); + + smb2_deltree(tree, FNAME); + + /* + * Standalone servers doesn't support encryption + */ + io.in.file_attributes = FILE_ATTRIBUTE_ENCRYPTED; + status = smb2_create(tree, tmp_ctx, &io); + if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("FILE_ATTRIBUTE_ENCRYPTED returned %s\n", nt_errstr(status)); + } else { + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_EQUAL(io.out.file_attr, (FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_ARCHIVE)); + status = smb2_util_close(tree, io.out.file.handle); + CHECK_STATUS(status, NT_STATUS_OK); + } smb2_deltree(tree, FNAME); |