| 1 | /*
|
|---|
| 2 | Unix SMB/CIFS implementation.
|
|---|
| 3 | test suite for epmapper rpc operations
|
|---|
| 4 |
|
|---|
| 5 | Copyright (C) Andrew Tridgell 2003
|
|---|
| 6 |
|
|---|
| 7 | This program is free software; you can redistribute it and/or modify
|
|---|
| 8 | it under the terms of the GNU General Public License as published by
|
|---|
| 9 | the Free Software Foundation; either version 3 of the License, or
|
|---|
| 10 | (at your option) any later version.
|
|---|
| 11 |
|
|---|
| 12 | This program is distributed in the hope that it will be useful,
|
|---|
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 15 | GNU General Public License for more details.
|
|---|
| 16 |
|
|---|
| 17 | You should have received a copy of the GNU General Public License
|
|---|
| 18 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|---|
| 19 | */
|
|---|
| 20 |
|
|---|
| 21 | #include "includes.h"
|
|---|
| 22 | #include "torture/torture.h"
|
|---|
| 23 | #include "librpc/gen_ndr/ndr_epmapper_c.h"
|
|---|
| 24 | #include "librpc/ndr/ndr_table.h"
|
|---|
| 25 | #include "librpc/rpc/dcerpc_proto.h"
|
|---|
| 26 | #include "torture/rpc/rpc.h"
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 | /*
|
|---|
| 30 | display any protocol tower
|
|---|
| 31 | */
|
|---|
| 32 | static void display_tower(TALLOC_CTX *mem_ctx, struct epm_tower *twr)
|
|---|
| 33 | {
|
|---|
| 34 | int i;
|
|---|
| 35 |
|
|---|
| 36 | for (i=0;i<twr->num_floors;i++) {
|
|---|
| 37 | printf(" %s", epm_floor_string(mem_ctx, &twr->floors[i]));
|
|---|
| 38 | }
|
|---|
| 39 | printf("\n");
|
|---|
| 40 | }
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 | static bool test_Map(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
|---|
| 44 | struct epm_twr_t *twr)
|
|---|
| 45 | {
|
|---|
| 46 | NTSTATUS status;
|
|---|
| 47 | struct epm_Map r;
|
|---|
| 48 | struct GUID uuid;
|
|---|
| 49 | struct policy_handle handle;
|
|---|
| 50 | int i;
|
|---|
| 51 | struct ndr_syntax_id syntax;
|
|---|
| 52 | uint32_t num_towers;
|
|---|
| 53 |
|
|---|
| 54 | ZERO_STRUCT(uuid);
|
|---|
| 55 | ZERO_STRUCT(handle);
|
|---|
| 56 |
|
|---|
| 57 | r.in.object = &uuid;
|
|---|
| 58 | r.in.map_tower = twr;
|
|---|
| 59 | r.in.entry_handle = &handle;
|
|---|
| 60 | r.out.entry_handle = &handle;
|
|---|
| 61 | r.in.max_towers = 100;
|
|---|
| 62 | r.out.num_towers = &num_towers;
|
|---|
| 63 |
|
|---|
| 64 | dcerpc_floor_get_lhs_data(&twr->tower.floors[0], &syntax);
|
|---|
| 65 |
|
|---|
| 66 | printf("epm_Map results for '%s':\n",
|
|---|
| 67 | ndr_interface_name(&syntax.uuid, syntax.if_version));
|
|---|
| 68 |
|
|---|
| 69 | twr->tower.floors[2].lhs.protocol = EPM_PROTOCOL_NCACN;
|
|---|
| 70 | twr->tower.floors[2].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 71 | twr->tower.floors[2].rhs.ncacn.minor_version = 0;
|
|---|
| 72 |
|
|---|
| 73 | twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_TCP;
|
|---|
| 74 | twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 75 | twr->tower.floors[3].rhs.tcp.port = 0;
|
|---|
| 76 |
|
|---|
| 77 | twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_IP;
|
|---|
| 78 | twr->tower.floors[4].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 79 | twr->tower.floors[4].rhs.ip.ipaddr = "0.0.0.0";
|
|---|
| 80 |
|
|---|
| 81 | status = dcerpc_epm_Map(p, mem_ctx, &r);
|
|---|
| 82 | if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
|
|---|
| 83 | for (i=0;i<*r.out.num_towers;i++) {
|
|---|
| 84 | if (r.out.towers[i].twr) {
|
|---|
| 85 | display_tower(mem_ctx, &r.out.towers[i].twr->tower);
|
|---|
| 86 | }
|
|---|
| 87 | }
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_HTTP;
|
|---|
| 91 | twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 92 | twr->tower.floors[3].rhs.http.port = 0;
|
|---|
| 93 |
|
|---|
| 94 | status = dcerpc_epm_Map(p, mem_ctx, &r);
|
|---|
| 95 | if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
|
|---|
| 96 | for (i=0;i<*r.out.num_towers;i++) {
|
|---|
| 97 | if (r.out.towers[i].twr) {
|
|---|
| 98 | display_tower(mem_ctx, &r.out.towers[i].twr->tower);
|
|---|
| 99 | }
|
|---|
| 100 | }
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_UDP;
|
|---|
| 104 | twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 105 | twr->tower.floors[3].rhs.http.port = 0;
|
|---|
| 106 |
|
|---|
| 107 | status = dcerpc_epm_Map(p, mem_ctx, &r);
|
|---|
| 108 | if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
|
|---|
| 109 | for (i=0;i<*r.out.num_towers;i++) {
|
|---|
| 110 | if (r.out.towers[i].twr) {
|
|---|
| 111 | display_tower(mem_ctx, &r.out.towers[i].twr->tower);
|
|---|
| 112 | }
|
|---|
| 113 | }
|
|---|
| 114 | }
|
|---|
| 115 |
|
|---|
| 116 | twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_SMB;
|
|---|
| 117 | twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 118 | twr->tower.floors[3].rhs.smb.unc = "";
|
|---|
| 119 |
|
|---|
| 120 | twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_NETBIOS;
|
|---|
| 121 | twr->tower.floors[4].lhs.lhs_data = data_blob(NULL, 0);
|
|---|
| 122 | twr->tower.floors[4].rhs.netbios.name = "";
|
|---|
| 123 |
|
|---|
| 124 | status = dcerpc_epm_Map(p, mem_ctx, &r);
|
|---|
| 125 | if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
|
|---|
| 126 | for (i=0;i<*r.out.num_towers;i++) {
|
|---|
| 127 | if (r.out.towers[i].twr) {
|
|---|
| 128 | display_tower(mem_ctx, &r.out.towers[i].twr->tower);
|
|---|
| 129 | }
|
|---|
| 130 | }
|
|---|
| 131 | }
|
|---|
| 132 |
|
|---|
| 133 | /* FIXME: Extend to do other protocols as well (ncacn_unix_stream, ncalrpc) */
|
|---|
| 134 |
|
|---|
| 135 | return true;
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| 138 | static bool test_Lookup(struct torture_context *tctx,
|
|---|
| 139 | struct dcerpc_pipe *p)
|
|---|
| 140 | {
|
|---|
| 141 | NTSTATUS status;
|
|---|
| 142 | struct epm_Lookup r;
|
|---|
| 143 | struct GUID uuid;
|
|---|
| 144 | struct rpc_if_id_t iface;
|
|---|
| 145 | struct policy_handle handle;
|
|---|
| 146 | uint32_t num_ents;
|
|---|
| 147 |
|
|---|
| 148 | ZERO_STRUCT(handle);
|
|---|
| 149 |
|
|---|
| 150 | r.in.inquiry_type = 0;
|
|---|
| 151 | r.in.object = &uuid;
|
|---|
| 152 | r.in.interface_id = &iface;
|
|---|
| 153 | r.in.vers_option = 0;
|
|---|
| 154 | r.in.entry_handle = &handle;
|
|---|
| 155 | r.out.entry_handle = &handle;
|
|---|
| 156 | r.in.max_ents = 10;
|
|---|
| 157 | r.out.num_ents = &num_ents;
|
|---|
| 158 |
|
|---|
| 159 | do {
|
|---|
| 160 | int i;
|
|---|
| 161 |
|
|---|
| 162 | ZERO_STRUCT(uuid);
|
|---|
| 163 | ZERO_STRUCT(iface);
|
|---|
| 164 |
|
|---|
| 165 | status = dcerpc_epm_Lookup(p, tctx, &r);
|
|---|
| 166 | if (!NT_STATUS_IS_OK(status) || r.out.result != 0) {
|
|---|
| 167 | break;
|
|---|
| 168 | }
|
|---|
| 169 |
|
|---|
| 170 | printf("epm_Lookup returned %d events GUID %s\n",
|
|---|
| 171 | *r.out.num_ents, GUID_string(tctx, &handle.uuid));
|
|---|
| 172 |
|
|---|
| 173 | for (i=0;i<*r.out.num_ents;i++) {
|
|---|
| 174 | printf("\nFound '%s'\n", r.out.entries[i].annotation);
|
|---|
| 175 | display_tower(tctx, &r.out.entries[i].tower->tower);
|
|---|
| 176 | if (r.out.entries[i].tower->tower.num_floors == 5) {
|
|---|
| 177 | test_Map(p, tctx, r.out.entries[i].tower);
|
|---|
| 178 | }
|
|---|
| 179 | }
|
|---|
| 180 | } while (NT_STATUS_IS_OK(status) &&
|
|---|
| 181 | r.out.result == 0 &&
|
|---|
| 182 | *r.out.num_ents == r.in.max_ents &&
|
|---|
| 183 | !policy_handle_empty(&handle));
|
|---|
| 184 |
|
|---|
| 185 | torture_assert_ntstatus_ok(tctx, status, "Lookup failed");
|
|---|
| 186 |
|
|---|
| 187 | return true;
|
|---|
| 188 | }
|
|---|
| 189 |
|
|---|
| 190 | static bool test_Delete(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct epm_entry_t *entries)
|
|---|
| 191 | {
|
|---|
| 192 | NTSTATUS status;
|
|---|
| 193 | struct epm_Delete r;
|
|---|
| 194 |
|
|---|
| 195 | r.in.num_ents = 1;
|
|---|
| 196 | r.in.entries = entries;
|
|---|
| 197 |
|
|---|
| 198 | status = dcerpc_epm_Delete(p, mem_ctx, &r);
|
|---|
| 199 | if (NT_STATUS_IS_ERR(status)) {
|
|---|
| 200 | printf("Delete failed - %s\n", nt_errstr(status));
|
|---|
| 201 | return false;
|
|---|
| 202 | }
|
|---|
| 203 |
|
|---|
| 204 | if (r.out.result != 0) {
|
|---|
| 205 | printf("Delete failed - %d\n", r.out.result);
|
|---|
| 206 | return false;
|
|---|
| 207 | }
|
|---|
| 208 |
|
|---|
| 209 | return true;
|
|---|
| 210 | }
|
|---|
| 211 |
|
|---|
| 212 | static bool test_Insert(struct torture_context *tctx,
|
|---|
| 213 | struct dcerpc_pipe *p)
|
|---|
| 214 | {
|
|---|
| 215 | NTSTATUS status;
|
|---|
| 216 | struct epm_Insert r;
|
|---|
| 217 | struct dcerpc_binding *bd;
|
|---|
| 218 |
|
|---|
| 219 | r.in.num_ents = 1;
|
|---|
| 220 |
|
|---|
| 221 | r.in.entries = talloc_array(tctx, struct epm_entry_t, 1);
|
|---|
| 222 | ZERO_STRUCT(r.in.entries[0].object);
|
|---|
| 223 | r.in.entries[0].annotation = "smbtorture endpoint";
|
|---|
| 224 | status = dcerpc_parse_binding(tctx, "ncalrpc:[SMBTORTURE]", &bd);
|
|---|
| 225 | torture_assert_ntstatus_ok(tctx, status,
|
|---|
| 226 | "Unable to generate dcerpc_binding struct");
|
|---|
| 227 |
|
|---|
| 228 | r.in.entries[0].tower = talloc(tctx, struct epm_twr_t);
|
|---|
| 229 |
|
|---|
| 230 | status = dcerpc_binding_build_tower(tctx, bd, &r.in.entries[0].tower->tower);
|
|---|
| 231 | torture_assert_ntstatus_ok(tctx, status,
|
|---|
| 232 | "Unable to build tower from binding struct");
|
|---|
| 233 |
|
|---|
| 234 | r.in.replace = 0;
|
|---|
| 235 |
|
|---|
| 236 | status = dcerpc_epm_Insert(p, tctx, &r);
|
|---|
| 237 | torture_assert_ntstatus_ok(tctx, status, "Insert failed");
|
|---|
| 238 |
|
|---|
| 239 | torture_assert(tctx, r.out.result == 0, "Insert failed");
|
|---|
| 240 |
|
|---|
| 241 | if (!test_Delete(p, tctx, r.in.entries)) {
|
|---|
| 242 | return false;
|
|---|
| 243 | }
|
|---|
| 244 |
|
|---|
| 245 | return true;
|
|---|
| 246 | }
|
|---|
| 247 |
|
|---|
| 248 | static bool test_InqObject(struct torture_context *tctx, struct dcerpc_pipe *p)
|
|---|
| 249 | {
|
|---|
| 250 | NTSTATUS status;
|
|---|
| 251 | struct epm_InqObject r;
|
|---|
| 252 |
|
|---|
| 253 | r.in.epm_object = talloc(tctx, struct GUID);
|
|---|
| 254 | *r.in.epm_object = ndr_table_epmapper.syntax_id.uuid;
|
|---|
| 255 |
|
|---|
| 256 | status = dcerpc_epm_InqObject(p, tctx, &r);
|
|---|
| 257 | torture_assert_ntstatus_ok(tctx, status, "InqObject failed");
|
|---|
| 258 |
|
|---|
| 259 | return true;
|
|---|
| 260 | }
|
|---|
| 261 |
|
|---|
| 262 | struct torture_suite *torture_rpc_epmapper(TALLOC_CTX *mem_ctx)
|
|---|
| 263 | {
|
|---|
| 264 | struct torture_suite *suite = torture_suite_create(mem_ctx, "EPMAPPER");
|
|---|
| 265 | struct torture_rpc_tcase *tcase;
|
|---|
| 266 |
|
|---|
| 267 | tcase = torture_suite_add_rpc_iface_tcase(suite, "epmapper",
|
|---|
| 268 | &ndr_table_epmapper);
|
|---|
| 269 |
|
|---|
| 270 | torture_rpc_tcase_add_test(tcase, "Lookup", test_Lookup);
|
|---|
| 271 | torture_rpc_tcase_add_test(tcase, "Insert", test_Insert);
|
|---|
| 272 | torture_rpc_tcase_add_test(tcase, "InqObject", test_InqObject);
|
|---|
| 273 |
|
|---|
| 274 | return suite;
|
|---|
| 275 | }
|
|---|