diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/torture/config.mk | 1 | ||||
-rw-r--r-- | source4/torture/raw/oplock.c | 87 | ||||
-rw-r--r-- | source4/torture/rpc/lsa_lookup.c | 264 | ||||
-rw-r--r-- | source4/torture/torture.c | 1 |
4 files changed, 352 insertions, 1 deletions
diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 4f4349bc5e..97e8bc4a9e 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -75,6 +75,7 @@ REQUIRED_SUBSYSTEMS = \ OBJ_FILES = \ rpc/join.o \ rpc/lsa.o \ + rpc/lsa_lookup.o \ rpc/session_key.o \ rpc/echo.o \ rpc/dcom.o \ diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index 64da410bd2..0dcbda3cb5 100644 --- a/source4/torture/raw/oplock.c +++ b/source4/torture/raw/oplock.c @@ -471,13 +471,70 @@ done: return ret; } +static BOOL test_bug3349(struct smbcli_state *cli, + struct smbcli_state *cli2, + TALLOC_CTX *mem_ctx) +{ + const char *fname = "\\test_oplock.dat"; + NTSTATUS status; + BOOL ret = True; + union smb_open io; + struct smb_unlink unl; + uint16_t fnum=0, fnum2=0; + + /* cleanup */ + smbcli_unlink(cli->tree, fname); + + smbcli_oplock_handler(cli->transport, oplock_handler_ack, cli->tree); + + /* + base ntcreatex parms + */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname; + + printf("if we close on break then the unlink can succeed\n"); + ZERO_STRUCT(break_info); + smbcli_oplock_handler(cli->transport, oplock_handler_close, cli->tree); + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | + NTCREATEX_FLAGS_REQUEST_OPLOCK | + NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.fnum; + CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN); + + unl.in.pattern = fname; + unl.in.attrib = 0; + ZERO_STRUCT(break_info); + status = smb_raw_unlink(cli2->tree, &unl); + CHECK_STATUS(status, NT_STATUS_OK); + + CHECK_VAL(break_info.fnum, fnum); + CHECK_VAL(break_info.level, 1); + CHECK_VAL(break_info.count, 1); +done: + smbcli_close(cli->tree, fnum); + smbcli_close(cli->tree, fnum2); + smbcli_unlink(cli->tree, fname); + return ret; +} /* basic testing of oplocks */ BOOL torture_raw_oplock(void) { - struct smbcli_state *cli1; + struct smbcli_state *cli1, *cli2; BOOL ret = True; TALLOC_CTX *mem_ctx; @@ -487,10 +544,38 @@ BOOL torture_raw_oplock(void) mem_ctx = talloc_init("torture_raw_oplock"); + { + struct cli_credentials *creds; + NTSTATUS status; + + creds = cli_credentials_init(mem_ctx); + cli_credentials_set_conf(creds); + cli_credentials_parse_string(creds, "user1000%asdf", + CRED_SPECIFIED); + status = smbcli_full_connection( + mem_ctx, &cli2, lp_parm_string(-1, "torture", "host"), + lp_parm_string(-1, "torture", "share"), "????", + creds, cli1->transport->socket->event.ctx); + + if (!NT_STATUS_IS_OK(status)) { + printf("opening 2nd connection failed: %s\n", + nt_errstr(status)); + return False; + } + } + + if (!test_bug3349(cli1, cli2, mem_ctx)) { + ret = False; + } + + goto done; + if (!test_oplock(cli1, mem_ctx)) { ret = False; } + done: + torture_close_connection(cli1); talloc_free(mem_ctx); return ret; diff --git a/source4/torture/rpc/lsa_lookup.c b/source4/torture/rpc/lsa_lookup.c new file mode 100644 index 0000000000..8fab89ebf1 --- /dev/null +++ b/source4/torture/rpc/lsa_lookup.c @@ -0,0 +1,264 @@ +/* + Unix SMB/CIFS implementation. + test suite for lsa rpc lookup operations + + Copyright (C) Volker Lendecke 2006 + + 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. +*/ + +#include "includes.h" +#include "torture/torture.h" +#include "librpc/gen_ndr/ndr_lsa.h" +#include "lib/events/events.h" + +static BOOL open_policy(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p, + struct policy_handle **handle) +{ + struct lsa_ObjectAttribute attr; + struct lsa_QosInfo qos; + struct lsa_OpenPolicy2 r; + NTSTATUS status; + + *handle = talloc(mem_ctx, struct policy_handle); + if (!*handle) { + return False; + } + + qos.len = 0; + qos.impersonation_level = 2; + qos.context_mode = 1; + qos.effective_only = 0; + + attr.len = 0; + attr.root_dir = NULL; + attr.object_name = NULL; + attr.attributes = 0; + attr.sec_desc = NULL; + attr.sec_qos = &qos; + + r.in.system_name = "\\"; + r.in.attr = &attr; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.handle = *handle; + + status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r); + + return NT_STATUS_IS_OK(status); +} + +static BOOL get_domainsid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p, + struct policy_handle *handle, + struct dom_sid **sid) +{ + struct lsa_QueryInfoPolicy r; + NTSTATUS status; + + r.in.level = LSA_POLICY_INFO_DOMAIN; + r.in.handle = handle; + + status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) return False; + + *sid = r.out.info->domain.sid; + return True; +} + +static NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, uint16_t level, + struct dcerpc_pipe *p, + struct policy_handle *handle, + struct dom_sid **sids, uint32_t num_sids, + struct lsa_TransNameArray *names) +{ + struct lsa_LookupSids r; + struct lsa_SidArray sidarray; + uint32_t count = 0; + uint32_t i; + + names->count = 0; + names->names = NULL; + + sidarray.num_sids = num_sids; + sidarray.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids); + + for (i=0; i<num_sids; i++) { + sidarray.sids[i].sid = sids[i]; + } + + r.in.handle = handle; + r.in.sids = &sidarray; + r.in.names = names; + r.in.level = level; + r.in.count = &count; + r.out.names = names; + r.out.count = &count; + + return dcerpc_lsa_LookupSids(p, mem_ctx, &r); +} + +const char *sid_type_lookup(enum lsa_SidType r) +{ + switch (r) { + case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break; + case SID_NAME_USER: return "SID_NAME_USER"; break; + case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break; + case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break; + case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break; + case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break; + case SID_NAME_DELETED: return "SID_NAME_DELETED"; break; + case SID_NAME_INVALID: return "SID_NAME_INVALID"; break; + case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break; + } + return "Invalid sid type\n"; +} + +static BOOL test_lookupsids(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p, + struct policy_handle *handle, + struct dom_sid **sids, uint32_t num_sids, + int level, NTSTATUS expected_result, + enum lsa_SidType *types) +{ + struct lsa_TransNameArray names; + NTSTATUS status; + uint32_t i; + BOOL ret = True; + + status = lookup_sids(mem_ctx, level, p, handle, sids, num_sids, + &names); + if (!NT_STATUS_EQUAL(status, expected_result)) { + printf("For level %d expected %s, got %s\n", + level, nt_errstr(expected_result), + nt_errstr(status)); + return False; + } + + if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) && + !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { + return True; + } + + for (i=0; i<num_sids; i++) { + if (names.names[i].sid_type != types[i]) { + printf("In level %d, for sid %s expected %s, " + "got %s\n", level, + dom_sid_string(mem_ctx, sids[i]), + sid_type_lookup(types[i]), + sid_type_lookup(names.names[i].sid_type)); + ret = False; + } + } + return ret; +} + +#define NUM_SIDS 6 + +BOOL torture_rpc_lsa_lookup(void) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + TALLOC_CTX *mem_ctx; + BOOL ret = True; + struct policy_handle *handle; + struct dom_sid *dom_sid; + struct dom_sid *sids[NUM_SIDS]; + + mem_ctx = talloc_init("torture_rpc_lsa"); + + status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_lsarpc); + if (!NT_STATUS_IS_OK(status)) { + ret = False; + goto done; + } + + ret &= open_policy(mem_ctx, p, &handle); + if (!ret) goto done; + + ret &= get_domainsid(mem_ctx, p, handle, &dom_sid); + if (!ret) goto done; + + printf("domain sid: %s\n", dom_sid_string(mem_ctx, dom_sid)); + + sids[0] = dom_sid_parse_talloc(mem_ctx, "S-1-1-0"); + sids[1] = dom_sid_parse_talloc(mem_ctx, "S-1-5-4"); + sids[2] = dom_sid_parse_talloc(mem_ctx, "S-1-5-32"); + sids[3] = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-545"); + sids[4] = dom_sid_dup(mem_ctx, dom_sid); + sids[5] = dom_sid_add_rid(mem_ctx, dom_sid, 512); + + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 0, + NT_STATUS_INVALID_PARAMETER, NULL); + + { + enum lsa_SidType types[NUM_SIDS] = + { SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN, + SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP }; + + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 1, + NT_STATUS_OK, types); + } + + { + enum lsa_SidType types[NUM_SIDS] = + { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_DOMAIN, SID_NAME_DOM_GRP }; + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 2, + STATUS_SOME_UNMAPPED, types); + } + + { + enum lsa_SidType types[NUM_SIDS] = + { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_DOMAIN, SID_NAME_DOM_GRP }; + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 3, + STATUS_SOME_UNMAPPED, types); + } + + { + enum lsa_SidType types[NUM_SIDS] = + { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_DOMAIN, SID_NAME_DOM_GRP }; + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 4, + STATUS_SOME_UNMAPPED, types); + } + + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 5, + NT_STATUS_NONE_MAPPED, NULL); + + { + enum lsa_SidType types[NUM_SIDS] = + { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_UNKNOWN, SID_NAME_UNKNOWN, + SID_NAME_DOMAIN, SID_NAME_DOM_GRP }; + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 6, + STATUS_SOME_UNMAPPED, types); + } + + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 7, + NT_STATUS_INVALID_PARAMETER, NULL); + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 8, + NT_STATUS_INVALID_PARAMETER, NULL); + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 9, + NT_STATUS_INVALID_PARAMETER, NULL); + ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 10, + NT_STATUS_INVALID_PARAMETER, NULL); + + done: + talloc_free(mem_ctx); + + return ret; +} diff --git a/source4/torture/torture.c b/source4/torture/torture.c index fd8fc6fd6b..50034f430b 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -2271,6 +2271,7 @@ static struct { /* rpc testers */ {"RPC-LSA", torture_rpc_lsa, 0}, + {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0}, {"RPC-SECRETS", torture_rpc_lsa_secrets, 0}, {"RPC-ECHO", torture_rpc_echo, 0}, {"RPC-DFS", torture_rpc_dfs, 0}, |