[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Aug 28 00:04:02 UTC 2018


The branch, master has been updated
       via  ffa1c04 examples: Add winexe re-implemented on current Samba libs
       via  082f60a libsmb: Expose protocol-agnostic cli_writeall_send/recv
       via  fd20372 libsmb: Rename cli_writeall_send/recv to cli_smb1_writeall_send/recv
       via  a5c4d91 libsmb: Add protocol-agnostic cli_read
      from  4d72ebb s3: VFS: vfs_full_audit: Ensure smb_fname_str_do_log() only returns absolute pathnames.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ffa1c040c625336209a6310e234f5087dd62e984
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Apr 10 17:18:18 2018 +0200

    examples: Add winexe re-implemented on current Samba libs
    
    winexe from https://sourceforge.net/projects/winexe/ is a project
    based on Samba libraries from 2012. According to the winexe git
    repository the last Samba commit winexe was updated to is 47bbf9886f0c
    from November 6, 2012. As winexe uses unpublished Samba internal
    libraries, it broke over time.
    
    This is a port of the winexe functionality to more modern Samba
    versions. It still uses internal APIs, but it being part of the tree
    means that it is much easier to keep up to date.
    
    The Windows service files were taken literally from the original
    winexe from the sourceforge git. Andrzej Hajda chose GPLv3 only and
    not GPLv3+. As GPL evolves very slowly, this should not be a practical
    problem for quite some time.
    
    To build it under Linux, you need mingw binaries on your build
    system. Under Debian stretch, the package names are gcc-mingw-w64 and
    friends.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Aug 28 02:03:07 CEST 2018 on sn-devel-144

commit 082f60af26f1822c815e70c189aa42d54228e414
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 16:32:01 2018 +0200

    libsmb: Expose protocol-agnostic cli_writeall_send/recv
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit fd203725cab0b5b604a4ae8adccc084dfcad9639
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 16:19:52 2018 +0200

    libsmb: Rename cli_writeall_send/recv to cli_smb1_writeall_send/recv
    
    Preparing a protocol agnostic writeall
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a5c4d91ebf6527001a2cc8a316db931768ec8249
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 16:18:28 2018 +0200

    libsmb: Add protocol-agnostic cli_read
    
    So far only cli_pull could be called directly without looking at the
    protocol. We did not have a simple read that did the right thing
    depending on the protocol
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 examples/winexe/README        |   18 +
 examples/winexe/winexe.c      | 1867 +++++++++++++++++++++++++++++++++++++++++
 examples/winexe/winexesvc.c   |  745 ++++++++++++++++
 examples/winexe/winexesvc.h   |   42 +
 examples/winexe/wscript       |   29 +
 examples/winexe/wscript_build |   87 ++
 source3/libsmb/clireadwrite.c |  265 +++++-
 source3/libsmb/proto.h        |   19 +
 source3/wscript_build         |    1 +
 wscript                       |    1 +
 10 files changed, 3044 insertions(+), 30 deletions(-)
 create mode 100644 examples/winexe/README
 create mode 100644 examples/winexe/winexe.c
 create mode 100644 examples/winexe/winexesvc.c
 create mode 100644 examples/winexe/winexesvc.h
 create mode 100644 examples/winexe/wscript
 create mode 100644 examples/winexe/wscript_build


Changeset truncated at 500 lines:

diff --git a/examples/winexe/README b/examples/winexe/README
new file mode 100644
index 0000000..c688e5d
--- /dev/null
+++ b/examples/winexe/README
@@ -0,0 +1,18 @@
+winexe from https://sourceforge.net/projects/winexe/ is a project
+based on Samba libraries from 2012. According to the winexe git
+repository the last Samba commit winexe was updated to is 47bbf9886f0c
+from November 6, 2012. As winexe uses unpublished Samba internal
+libraries, it broke over time.
+
+This is a port of the winexe functionality to more modern Samba
+versions. It still uses internal APIs, but it being part of the tree
+means that it is much easier to keep up to date.
+
+The Windows service files were taken literally from the original
+winexe from the sourceforge git. Andrzej Hajda chose GPLv3 only and
+not GPLv3+. As GPL evolves very slowly, this should not be a practical
+problem for quite some time.
+
+To build it under Linux, you need mingw binaries on your build
+system. Under Debian stretch, the package names are gcc-mingw-w64 and
+friends.
diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c
new file mode 100644
index 0000000..cf667a6
--- /dev/null
+++ b/examples/winexe/winexe.c
@@ -0,0 +1,1867 @@
+/*
+ * Samba Unix/Linux CIFS implementation
+ *
+ * winexe
+ *
+ * Copyright (C) 2018 Volker Lendecke <vl at samba.org>
+ *
+ * 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 <tevent.h>
+#include <popt.h>
+#include "version.h"
+#include "lib/param/param.h"
+#include "auth/credentials/credentials.h"
+#include "lib/util/talloc_stack.h"
+#include "lib/util/tevent_ntstatus.h"
+#include "lib/util/sys_rw.h"
+#include "libsmb/proto.h"
+#include "librpc/gen_ndr/ndr_svcctl_c.h"
+#include "rpc_client/cli_pipe.h"
+#include "libcli/smb/smbXcli_base.h"
+#include "libcli/util/werror.h"
+#include "lib/async_req/async_sock.h"
+#include "client.h"
+
+#define SVC_INTERACTIVE 1
+#define SVC_IGNORE_INTERACTIVE 2
+#define SVC_INTERACTIVE_MASK 3
+#define SVC_FORCE_UPLOAD 4
+#define SVC_OS64BIT 8
+#define SVC_OSCHOOSE 16
+#define SVC_UNINSTALL 32
+#define SVC_SYSTEM 64
+
+#define SERVICE_NAME "winexesvc"
+
+#define PIPE_NAME "ahexec"
+#define PIPE_NAME_IN "ahexec_stdin%08X"
+#define PIPE_NAME_OUT "ahexec_stdout%08X"
+#define PIPE_NAME_ERR "ahexec_stderr%08X"
+
+static const char version_message_fmt[] = "winexe version %d.%d\n"
+	"This program may be freely redistributed under the terms of the "
+	"GNU GPLv3\n";
+
+struct program_options {
+	char *hostname;
+	char *cmd;
+	struct cli_credentials *credentials;
+	char *runas;
+	char *runas_file;
+	int flags;
+};
+
+static void parse_args(int argc, const char *argv[],
+		       TALLOC_CTX *mem_ctx,
+		       struct program_options *options,
+		       struct loadparm_context *lp_ctx)
+{
+	poptContext pc;
+	int opt, i;
+	struct cli_credentials *cred;
+
+	int argc_new;
+	char **argv_new;
+
+	int flag_interactive = SVC_IGNORE_INTERACTIVE;
+	int flag_ostype = 2;
+	int flag_reinstall = 0;
+	int flag_uninstall = 0;
+	int flag_help = 0;
+	int flag_version = 0;
+	int flag_nopass = 0;
+	char *opt_user = NULL;
+	char *opt_kerberos = NULL;
+	char *opt_auth_file = NULL;
+	char *opt_debuglevel = NULL;
+
+	struct poptOption long_options[] = {
+		{ "help", 'h', POPT_ARG_NONE, &flag_help, 0,
+		  "Display help message" },
+		{ "version", 'V', POPT_ARG_NONE, &flag_version, 0,
+		  "Display version number" },
+		{ "user", 'U', POPT_ARG_STRING, &opt_user, 0,
+		  "Set the network username", "[DOMAIN/]USERNAME[%PASSWORD]" },
+		{ "authentication-file", 'A',
+		  POPT_ARG_STRING, &opt_auth_file, 0,
+		  "Get the credentials from a file", "FILE" },
+		{ "no-pass", 'N', POPT_ARG_NONE, &flag_nopass, 0,
+		  "Do not ask for a password", NULL },
+		{ "kerberos", 'k', POPT_ARG_STRING, &opt_kerberos, 0,
+		  "Use Kerberos, -k [yes|no]" },
+		{ "debuglevel", 'd', POPT_ARG_STRING, &opt_debuglevel, 0,
+		  "Set debug level", "DEBUGLEVEL" },
+		{ "uninstall", 0, POPT_ARG_NONE, &flag_uninstall, 0,
+		  "Uninstall winexe service after remote execution", NULL},
+		{ "reinstall", 0, POPT_ARG_NONE, &flag_reinstall, 0,
+		  "Reinstall winexe service before remote execution", NULL},
+		{ "runas", 0, POPT_ARG_STRING, &options->runas, 0,
+		  "Run as the given user (BEWARE: this password is sent "
+		  "in cleartext over the network!)",
+		  "[DOMAIN\\]USERNAME%PASSWORD"},
+		{ "runas-file", 0, POPT_ARG_STRING, &options->runas_file, 0,
+		  "Run as user options defined in a file", "FILE"},
+		{ "interactive", 0, POPT_ARG_INT, &flag_interactive, 0,
+		  "Desktop interaction: 0 - disallow, 1 - allow. If allow, "
+		  "also use the --system switch (Windows requirement). Vista "
+		  "does not support this option.", "0|1"},
+		{ "ostype", 0, POPT_ARG_INT, &flag_ostype, 0,
+		  "OS type: 0 - 32-bit, 1 - 64-bit, 2 - winexe will decide. "
+		  "Determines which version (32-bit or 64-bit) of service "
+		  "will be installed.", "0|1|2"},
+		POPT_TABLEEND
+	};
+
+	ZERO_STRUCTP(options);
+
+	pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,
+			    0);
+
+	poptSetOtherOptionHelp(pc, "[OPTION]... //HOST COMMAND\nOptions:");
+
+	if (((opt = poptGetNextOpt(pc)) != -1) || flag_help || flag_version) {
+		fprintf(stderr, version_message_fmt, SAMBA_VERSION_MAJOR,
+			SAMBA_VERSION_MINOR);
+		if (flag_version) {
+			exit(0);
+		}
+		poptPrintHelp(pc, stdout, 0);
+		if (flag_help) {
+			exit(0);
+		}
+		exit(1);
+	}
+
+	argv_new = discard_const_p(char *, poptGetArgs(pc));
+
+	argc_new = argc;
+	for (i = 0; i < argc; i++) {
+		if (!argv_new || argv_new[i] == NULL) {
+			argc_new = i;
+			break;
+		}
+	}
+
+	if (argc_new != 2 || argv_new[0][0] != '/' || argv_new[0][1] != '/') {
+		fprintf(stderr, version_message_fmt, SAMBA_VERSION_MAJOR,
+			SAMBA_VERSION_MINOR);
+		poptPrintHelp(pc, stdout, 0);
+		exit(1);
+	}
+
+	if (opt_debuglevel) {
+		lp_set_cmdline("log level", opt_debuglevel);
+	}
+
+	cred = cli_credentials_init(mem_ctx);
+
+	if (opt_user) {
+		cli_credentials_parse_string(cred, opt_user, CRED_SPECIFIED);
+	} else if (opt_auth_file) {
+		cli_credentials_parse_file(cred, opt_auth_file,
+					   CRED_SPECIFIED);
+	}
+
+	cli_credentials_guess(cred, lp_ctx);
+	if (!cli_credentials_get_password(cred) && !flag_nopass) {
+		char *p = getpass("Enter password: ");
+		if (*p) {
+			cli_credentials_set_password(cred, p, CRED_SPECIFIED);
+		}
+	}
+
+	if (opt_kerberos) {
+		cli_credentials_set_kerberos_state(cred,
+		                                   strcmp(opt_kerberos, "yes")
+		                                   ? CRED_MUST_USE_KERBEROS
+		                                   : CRED_DONT_USE_KERBEROS);
+	}
+
+	if (options->runas == NULL && options->runas_file != NULL) {
+		struct cli_credentials *runas_cred;
+		const char *user;
+		const char *pass;
+
+		runas_cred = cli_credentials_init(mem_ctx);
+		cli_credentials_parse_file(runas_cred, options->runas_file,
+					   CRED_SPECIFIED);
+
+		user = cli_credentials_get_username(runas_cred);
+		pass = cli_credentials_get_password(runas_cred);
+
+		if (user && pass) {
+			char buffer[1024];
+			const char *dom;
+
+			dom = cli_credentials_get_domain(runas_cred);
+			if (dom) {
+				snprintf(buffer, sizeof(buffer), "%s\\%s%%%s",
+					 dom, user, pass);
+			} else {
+				snprintf(buffer, sizeof(buffer), "%s%%%s",
+					 user, pass);
+			}
+			buffer[sizeof(buffer)-1] = '\0';
+			options->runas = talloc_strdup(mem_ctx, buffer);
+		}
+	}
+
+	options->credentials = cred;
+
+	options->hostname = argv_new[0] + 2;
+	options->cmd = argv_new[1];
+
+	options->flags = flag_interactive;
+	if (flag_reinstall) {
+		options->flags |= SVC_FORCE_UPLOAD;
+	}
+	if (flag_ostype == 1) {
+		options->flags |= SVC_OS64BIT;
+	}
+	if (flag_ostype == 2) {
+		options->flags |= SVC_OSCHOOSE;
+	}
+	if (flag_uninstall) {
+		options->flags |= SVC_UNINSTALL;
+	}
+}
+
+static NTSTATUS winexe_svc_upload(
+	const char *hostname,
+	const char *service_filename,
+	const DATA_BLOB *svc32_exe,
+	const DATA_BLOB *svc64_exe,
+	struct cli_credentials *credentials,
+	int flags)
+{
+	struct cli_state *cli;
+	uint16_t fnum;
+	NTSTATUS status;
+	const DATA_BLOB *binary = NULL;
+
+	status = cli_full_connection_creds(
+		&cli,
+		NULL,
+		hostname,
+		NULL,
+		445,
+		"ADMIN$",
+		"?????",
+		credentials,
+		0,
+		0);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("cli_full_connection_creds failed: %s\n",
+			    nt_errstr(status));
+		return status;
+	}
+
+	if (flags & SVC_FORCE_UPLOAD) {
+		status = cli_unlink(cli, service_filename, 0);
+		if (!NT_STATUS_IS_OK(status)) {
+			DBG_WARNING("cli_unlink failed: %s\n",
+				    nt_errstr(status));
+		}
+	}
+
+	if (flags & SVC_OSCHOOSE) {
+		status = cli_chkpath(cli, "SysWoW64");
+		if (NT_STATUS_IS_OK(status)) {
+			flags |= SVC_OS64BIT;
+		}
+	}
+
+	if (flags & SVC_OS64BIT) {
+		binary = svc64_exe;
+	} else {
+		binary = svc32_exe;
+	}
+
+	if (binary == NULL) {
+		//TODO
+	}
+
+	status = cli_ntcreate(
+		cli,
+		service_filename,
+		0,			/* CreatFlags */
+		SEC_FILE_WRITE_DATA,    /* DesiredAccess */
+		FILE_ATTRIBUTE_NORMAL,  /* FileAttributes */
+		FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
+		FILE_OPEN_IF,		 /* CreateDisposition */
+		FILE_NON_DIRECTORY_FILE, /* CreateOptions */
+		0,			 /* SecurityFlags */
+		&fnum,
+		NULL);		/* CreateReturns */
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("Could not create %s: %s\n", service_filename,
+			    nt_errstr(status));
+		goto done;
+	}
+
+	status = cli_writeall(
+		cli,
+		fnum,
+		0,
+		binary->data,
+		0,
+		binary->length,
+		NULL);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("Could not write file: %s\n", nt_errstr(status));
+		goto close_done;
+	}
+
+close_done:
+	status = cli_close(cli, fnum);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("Close(%"PRIu16") failed for %s: %s\n", fnum,
+			    service_filename, nt_errstr(status));
+	}
+done:
+	TALLOC_FREE(cli);
+	return status;
+}
+
+static NTSTATUS winexe_svc_install(
+	struct cli_state *cli,
+	const char *hostname,
+	const char *service_name,
+	const char *service_filename,
+	const DATA_BLOB *svc32_exe,
+	const DATA_BLOB *svc64_exe,
+	struct cli_credentials *credentials,
+	int flags)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct rpc_pipe_client *rpccli;
+	struct policy_handle scmanager_handle;
+	struct policy_handle service_handle;
+	struct SERVICE_STATUS service_status;
+	bool need_start = false;
+	bool need_conf = false;
+	NTSTATUS status;
+	WERROR werr;
+
+	status = cli_rpc_pipe_open_noauth_transport(
+		cli,
+		NCACN_NP,
+		&ndr_table_svcctl,
+		&rpccli);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("cli_rpc_pipe_open_noauth_transport failed: %s\n",
+			    nt_errstr(status));
+		goto done;
+	}
+
+	status = dcerpc_svcctl_OpenSCManagerW(
+		rpccli->binding_handle,
+		frame,
+		smbXcli_conn_remote_name(cli->conn),
+		NULL,
+		SEC_FLAG_MAXIMUM_ALLOWED,
+		&scmanager_handle,
+		&werr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("dcerpc_svcctl_OpenSCManagerW failed: %s\n",
+			    nt_errstr(status));
+		goto done;
+	}
+	if (!W_ERROR_IS_OK(werr)) {
+		DBG_WARNING("dcerpc_svcctl_OpenSCManagerW failed: %s\n",
+			    win_errstr(werr));
+		goto done;
+	}
+
+	status = dcerpc_svcctl_OpenServiceW(
+		rpccli->binding_handle,
+		frame,
+		&scmanager_handle,
+		service_name,
+		SERVICE_ALL_ACCESS,
+		&service_handle,
+		&werr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("dcerpc_svcctl_OpenServiceW failed: %s\n",
+			    nt_errstr(status));
+		goto close_scmanager;
+	}
+
+	if (W_ERROR_EQUAL(werr,  WERR_SERVICE_DOES_NOT_EXIST)) {
+		status = dcerpc_svcctl_CreateServiceW(
+			rpccli->binding_handle,
+			frame,
+			&scmanager_handle,
+			service_name,
+			NULL,
+			SERVICE_ALL_ACCESS,
+			SERVICE_TYPE_WIN32_OWN_PROCESS |
+			((flags & SVC_INTERACTIVE) ?
+			 SERVICE_TYPE_INTERACTIVE_PROCESS : 0),
+			SVCCTL_DEMAND_START,
+			SVCCTL_SVC_ERROR_NORMAL,
+			service_filename,
+			NULL,
+			NULL,
+			NULL,
+			0,
+			NULL,
+			NULL,
+			0,
+			&service_handle,
+			&werr);
+		if (!NT_STATUS_IS_OK(status)) {
+			DBG_WARNING("dcerpc_svcctl_CreateServiceW "
+				    "failed: %s\n", nt_errstr(status));
+			goto close_scmanager;
+		}
+		if (!W_ERROR_IS_OK(werr)) {
+			DBG_WARNING("dcerpc_svcctl_CreateServiceW "
+				    "failed: %s\n", win_errstr(werr));
+			status = werror_to_ntstatus(werr);
+			goto close_scmanager;
+		}
+	}
+
+	status = dcerpc_svcctl_QueryServiceStatus(
+		rpccli->binding_handle,
+		frame,
+		&service_handle,
+		&service_status,
+		&werr);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_WARNING("dcerpc_svcctl_QueryServiceStatus "
+			    "failed: %s\n", nt_errstr(status));
+		goto close_service;
+	}
+	if (!W_ERROR_IS_OK(werr)) {
+		DBG_WARNING("dcerpc_svcctl_QueryServiceStatus "
+			    "failed: %s\n", win_errstr(werr));
+		status = werror_to_ntstatus(werr);
+		goto close_service;
+	}
+
+	if (!(flags & SVC_IGNORE_INTERACTIVE)) {
+		need_conf =
+			!(service_status.type &
+			  SERVICE_TYPE_INTERACTIVE_PROCESS) ^
+			!(flags & SVC_INTERACTIVE);
+	}
+
+	if (service_status.state == SVCCTL_STOPPED) {
+		need_start = true;
+	} else if (need_conf) {
+		status = dcerpc_svcctl_ControlService(
+			rpccli->binding_handle,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list