From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- source3/rpcclient/cmd_srvsvc.c | 1266 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1266 insertions(+) create mode 100644 source3/rpcclient/cmd_srvsvc.c (limited to 'source3/rpcclient/cmd_srvsvc.c') diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c new file mode 100644 index 0000000..073e51d --- /dev/null +++ b/source3/rpcclient/cmd_srvsvc.c @@ -0,0 +1,1266 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Andrew Tridgell 1992-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999 + Copyright (C) Tim Potter 2000,2002 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "rpcclient.h" +#include "../librpc/gen_ndr/ndr_srvsvc.h" +#include "../librpc/gen_ndr/ndr_srvsvc_c.h" +#include "../libcli/security/display_sec.h" +#include "lib/util/string_wrappers.h" + +/* Display server query info */ + +static char *get_server_type_str(uint32_t type) +{ + static fstring typestr; + int i; + + if (type == SV_TYPE_ALL) { + fstrcpy(typestr, "All"); + return typestr; + } + + typestr[0] = 0; + + for (i = 0; i < 32; i++) { + if (type & ((uint32_t)1 << i)) { + switch (1 << i) { + case SV_TYPE_WORKSTATION: + fstrcat(typestr, "Wk "); + break; + case SV_TYPE_SERVER: + fstrcat(typestr, "Sv "); + break; + case SV_TYPE_SQLSERVER: + fstrcat(typestr, "Sql "); + break; + case SV_TYPE_DOMAIN_CTRL: + fstrcat(typestr, "PDC "); + break; + case SV_TYPE_DOMAIN_BAKCTRL: + fstrcat(typestr, "BDC "); + break; + case SV_TYPE_TIME_SOURCE: + fstrcat(typestr, "Tim "); + break; + case SV_TYPE_AFP: + fstrcat(typestr, "AFP "); + break; + case SV_TYPE_NOVELL: + fstrcat(typestr, "Nov "); + break; + case SV_TYPE_DOMAIN_MEMBER: + fstrcat(typestr, "Dom "); + break; + case SV_TYPE_PRINTQ_SERVER: + fstrcat(typestr, "PrQ "); + break; + case SV_TYPE_DIALIN_SERVER: + fstrcat(typestr, "Din "); + break; + case SV_TYPE_SERVER_UNIX: + fstrcat(typestr, "Unx "); + break; + case SV_TYPE_NT: + fstrcat(typestr, "NT "); + break; + case SV_TYPE_WFW: + fstrcat(typestr, "Wfw "); + break; + case SV_TYPE_SERVER_MFPN: + fstrcat(typestr, "Mfp "); + break; + case SV_TYPE_SERVER_NT: + fstrcat(typestr, "SNT "); + break; + case SV_TYPE_POTENTIAL_BROWSER: + fstrcat(typestr, "PtB "); + break; + case SV_TYPE_BACKUP_BROWSER: + fstrcat(typestr, "BMB "); + break; + case SV_TYPE_MASTER_BROWSER: + fstrcat(typestr, "LMB "); + break; + case SV_TYPE_DOMAIN_MASTER: + fstrcat(typestr, "DMB "); + break; + case SV_TYPE_SERVER_OSF: + fstrcat(typestr, "OSF "); + break; + case SV_TYPE_SERVER_VMS: + fstrcat(typestr, "VMS "); + break; + case SV_TYPE_WIN95_PLUS: + fstrcat(typestr, "W95 "); + break; + case SV_TYPE_ALTERNATE_XPORT: + fstrcat(typestr, "Xpt "); + break; + case SV_TYPE_LOCAL_LIST_ONLY: + fstrcat(typestr, "Dom "); + break; + case SV_TYPE_DOMAIN_ENUM: + fstrcat(typestr, "Loc "); + break; + } + } + } + + i = strlen(typestr) - 1; + + if (typestr[i] == ' ') + typestr[i] = 0; + + return typestr; +} + +static void display_server(const char *sname, uint32_t type, const char *comment) +{ + printf("\t%-15.15s%-20s %s\n", sname, get_server_type_str(type), + comment); +} + +static void display_srv_info_101(struct srvsvc_NetSrvInfo101 *r) +{ + display_server(r->server_name, r->server_type, r->comment); + + printf("\tplatform_id :\t%d\n", r->platform_id); + printf("\tos version :\t%d.%d\n", + r->version_major, r->version_minor); + printf("\tserver type :\t0x%x\n", r->server_type); +} + +static void display_srv_info_102(struct srvsvc_NetSrvInfo102 *r) +{ + display_server(r->server_name, r->server_type, r->comment); + + printf("\tplatform_id :\t%d\n", r->platform_id); + printf("\tos version :\t%d.%d\n", + r->version_major, r->version_minor); + printf("\tserver type :\t0x%x\n", r->server_type); + + printf("\tusers :\t%x\n", r->users); + printf("\tdisc, hidden :\t%x, %x\n", r->disc, r->hidden); + printf("\tannounce, delta :\t%d, %d\n", r->announce, + r->anndelta); + printf("\tlicenses :\t%d\n", r->licenses); + printf("\tuser path :\t%s\n", r->userpath); +} + +/* Server query info */ +static WERROR cmd_srvsvc_srv_query_info(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32_t info_level = 101; + union srvsvc_NetSrvInfo info; + WERROR result; + NTSTATUS status; + const char *server_unc = cli->srv_name_slash; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 3) { + printf("Usage: %s [infolevel] [server_unc]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + info_level = atoi(argv[1]); + } + + if (argc >= 3) { + server_unc = argv[2]; + } + + status = dcerpc_srvsvc_NetSrvGetInfo(b, mem_ctx, + server_unc, + info_level, + &info, + &result); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* Display results */ + + switch (info_level) { + case 101: + display_srv_info_101(info.info101); + break; + case 102: + display_srv_info_102(info.info102); + break; + default: + printf("unsupported info level %d\n", info_level); + break; + } + + done: + return result; +} + +static void display_share_info_1(struct srvsvc_NetShareInfo1 *r) +{ + printf("netname: %s\n", r->name); + printf("\tremark:\t%s\n", r->comment); +} + +static void display_share_info_2(struct srvsvc_NetShareInfo2 *r) +{ + printf("netname: %s\n", r->name); + printf("\tremark:\t%s\n", r->comment); + printf("\tpath:\t%s\n", r->path); + printf("\tpassword:\t%s\n", r->password); +} + +static void display_share_info_502(struct srvsvc_NetShareInfo502 *r) +{ + printf("netname: %s\n", r->name); + printf("\tremark:\t%s\n", r->comment); + printf("\tpath:\t%s\n", r->path); + printf("\tpassword:\t%s\n", r->password); + + printf("\ttype:\t0x%x\n", r->type); + printf("\tperms:\t%d\n", r->permissions); + printf("\tmax_uses:\t%d\n", r->max_users); + printf("\tnum_uses:\t%d\n", r->current_users); + + if (r->sd_buf.sd) + display_sec_desc(r->sd_buf.sd); + +} + +static void display_share_info_1005(struct srvsvc_NetShareInfo1005 *r) +{ + printf("flags: 0x%x\n", r->dfs_flags); + printf("csc caching: %u\n", + (r->dfs_flags & SHARE_1005_CSC_POLICY_MASK) >> + SHARE_1005_CSC_POLICY_SHIFT); +} + +static WERROR cmd_srvsvc_net_share_enum_int(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv, + uint32_t opcode) +{ + uint32_t info_level = 2; + struct srvsvc_NetShareInfoCtr info_ctr; + struct srvsvc_NetShareCtr0 ctr0; + struct srvsvc_NetShareCtr1 ctr1; + struct srvsvc_NetShareCtr2 ctr2; + struct srvsvc_NetShareCtr501 ctr501; + struct srvsvc_NetShareCtr502 ctr502; + struct srvsvc_NetShareCtr1004 ctr1004; + struct srvsvc_NetShareCtr1005 ctr1005; + struct srvsvc_NetShareCtr1006 ctr1006; + struct srvsvc_NetShareCtr1007 ctr1007; + struct srvsvc_NetShareCtr1501 ctr1501; + WERROR result; + NTSTATUS status; + uint32_t totalentries = 0; + uint32_t count = 0; + uint32_t resume_handle = 0; + uint32_t *resume_handle_p = NULL; + uint32_t preferred_len = 0xffffffff, i; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 3) { + printf("Usage: %s [infolevel] [resume_handle]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + info_level = atoi(argv[1]); + } + + if (argc == 3) { + resume_handle = atoi(argv[2]); + resume_handle_p = &resume_handle; + } + + ZERO_STRUCT(info_ctr); + + info_ctr.level = info_level; + + switch (info_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; + case 501: + ZERO_STRUCT(ctr501); + info_ctr.ctr.ctr501 = &ctr501; + break; + case 502: + ZERO_STRUCT(ctr502); + info_ctr.ctr.ctr502 = &ctr502; + break; + case 1004: + ZERO_STRUCT(ctr1004); + info_ctr.ctr.ctr1004 = &ctr1004; + break; + case 1005: + ZERO_STRUCT(ctr1005); + info_ctr.ctr.ctr1005 = &ctr1005; + break; + case 1006: + ZERO_STRUCT(ctr1006); + info_ctr.ctr.ctr1006 = &ctr1006; + break; + case 1007: + ZERO_STRUCT(ctr1007); + info_ctr.ctr.ctr1007 = &ctr1007; + break; + case 1501: + ZERO_STRUCT(ctr1501); + info_ctr.ctr.ctr1501 = &ctr1501; + break; + } + + switch (opcode) { + case NDR_SRVSVC_NETSHAREENUM: + status = dcerpc_srvsvc_NetShareEnum(b, mem_ctx, + cli->desthost, + &info_ctr, + preferred_len, + &totalentries, + resume_handle_p, + &result); + break; + case NDR_SRVSVC_NETSHAREENUMALL: + status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx, + cli->desthost, + &info_ctr, + preferred_len, + &totalentries, + resume_handle_p, + &result); + break; + default: + return WERR_INVALID_PARAMETER; + } + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* Display results */ + + switch (info_level) { + case 1: + count = info_ctr.ctr.ctr1->count; + for (i = 0; i < count; i++) + display_share_info_1(&info_ctr.ctr.ctr1->array[i]); + break; + case 2: + count = info_ctr.ctr.ctr2->count; + for (i = 0; i < count; i++) + display_share_info_2(&info_ctr.ctr.ctr2->array[i]); + break; + case 502: + count = info_ctr.ctr.ctr502->count; + for (i = 0; i < count; i++) + display_share_info_502(&info_ctr.ctr.ctr502->array[i]); + break; + default: + printf("unsupported info level %d\n", info_level); + break; + } + + done: + return result; +} + +static WERROR cmd_srvsvc_net_share_enum(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + return cmd_srvsvc_net_share_enum_int(cli, mem_ctx, + argc, argv, + NDR_SRVSVC_NETSHAREENUM); +} + +static WERROR cmd_srvsvc_net_share_enum_all(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + return cmd_srvsvc_net_share_enum_int(cli, mem_ctx, + argc, argv, + NDR_SRVSVC_NETSHAREENUMALL); +} + +static WERROR cmd_srvsvc_net_share_get_info(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32_t info_level = 502; + union srvsvc_NetShareInfo info; + WERROR result; + NTSTATUS status; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc < 2 || argc > 3) { + printf("Usage: %s sharename [infolevel 1|2|502|1005]\n", + argv[0]); + return WERR_OK; + } + + if (argc == 3) + info_level = atoi(argv[2]); + + status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx, + cli->desthost, + argv[1], + info_level, + &info, + &result); + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* Display results */ + + switch (info_level) { + case 1: + display_share_info_1(info.info1); + break; + case 2: + display_share_info_2(info.info2); + break; + case 502: + display_share_info_502(info.info502); + break; + case 1005: + display_share_info_1005(info.info1005); + break; + default: + printf("unsupported info level %d\n", info_level); + break; + } + + done: + return result; +} + +static WERROR cmd_srvsvc_net_share_set_info(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32_t info_level = 502; + union srvsvc_NetShareInfo info_get; + WERROR result; + NTSTATUS status; + uint32_t parm_err = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 3) { + printf("Usage: %s [sharename] [comment]\n", argv[0]); + return WERR_OK; + } + + /* retrieve share info */ + status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx, + cli->desthost, + argv[1], + info_level, + &info_get, + &result); + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + info_get.info502->comment = argv[2]; + + /* set share info */ + status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx, + cli->desthost, + argv[1], + info_level, + &info_get, + &parm_err, + &result); + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* re-retrieve share info and display */ + status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx, + cli->desthost, + argv[1], + info_level, + &info_get, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + display_share_info_502(info_get.info502); + + done: + return result; +} + +static WERROR cmd_srvsvc_net_share_set_dfs_flags(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + struct srvsvc_NetShareInfo1005 info1005 = { 0 }; + union srvsvc_NetShareInfo info = { .info1005 = &info1005 }; + WERROR result; + NTSTATUS status; + uint32_t parm_err = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 3) { + printf("Usage: %s [sharename] [dfsflags]\n", argv[0]); + return WERR_OK; + } + + if (argc > 2) { + info.info1005->dfs_flags = strtol(argv[2], NULL, 0); + } + + /* set share info */ + status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx, + cli->desthost, + argv[1], + 1005, + &info, + &parm_err, + &result); + + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + return result; + } + + /* re-retrieve share info and display */ + status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx, + cli->desthost, + argv[1], + 1005, + &info, + &result); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + return result; + } + + display_share_info_1005(info.info1005); + + return result; +} + +static WERROR cmd_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + struct srvsvc_NetRemoteTODInfo *tod = NULL; + WERROR result; + NTSTATUS status; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 1) { + printf("Usage: %s\n", argv[0]); + return WERR_OK; + } + + status = dcerpc_srvsvc_NetRemoteTOD(b, mem_ctx, + cli->srv_name_slash, + &tod, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + return result; +} + +static WERROR cmd_srvsvc_net_file_enum(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + struct srvsvc_NetFileCtr3 ctr3 = { 0 }; + struct srvsvc_NetFileInfoCtr info_ctr = { + .level = 3, + .ctr = { + .ctr3 = &ctr3, + }, + }; + WERROR result; + NTSTATUS status; + uint32_t preferred_len = 0xffff; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 2) { + printf("Usage: %s [infolevel]\n", argv[0]); + return WERR_OK; + } + + if (argc == 2) { + info_ctr.level = atoi(argv[1]); + } + + status = dcerpc_srvsvc_NetFileEnum(b, mem_ctx, + cli->desthost, + NULL, + NULL, + &info_ctr, + preferred_len, + &total_entries, + &resume_handle, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + if (info_ctr.level == 3) { + struct srvsvc_NetFileCtr3 *ret = info_ctr.ctr.ctr3; + uint32_t i; + + for (i=0; icount; i++) { + printf("%s\n", ret->array[i].path); + } + } + done: + return result; +} + +static WERROR cmd_srvsvc_net_name_validate(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + WERROR result; + NTSTATUS status; + uint32_t name_type = 9; + uint32_t flags = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc < 2 || argc > 3) { + printf("Usage: %s [sharename] [type]\n", argv[0]); + return WERR_OK; + } + + if (argc == 3) { + name_type = atoi(argv[2]); + } + + status = dcerpc_srvsvc_NetNameValidate(b, mem_ctx, + cli->desthost, + argv[1], + name_type, + flags, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + return result; +} + +static WERROR cmd_srvsvc_net_file_get_sec(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + WERROR result; + NTSTATUS status; + struct sec_desc_buf *sd_buf = NULL; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc < 2 || argc > 4) { + printf("Usage: %s [sharename] [file]\n", argv[0]); + return WERR_OK; + } + + status = dcerpc_srvsvc_NetGetFileSecurity(b, mem_ctx, + cli->desthost, + argv[1], + argv[2], + SECINFO_DACL, + &sd_buf, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + display_sec_desc(sd_buf->sd); + + done: + return result; +} + +static WERROR cmd_srvsvc_net_sess_del(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + WERROR result; + NTSTATUS status; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc < 2 || argc > 4) { + printf("Usage: %s [client] [user]\n", argv[0]); + return WERR_OK; + } + + status = dcerpc_srvsvc_NetSessDel(b, mem_ctx, + cli->desthost, + argv[1], + argv[2], + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + done: + return result; +} + +static WERROR cmd_srvsvc_net_sess_enum(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + WERROR result; + NTSTATUS status; + struct srvsvc_NetSessInfoCtr info_ctr; + struct srvsvc_NetSessCtr0 ctr0; + struct srvsvc_NetSessCtr1 ctr1; + struct srvsvc_NetSessCtr2 ctr2; + struct srvsvc_NetSessCtr10 ctr10; + struct srvsvc_NetSessCtr502 ctr502; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + uint32_t *resume_handle_p = NULL; + uint32_t level = 1; + const char *client = NULL; + const char *user = NULL; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 6) { + printf("Usage: %s [client] [user] [level] [resume_handle]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + client = argv[1]; + } + + if (argc >= 3) { + user = argv[2]; + } + + if (argc >= 4) { + level = atoi(argv[3]); + } + + if (argc >= 5) { + resume_handle = atoi(argv[4]); + resume_handle_p = &resume_handle; + } + + ZERO_STRUCT(info_ctr); + + info_ctr.level = level; + + d_printf("trying level: %d\n", level); + + switch (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; + case 10: + ZERO_STRUCT(ctr10); + info_ctr.ctr.ctr10 = &ctr10; + break; + case 502: + ZERO_STRUCT(ctr502); + info_ctr.ctr.ctr502 = &ctr502; + break; + } + + status = dcerpc_srvsvc_NetSessEnum(b, mem_ctx, + cli->desthost, + client, + user, + &info_ctr, + 0xffffffff, + &total_entries, + resume_handle_p, + &result); + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + d_printf("Received %d entries.\n", total_entries); + + done: + return result; +} + +static WERROR cmd_srvsvc_net_disk_enum(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + struct srvsvc_NetDiskInfo info; + WERROR result; + NTSTATUS status; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + uint32_t level = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 4) { + printf("Usage: %s [level] [resume_handle]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + level = atoi(argv[1]); + } + + if (argc >= 3) { + resume_handle = atoi(argv[2]); + } + + ZERO_STRUCT(info); + + status = dcerpc_srvsvc_NetDiskEnum(b, mem_ctx, + cli->desthost, + level, + &info, + 0xffffffff, + &total_entries, + &resume_handle, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + done: + return result; +} + +static WERROR cmd_srvsvc_net_conn_enum(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + struct srvsvc_NetConnInfoCtr info_ctr; + struct srvsvc_NetConnCtr0 ctr0; + struct srvsvc_NetConnCtr1 ctr1; + WERROR result; + NTSTATUS status; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + uint32_t *resume_handle_p = NULL; + uint32_t level = 1; + const char *path = "IPC$"; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc > 4) { + printf("Usage: %s [level] [path] [resume_handle]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) { + level = atoi(argv[1]); + } + + if (argc >= 3) { + path = argv[2]; + } + + if (argc >= 4) { + resume_handle = atoi(argv[3]); + resume_handle_p = &resume_handle; + } + + ZERO_STRUCT(info_ctr); + + info_ctr.level = level; + + switch (level) { + case 0: + ZERO_STRUCT(ctr0); + info_ctr.ctr.ctr0 = &ctr0; + break; + case 1: + ZERO_STRUCT(ctr1); + info_ctr.ctr.ctr1 = &ctr1; + break; + default: + return WERR_INVALID_PARAMETER; + } + + status = dcerpc_srvsvc_NetConnEnum(b, mem_ctx, + cli->desthost, + path, + &info_ctr, + 0xffffffff, + &total_entries, + resume_handle_p, + &result); + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + done: + return result; +} + +static WERROR cmd_srvsvc_net_share_add(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + struct srvsvc_NetShareInfo502 info502 = { 0 }; + union srvsvc_NetShareInfo info = { .info502 = &info502 }; + WERROR result; + NTSTATUS status; + uint32_t max_users = -1, parm_error; + struct sec_desc_buf sd_buf = { 0 }; + const char *path, *share_name, *comment = NULL; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc < 3 || argc > 5) { + printf("Usage: %s path share_name [max_users] [comment]\n", + argv[0]); + return WERR_OK; + } + + path = argv[1]; + share_name = argv[2]; + + if (argc >= 4) { + max_users = atoi(argv[3]); + } + + if (argc >= 5) { + comment = argv[4]; + } + + info.info502->name = share_name; + info.info502->type = STYPE_DISKTREE; + info.info502->comment = comment; + info.info502->max_users = max_users; + info.info502->path = path; + info.info502->sd_buf = sd_buf; + + status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx, cli->desthost, + 502, &info, &parm_error, &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + + return result; +} + +static WERROR cmd_srvsvc_net_share_del(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + const char *share_name; + WERROR result; + NTSTATUS status; + struct dcerpc_binding_handle *b = cli->binding_handle; + + if (argc < 2) { + printf("Usage: %s share_name\n", argv[0]); + return WERR_OK; + } + + share_name = argv[1]; + + status = dcerpc_srvsvc_NetShareDel(b, mem_ctx, cli->desthost, + share_name, 0, &result); + + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + + return result; +} + + +/* List of commands exported by this module */ + +struct cmd_set srvsvc_commands[] = { + + { + .name = "SRVSVC", + }, + + { + .name = "srvinfo", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_srv_query_info, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Server query info", + .usage = "", + }, + { + .name = "netshareenum", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_enum, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Enumerate shares", + .usage = "", + }, + { + .name = "netshareenumall", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_enum_all, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Enumerate all shares", + .usage = "", + }, + { + .name = "netsharegetinfo", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_get_info, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Get Share Info", + .usage = "", + }, + { + .name = "netsharesetinfo", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_set_info, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Set Share Info", + .usage = "", + }, + { + .name = "netsharesetdfsflags", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_set_dfs_flags, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Set DFS flags", + .usage = "", + }, + { + .name = "netfileenum", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_file_enum, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Enumerate open files", + .usage = "", + }, + { + .name = "netremotetod", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_remote_tod, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Fetch remote time of day", + .usage = "", + }, + { + .name = "netnamevalidate", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_name_validate, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Validate sharename", + .usage = "", + }, + { + .name = "netfilegetsec", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_file_get_sec, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Get File security", + .usage = "", + }, + { + .name = "netsessdel", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_sess_del, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Delete Session", + .usage = "", + }, + { + .name = "netsessenum", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_sess_enum, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Enumerate Sessions", + .usage = "", + }, + { + .name = "netdiskenum", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_disk_enum, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Enumerate Disks", + .usage = "", + }, + { + .name = "netconnenum", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_conn_enum, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Enumerate Connections", + .usage = "", + }, + { + .name = "netshareadd", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_add, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Add share", + .usage = "", + }, + { + .name = "netsharedel", + .returntype = RPC_RTYPE_WERROR, + .ntfn = NULL, + .wfn = cmd_srvsvc_net_share_del, + .table = &ndr_table_srvsvc, + .rpc_pipe = NULL, + .description = "Delete share", + .usage = "", + }, + + { + .name = NULL, + } +}; -- cgit v1.2.3