summaryrefslogtreecommitdiffstats
path: root/source3/rpcclient/cmd_srvsvc.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /source3/rpcclient/cmd_srvsvc.c
parentInitial commit. (diff)
downloadsamba-4f5791ebd03eaec1c7da0865a383175b05102712.tar.xz
samba-4f5791ebd03eaec1c7da0865a383175b05102712.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source3/rpcclient/cmd_srvsvc.c')
-rw-r--r--source3/rpcclient/cmd_srvsvc.c1266
1 files changed, 1266 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+*/
+
+#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; i<ret->count; 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,
+ }
+};