static bool get_rpc_shares(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state) { NTSTATUS status; struct rpc_pipe_client *pipe_hnd = NULL; TALLOC_CTX *mem_ctx; WERROR werr; struct srvsvc_NetShareInfoCtr info_ctr; struct srvsvc_NetShareCtr1 ctr1; int i; uint32_t resume_handle = 0; uint32_t total_entries = 0; struct dcerpc_binding_handle *b; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { DEBUG(0, ("talloc_new failed\n")); return False; } status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Could not connect to srvsvc pipe: %s\n", nt_errstr(status))); TALLOC_FREE(mem_ctx); return False; } b = pipe_hnd->binding_handle; ZERO_STRUCT(info_ctr); ZERO_STRUCT(ctr1); info_ctr.level = 1; info_ctr.ctr.ctr1 = &ctr1; status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx, pipe_hnd->desthost, &info_ctr, 0xffffffff, &total_entries, &resume_handle, &werr); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) { TALLOC_FREE(mem_ctx); TALLOC_FREE(pipe_hnd); return False; } for (i=0; i<total_entries; i++) { struct srvsvc_NetShareInfo1 info = info_ctr.ctr.ctr1->array[i]; fn(info.name, info.type, info.comment, state); } TALLOC_FREE(mem_ctx); TALLOC_FREE(pipe_hnd); return True; }
WERROR NetShareEnum_r(struct libnetapi_ctx *ctx, struct NetShareEnum *r) { WERROR werr; NTSTATUS status; struct srvsvc_NetShareInfoCtr info_ctr; struct srvsvc_NetShareCtr0 ctr0; struct srvsvc_NetShareCtr1 ctr1; struct srvsvc_NetShareCtr2 ctr2; uint32_t i; struct dcerpc_binding_handle *b; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 1: case 2: break; case 502: case 503: return WERR_NOT_SUPPORTED; default: return WERR_UNKNOWN_LEVEL; } ZERO_STRUCT(info_ctr); werr = libnetapi_get_binding_handle(ctx, r->in.server_name, &ndr_table_srvsvc, &b); if (!W_ERROR_IS_OK(werr)) { goto done; } info_ctr.level = r->in.level; switch (r->in.level) { case 0: ZERO_STRUCT(ctr0); info_ctr.ctr.ctr0 = &ctr0; break; case 1: ZERO_STRUCT(ctr1); info_ctr.ctr.ctr1 = &ctr1; break; case 2: ZERO_STRUCT(ctr2); info_ctr.ctr.ctr2 = &ctr2; break; } status = dcerpc_srvsvc_NetShareEnumAll(b, talloc_tos(), r->in.server_name, &info_ctr, r->in.prefmaxlen, r->out.total_entries, r->out.resume_handle, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!W_ERROR_IS_OK(werr) && !W_ERROR_EQUAL(werr, WERR_MORE_DATA)) { goto done; } for (i=0; i < info_ctr.ctr.ctr1->count; i++) { union srvsvc_NetShareInfo _i; switch (r->in.level) { case 0: _i.info0 = &info_ctr.ctr.ctr0->array[i]; break; case 1: _i.info1 = &info_ctr.ctr.ctr1->array[i]; break; case 2: _i.info2 = &info_ctr.ctr.ctr2->array[i]; break; } status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx, r->in.level, &_i, r->out.buffer, r->out.entries_read); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } done: return werr; }
NTSTATUS libnet_ListShares(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_ListShares *r) { NTSTATUS status; struct libnet_RpcConnect c; struct srvsvc_NetShareEnumAll s; struct srvsvc_NetShareInfoCtr info_ctr; uint32_t resume_handle = 0; uint32_t totalentries = 0; struct srvsvc_NetShareCtr0 ctr0; struct srvsvc_NetShareCtr1 ctr1; struct srvsvc_NetShareCtr2 ctr2; struct srvsvc_NetShareCtr501 ctr501; struct srvsvc_NetShareCtr502 ctr502; c.level = LIBNET_RPC_CONNECT_SERVER; c.in.name = r->in.server_name; c.in.dcerpc_iface = &ndr_table_srvsvc; s.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", c.in.name); status = libnet_RpcConnect(ctx, mem_ctx, &c); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "Connection to SRVSVC pipe of server %s " "failed: %s", r->in.server_name, nt_errstr(status)); return status; } info_ctr.level = r->in.level; switch (info_ctr.level) { case 0: info_ctr.ctr.ctr0 = &ctr0; ZERO_STRUCT(ctr0); break; case 1: info_ctr.ctr.ctr1 = &ctr1; ZERO_STRUCT(ctr1); break; case 2: info_ctr.ctr.ctr2 = &ctr2; ZERO_STRUCT(ctr2); break; case 501: info_ctr.ctr.ctr501 = &ctr501; ZERO_STRUCT(ctr501); break; case 502: info_ctr.ctr.ctr502 = &ctr502; ZERO_STRUCT(ctr502); break; default: r->out.error_string = talloc_asprintf(mem_ctx, "libnet_ListShares: Invalid info level requested: %d", info_ctr.level); return NT_STATUS_INVALID_PARAMETER; } s.in.max_buffer = ~0; s.in.resume_handle = &resume_handle; s.in.info_ctr = &info_ctr; s.out.info_ctr = &info_ctr; s.out.totalentries = &totalentries; status = dcerpc_srvsvc_NetShareEnumAll(c.out.dcerpc_pipe, mem_ctx, &s); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "srvsvc_NetShareEnumAll on server '%s' failed" ": %s", r->in.server_name, nt_errstr(status)); goto disconnect; } if (!W_ERROR_IS_OK(s.out.result) && !W_ERROR_EQUAL(s.out.result, WERR_MORE_DATA)) { r->out.error_string = talloc_asprintf(mem_ctx, "srvsvc_NetShareEnumAll on server '%s' failed: %s", r->in.server_name, win_errstr(s.out.result)); goto disconnect; } r->out.ctr = s.out.info_ctr->ctr; disconnect: talloc_free(c.out.dcerpc_pipe); return status; }