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; 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; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { DEBUG(0, ("talloc_new failed\n")); return False; } pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status); if (pipe_hnd == NULL) { DEBUG(10, ("Could not connect to srvsvc pipe: %s\n", nt_errstr(status))); TALLOC_FREE(mem_ctx); return False; } ZERO_STRUCT(info_ctr); ZERO_STRUCT(ctr1); info_ctr.level = 1; info_ctr.ctr.ctr1 = &ctr1; status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, mem_ctx, pipe_hnd->cli->desthost, &info_ctr, 0xffffffff, &total_entries, &resume_handle, &werr); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) { TALLOC_FREE(mem_ctx); cli_rpc_pipe_close(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); cli_rpc_pipe_close(pipe_hnd); return True; }
WERROR NetShareEnum_r(struct libnetapi_ctx *ctx, struct NetShareEnum *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; struct srvsvc_NetShareInfoCtr info_ctr; struct srvsvc_NetShareCtr0 ctr0; struct srvsvc_NetShareCtr1 ctr1; struct srvsvc_NetShareCtr2 ctr2; uint32_t i; 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_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); 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 = rpccli_srvsvc_NetShareEnumAll(pipe_cli, ctx, r->in.server_name, &info_ctr, r->in.prefmaxlen, r->out.total_entries, r->out.resume_handle, &werr); if (NT_STATUS_IS_ERR(status)) { 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); } } done: return werr; }