1/* 2 Unix SMB/CIFS implementation. 3 Test suite for libnet calls. 4 5 Copyright (C) Gregory LEOCADIE <gleocadie@idealx.com> 2005 6 Copyright (C) Rafal Szczesniak 2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "torture/rpc/rpc.h" 24#include "libnet/libnet.h" 25#include "lib/cmdline/popt_common.h" 26#include "librpc/gen_ndr/ndr_srvsvc_c.h" 27 28 29#define TEST_SHARENAME "libnetsharetest" 30 31 32static void test_displayshares(struct libnet_ListShares s) 33{ 34 int i, j; 35 36 struct share_type { 37 enum srvsvc_ShareType type; 38 const char *desc; 39 } share_types[] = { 40 { STYPE_DISKTREE, "STYPE_DISKTREE" }, 41 { STYPE_DISKTREE_TEMPORARY, "STYPE_DISKTREE_TEMPORARY" }, 42 { STYPE_DISKTREE_HIDDEN, "STYPE_DISKTREE_HIDDEN" }, 43 { STYPE_PRINTQ, "STYPE_PRINTQ" }, 44 { STYPE_PRINTQ_TEMPORARY, "STYPE_PRINTQ_TEMPORARY" }, 45 { STYPE_PRINTQ_HIDDEN, "STYPE_PRINTQ_HIDDEN" }, 46 { STYPE_DEVICE, "STYPE_DEVICE" }, 47 { STYPE_DEVICE_TEMPORARY, "STYPE_DEVICE_TEMPORARY" }, 48 { STYPE_DEVICE_HIDDEN, "STYPE_DEVICE_HIDDEN" }, 49 { STYPE_IPC, "STYPE_IPC" }, 50 { STYPE_IPC_TEMPORARY, "STYPE_IPC_TEMPORARY" }, 51 { STYPE_IPC_HIDDEN, "STYPE_IPC_HIDDEN" } 52 }; 53 54 switch (s.in.level) { 55 case 0: 56 for (i = 0; i < s.out.ctr.ctr0->count; i++) { 57 struct srvsvc_NetShareInfo0 *info = &s.out.ctr.ctr0->array[i]; 58 d_printf("\t[%d] %s\n", i, info->name); 59 } 60 break; 61 62 case 1: 63 for (i = 0; i < s.out.ctr.ctr1->count; i++) { 64 struct srvsvc_NetShareInfo1 *info = &s.out.ctr.ctr1->array[i]; 65 for (j = 0; j < ARRAY_SIZE(share_types); j++) { 66 if (share_types[j].type == info->type) break; 67 } 68 d_printf("\t[%d] %s (%s)\t%s\n", i, info->name, 69 info->comment, share_types[j].desc); 70 } 71 break; 72 73 case 2: 74 for (i = 0; i < s.out.ctr.ctr2->count; i++) { 75 struct srvsvc_NetShareInfo2 *info = &s.out.ctr.ctr2->array[i]; 76 for (j = 0; j < ARRAY_SIZE(share_types); j++) { 77 if (share_types[j].type == info->type) break; 78 } 79 d_printf("\t[%d] %s\t%s\n\t %s\n\t [perms=0x%08x, max_usr=%d, cur_usr=%d, path=%s, pass=%s]\n", 80 i, info->name, share_types[j].desc, info->comment, 81 info->permissions, info->max_users, 82 info->current_users, info->path, 83 info->password); 84 } 85 break; 86 87 case 501: 88 for (i = 0; i < s.out.ctr.ctr501->count; i++) { 89 struct srvsvc_NetShareInfo501 *info = &s.out.ctr.ctr501->array[i]; 90 for (j = 0; j < ARRAY_SIZE(share_types); j++) { 91 if (share_types[j].type == info->type) break; 92 } 93 d_printf("\t[%d] %s\t%s [csc_policy=0x%08x]\n\t %s\n", i, info->name, 94 share_types[j].desc, info->csc_policy, 95 info->comment); 96 } 97 break; 98 99 case 502: 100 for (i = 0; i < s.out.ctr.ctr502->count; i++) { 101 struct srvsvc_NetShareInfo502 *info = &s.out.ctr.ctr502->array[i]; 102 for (j = 0; j < ARRAY_SIZE(share_types); j++) { 103 if (share_types[j].type == info->type) break; 104 } 105 d_printf("\t[%d] %s\t%s\n\t %s\n\t [perms=0x%08x, max_usr=%d, cur_usr=%d, path=%s, pass=%s]\n", 106 i, info->name, share_types[j].desc, info->comment, 107 info->permissions, info->max_users, 108 info->current_users, info->path, 109 info->password); 110 } 111 break; 112 } 113} 114 115 116bool torture_listshares(struct torture_context *torture) 117{ 118 struct libnet_ListShares share; 119 NTSTATUS status; 120 uint32_t levels[] = { 0, 1, 2, 501, 502 }; 121 int i; 122 bool ret = true; 123 struct libnet_context* libnetctx; 124 struct dcerpc_binding *binding; 125 TALLOC_CTX *mem_ctx; 126 127 mem_ctx = talloc_init("test_listshares"); 128 status = torture_rpc_binding(torture, &binding); 129 if (!NT_STATUS_IS_OK(status)) { 130 ret = false; 131 goto done; 132 } 133 134 libnetctx = libnet_context_init(torture->ev, torture->lp_ctx); 135 if (!libnetctx) { 136 printf("Couldn't allocate libnet context\n"); 137 ret = false; 138 goto done; 139 } 140 141 libnetctx->cred = cmdline_credentials; 142 143 printf("Testing libnet_ListShare\n"); 144 145 share.in.server_name = talloc_asprintf(mem_ctx, "%s", binding->host); 146 147 for (i = 0; i < ARRAY_SIZE(levels); i++) { 148 share.in.level = levels[i]; 149 printf("testing libnet_ListShare level %u\n", share.in.level); 150 151 status = libnet_ListShares(libnetctx, mem_ctx, &share); 152 if (!NT_STATUS_IS_OK(status)) { 153 printf("libnet_ListShare level %u failed - %s\n", share.in.level, share.out.error_string); 154 ret = false; 155 goto done; 156 } 157 158 printf("listing shares:\n"); 159 test_displayshares(share); 160 } 161 162done: 163 talloc_free(mem_ctx); 164 return ret; 165} 166 167 168static bool test_addshare(struct dcerpc_pipe *svc_pipe, TALLOC_CTX *mem_ctx, const char *host, 169 const char* share) 170{ 171 NTSTATUS status; 172 struct srvsvc_NetShareAdd add; 173 union srvsvc_NetShareInfo info; 174 struct srvsvc_NetShareInfo2 i; 175 176 i.name = share; 177 i.type = STYPE_DISKTREE; 178 i.path = "C:\\WINDOWS\\TEMP"; 179 i.max_users = 5; 180 i.comment = "Comment to the test share"; 181 i.password = NULL; 182 i.permissions = 0x0; 183 184 info.info2 = &i; 185 186 add.in.server_unc = host; 187 add.in.level = 2; 188 add.in.info = &info; 189 add.in.parm_error = NULL; 190 191 status = dcerpc_srvsvc_NetShareAdd(svc_pipe, mem_ctx, &add); 192 if (!NT_STATUS_IS_OK(status)) { 193 printf("Failed to add a new share\n"); 194 return false; 195 } 196 197 printf("share added\n"); 198 return true; 199} 200 201 202bool torture_delshare(struct torture_context *torture) 203{ 204 struct dcerpc_pipe *p; 205 struct dcerpc_binding *binding; 206 struct libnet_context* libnetctx; 207 const char *host; 208 NTSTATUS status; 209 bool ret = true; 210 struct libnet_DelShare share; 211 212 host = torture_setting_string(torture, "host", NULL); 213 status = torture_rpc_binding(torture, &binding); 214 torture_assert_ntstatus_ok(torture, status, "Failed to get binding"); 215 216 libnetctx = libnet_context_init(torture->ev, torture->lp_ctx); 217 libnetctx->cred = cmdline_credentials; 218 219 status = torture_rpc_connection(torture, 220 &p, 221 &ndr_table_srvsvc); 222 223 torture_assert_ntstatus_ok(torture, status, "Failed to get rpc connection"); 224 225 if (!test_addshare(p, torture, host, TEST_SHARENAME)) { 226 return false; 227 } 228 229 share.in.server_name = binding->host; 230 share.in.share_name = TEST_SHARENAME; 231 232 status = libnet_DelShare(libnetctx, torture, &share); 233 torture_assert_ntstatus_ok(torture, status, "Failed to delete share"); 234 235 return ret; 236} 237