The branch, v4-12-test has been updated via f50790c1be7 nmblib: avoid undefined behaviour in handle_name_ptrs() via 8b86109e5de vfs_recycle: prevent flooding the log if we're called on non-existant paths via 1d226313e03 librpc: fix IDL for svcctl_ChangeServiceConfigW via ea4603fd5e5 s4-torture: add ndr svcctl testsuite via ea15a4bd189 s4-torture: add rpc test for ChangeServiceConfigW via b0f590055c1 VFS: default: add support for FILE_ATTRIBUTE_OFFLINE to async dosmode via 34f3476d560 VFS: default: use correct type for pathlen in vfswrap_getxattrat_do_sync() via cfaca1c0b7a VFS: default: avoid a crash in vfswrap_getxattrat_do_sync() via 69e66865203 VFS: default: remove unused arg from vfswrap_is_offline() via 8f4e8be8554 VFS: default: let vfswrap_is_offline() take conn, not handle via e98dcaa16d0 smbd: ignore set NTACL requests which contain S-1-5-88 NFS ACEs via b8ef341f6b5 vfs_fruit: tmsize prevent overflow Force the type during arithmetic in order to prevent overflow when summing the Time Machine folder size. Increase the precision to off_t (used for file sizes), leave the overflow error traps but with more precise wording. from fdc2f7d218a VERSION: Bump version up to 4.12.1...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-12-test - Log ----------------------------------------------------------------- commit f50790c1be70af62cb2d0231cc05bdf59344b4c1 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Sun Jan 19 15:08:58 2020 +1300 nmblib: avoid undefined behaviour in handle_name_ptrs() If *offset is length - 1, we would read ubuf[(*offset)+1] as the lower bits of the new *offset. This value is undefined, but because it is checked against the valid range, there is no way to read further beyond that one byte. Credit to oss-fuzz. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14242 OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20193 Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Fri Feb 7 10:19:39 UTC 2020 on sn-devel-184 (cherry picked from commit 3bc7acc62646b105b03fd3c65e9170a373f95392) Autobuild-User(v4-12-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-12-test): Wed Mar 18 12:26:06 UTC 2020 on sn-devel-184 commit 8b86109e5deca6b19883828ff02b4cf19e751641 Author: Ralph Boehme <s...@samba.org> Date: Fri Mar 6 12:22:25 2020 +0100 vfs_recycle: prevent flooding the log if we're called on non-existant paths vfs_recycle is assuming that any path passed to unlink must exist, otherwise it logs this error. Turn this into a DEBUG level message. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14316 See also: https://bugzilla.redhat.com/show_bug.cgi?id=1780802 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Isaac Boukris <ibouk...@samba.org> Autobuild-User(master): Isaac Boukris <ibouk...@samba.org> Autobuild-Date(master): Mon Mar 9 14:15:06 UTC 2020 on sn-devel-184 commit 1d226313e0393e7d1e712c990fe2e1d4db26fe71 Author: Günther Deschner <g...@samba.org> Date: Wed Mar 4 15:23:43 2020 +0100 librpc: fix IDL for svcctl_ChangeServiceConfigW Found while trying to run winexe against Windows Server 2019. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14313 Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> (cherry picked from commit ebda529b59105e9b70cc74377fe4d54cc16b4f37) commit ea4603fd5e58d589034772b173a3a518133faa69 Author: Günther Deschner <g...@samba.org> Date: Thu Mar 5 20:42:21 2020 +0100 s4-torture: add ndr svcctl testsuite BUG: https://bugzilla.samba.org/show_bug.cgi?id=14313 Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> (cherry picked from commit c3fa0b2df9fc53dddcc3160b6a3dc751bbb389a4) commit ea15a4bd1896e5ef1e07738bd46387d9f9bfcdbe Author: Günther Deschner <g...@samba.org> Date: Thu Mar 5 22:45:48 2020 +0100 s4-torture: add rpc test for ChangeServiceConfigW BUG: https://bugzilla.samba.org/show_bug.cgi?id=14313 Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> (cherry picked from commit 0825324bc75d2ab10164a1f137be782d84c822b8) commit b0f590055c1642686145154203207b942988608b Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 24 15:03:56 2020 +0100 VFS: default: add support for FILE_ATTRIBUTE_OFFLINE to async dosmode This had been missing in the initial async dosmode implementation. It's the responsibility of the sync and async dosmode functions to call vfswrap_is_offline() since the offline functionality has been converted from a first class VFS function to be a part of the DOS attributes VFS functions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14293 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit a23f8d913fa8d77bab394aea9a8e7df2704e8b19) commit 34f3476d560b743f800bda69338e0c876846e680 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 24 14:30:37 2020 +0100 VFS: default: use correct type for pathlen in vfswrap_getxattrat_do_sync() full_path_tos() returns a ssize_t. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14293 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit ace296b97642d9160ea66db89dcd0f24a21dba4e) commit cfaca1c0b7a7f7d7e0b688b21846a9a9d1968cd8 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 24 14:29:01 2020 +0100 VFS: default: avoid a crash in vfswrap_getxattrat_do_sync() Must use tevent_req_data() to get our tevent_req state, talloc_get_type_abort() will just crash as struct tevent_req != struct vfswrap_getxattrat_state. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14293 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit cbca811212a930b94f9917e5a82b6a95ab085e91) commit 69e66865203ac1b6dc7fe2eb109f0ee7b5745fc9 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 24 14:28:19 2020 +0100 VFS: default: remove unused arg from vfswrap_is_offline() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14293 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 99873724cd493366c9957fd9fe230d52a6f02691) commit 8f4e8be85547427cf6a3969d1738d1ed68ee195e Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 24 14:24:12 2020 +0100 VFS: default: let vfswrap_is_offline() take conn, not handle vfswrap_is_offline() has been converted to a "helper" function some time ago, it had been a VFS interface function before. To make this change more obvious let it take a struct connection_struct instead of a struct vfs_handle_struct which is the canonical first parameter to VFS functions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14293 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit d4c69d82bdc0fa029609032a9d32f32fa1708beb) commit e98dcaa16d0943e44fad96868777f08dde023be1 Author: Ralph Boehme <s...@samba.org> Date: Thu Feb 27 17:01:10 2020 +0100 smbd: ignore set NTACL requests which contain S-1-5-88 NFS ACEs We apply the same "ignore" logic already in the POSIX ACL code and in the vfs_acl_xattr|tdb VFS modules to smb_set_nt_acl_nfs4() in the nfs4_acl helper subsystem which is common to a bunch of VFS modules: GPFS, ZFS, NFS4_xattr and aixacl2. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14307 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Mar 3 19:15:10 UTC 2020 on sn-devel-184 (cherry picked from commit f89c7ad851681c0e0ab39a1bedb3eeb672516fbb) commit b8ef341f6b537ce23262ca191f4f55a6508a0854 Author: Art M. Gallagher <re...@artmg.net> Date: Tue Mar 3 21:51:46 2020 +0000 vfs_fruit: tmsize prevent overflow Force the type during arithmetic in order to prevent overflow when summing the Time Machine folder size. Increase the precision to off_t (used for file sizes), leave the overflow error traps but with more precise wording. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13622 Signed-off-by: Art M. Gallagher <smbl...@artmg.org> Reviewed-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Sat Mar 7 01:37:31 UTC 2020 on sn-devel-184 (cherry picked from commit b0ba7cd4f96a6ea227943cb05ef51a463e292b2d) ----------------------------------------------------------------------- Summary of changes: examples/winexe/winexe.c | 2 + librpc/idl/svcctl.idl | 25 +++++++++--- selftest/knownfail | 3 ++ source3/libsmb/nmblib.c | 3 ++ source3/modules/nfs4_acls.c | 4 ++ source3/modules/vfs_default.c | 49 ++++++++++++++++++------ source3/modules/vfs_fruit.c | 12 ++++-- source3/modules/vfs_recycle.c | 4 +- source4/torture/ndr/ndr.c | 1 + source4/torture/ndr/svcctl.c | 88 +++++++++++++++++++++++++++++++++++++++++++ source4/torture/rpc/svcctl.c | 81 ++++++++++++++++++++++++++++++++++++++- source4/torture/wscript_build | 1 + 12 files changed, 250 insertions(+), 23 deletions(-) create mode 100644 source4/torture/ndr/svcctl.c Changeset truncated at 500 lines: diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c index 22f748b1d45..fc6b15f8e52 100644 --- a/examples/winexe/winexe.c +++ b/examples/winexe/winexe.c @@ -625,8 +625,10 @@ static NTSTATUS winexe_svc_install( NULL, /* load_order_group */ NULL, /* tag_id */ NULL, /* dependencies */ + 0, /* dwDependSize */ NULL, /* service_start_name */ NULL, /* password */ + 0, /* dwPwSize */ NULL, /* display_name */ &werr); diff --git a/librpc/idl/svcctl.idl b/librpc/idl/svcctl.idl index 671a1dc47be..a9dd3dec990 100644 --- a/librpc/idl/svcctl.idl +++ b/librpc/idl/svcctl.idl @@ -13,6 +13,17 @@ import "misc.idl", "security.idl"; helpstring("Service Control") ] interface svcctl { + const int MAX_SERVICE_NAME_LENGTH = 256; + const short SC_MAX_DEPEND_SIZE = 4 * 1024; + const short SC_MAX_NAME_LENGTH = MAX_SERVICE_NAME_LENGTH + 1; + const short SC_MAX_PATH_LENGTH = 32 * 1024; + const short SC_MAX_PWD_SIZE = 514; + const short SC_MAX_COMPUTER_NAME_LENGTH = 1024; + const short SC_MAX_ACCOUNT_NAME_LENGTH = 2 * 1024; + const short SC_MAX_COMMENT_LENGTH = 128; + const short SC_MAX_ARGUMENT_LENGTH = 1024; + const short SC_MAX_ARGUMENTS = 1024; + typedef struct { uint32 is_locked; [string,charset(UTF16)] uint16 *lock_owner; @@ -188,18 +199,20 @@ import "misc.idl", "security.idl"; SVCCTL_DISABLED = 0x00000004 } svcctl_StartType; - WERROR svcctl_ChangeServiceConfigW( + [public] WERROR svcctl_ChangeServiceConfigW( [in,ref] policy_handle *handle, [in] uint32 type, [in] svcctl_StartType start_type, [in] svcctl_ErrorControl error_control, [in,unique] [string,charset(UTF16)] uint16 *binary_path, [in,unique] [string,charset(UTF16)] uint16 *load_order_group, - [out,ref] uint32 *tag_id, - [in,unique] [string,charset(UTF16)] uint16 *dependencies, - [in,unique] [string,charset(UTF16)] uint16 *service_start_name, - [in,unique] [string,charset(UTF16)] uint16 *password, - [in,unique] [string,charset(UTF16)] uint16 *display_name + [in,out,unique] uint32 *tag_id, + [in,unique,size_is(dwDependSize)] [string,charset(UTF16)] uint16 *dependencies, + [in,range(0, SC_MAX_DEPEND_SIZE)] uint32 dwDependSize, + [in,unique,range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] [string,charset(UTF16)] uint16 *service_start_name, + [in,unique,size_is(dwPwSize)] [string,charset(UTF16)] uint16 *password, + [in,range(0, SC_MAX_PWD_SIZE)] uint32 dwPwSize, + [in,unique,range(0, SC_MAX_NAME_LENGTH)] [string,charset(UTF16)] uint16 *display_name ); /*****************/ diff --git a/selftest/knownfail b/selftest/knownfail index c9ef0851172..20441c078b4 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -234,6 +234,9 @@ ^samba3.rpc.eventlog.eventlog.GetNumRecords\(ad_dc\) ^samba3.rpc.eventlog.eventlog.OpenEventLog\(ad_dc\) ^samba3.rap.basic.netsessiongetinfo\(ad_dc\) +# not implemented +^samba3.rpc.svcctl.svcctl.ChangeServiceConfigW\(ad_dc\) +^samba3.rpc.svcctl.svcctl.ChangeServiceConfigW\(nt4_dc\) # # This makes less sense when not running against an AD DC # diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 84cbb054b8e..c05fac2bba9 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -160,6 +160,9 @@ static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length, if (!*got_pointer) (*ret) += 2; (*got_pointer)=True; + if (*offset > length - 2) { + return False; + } (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 4d50223c795..7f32e681694 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -996,6 +996,10 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, * refined... */ } + if (security_descriptor_with_ms_nfs(psd)) { + return NT_STATUS_OK; + } + if (pparams == NULL) { /* Special behaviours */ if (smbacl4_get_vfs_params(fsp->conn, ¶ms)) { diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 37b59d8c3c0..a30f3ba1d31 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1638,9 +1638,8 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle, return NT_STATUS_NOT_SUPPORTED; } -static bool vfswrap_is_offline(struct vfs_handle_struct *handle, - const struct smb_filename *fname, - SMB_STRUCT_STAT *sbuf); +static bool vfswrap_is_offline(struct connection_struct *conn, + const struct smb_filename *fname); static NTSTATUS vfswrap_get_dos_attributes(struct vfs_handle_struct *handle, struct smb_filename *smb_fname, @@ -1648,7 +1647,7 @@ static NTSTATUS vfswrap_get_dos_attributes(struct vfs_handle_struct *handle, { bool offline; - offline = vfswrap_is_offline(handle, smb_fname, &smb_fname->st); + offline = vfswrap_is_offline(handle->conn, smb_fname); if (offline) { *dosmode |= FILE_ATTRIBUTE_OFFLINE; } @@ -1720,6 +1719,12 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq) struct vfswrap_get_dos_attributes_state); ssize_t xattr_size; DATA_BLOB blob = {0}; + char *path = NULL; + char *tofree = NULL; + char pathbuf[PATH_MAX+1]; + ssize_t pathlen; + struct smb_filename smb_fname; + bool offline; NTSTATUS status; xattr_size = SMB_VFS_GETXATTRAT_RECV(subreq, @@ -1768,6 +1773,29 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq) return; } + pathlen = full_path_tos(state->dir_fsp->fsp_name->base_name, + state->smb_fname->base_name, + pathbuf, + sizeof(pathbuf), + &path, + &tofree); + if (pathlen == -1) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + + smb_fname = (struct smb_filename) { + .base_name = path, + .st = state->smb_fname->st, + .flags = state->smb_fname->flags, + }; + + offline = vfswrap_is_offline(state->conn, &smb_fname); + if (offline) { + state->dosmode |= FILE_ATTRIBUTE_OFFLINE; + } + TALLOC_FREE(tofree); + tevent_req_done(req); return; } @@ -1798,7 +1826,7 @@ static NTSTATUS vfswrap_fget_dos_attributes(struct vfs_handle_struct *handle, { bool offline; - offline = vfswrap_is_offline(handle, fsp->fsp_name, &fsp->fsp_name->st); + offline = vfswrap_is_offline(handle->conn, fsp->fsp_name); if (offline) { *dosmode |= FILE_ATTRIBUTE_OFFLINE; } @@ -3326,12 +3354,12 @@ static struct tevent_req *vfswrap_getxattrat_send( static void vfswrap_getxattrat_do_sync(struct tevent_req *req) { - struct vfswrap_getxattrat_state *state = talloc_get_type_abort( + struct vfswrap_getxattrat_state *state = tevent_req_data( req, struct vfswrap_getxattrat_state); char *path = NULL; char *tofree = NULL; char pathbuf[PATH_MAX+1]; - size_t pathlen; + ssize_t pathlen; int err; pathlen = full_path_tos(state->dir_fsp->fsp_name->base_name, @@ -3543,9 +3571,8 @@ static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_str return false; } -static bool vfswrap_is_offline(struct vfs_handle_struct *handle, - const struct smb_filename *fname, - SMB_STRUCT_STAT *sbuf) +static bool vfswrap_is_offline(struct connection_struct *conn, + const struct smb_filename *fname) { NTSTATUS status; char *path; @@ -3555,7 +3582,7 @@ static bool vfswrap_is_offline(struct vfs_handle_struct *handle, return false; } - if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) { + if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) { #if defined(ENOTSUP) errno = ENOTSUP; #endif diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index ebf3e18af2f..b2d0901a800 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -4986,15 +4986,21 @@ static bool fruit_tmsize_do_dirent(vfs_handle_struct *handle, return true; } + /* + * Arithmetic on 32-bit systems may cause overflow, depending on + * size_t precision. First we check its unlikely, then we + * force the precision into target off_t, then we check that + * the total did not overflow either. + */ if (bandsize > SIZE_MAX/nbands) { - DBG_ERR("tmsize overflow: bandsize [%zu] nbands [%zu]\n", + DBG_ERR("tmsize potential overflow: bandsize [%zu] nbands [%zu]\n", bandsize, nbands); return false; } - tm_size = bandsize * nbands; + tm_size = (off_t)bandsize * (off_t)nbands; if (state->total_size + tm_size < state->total_size) { - DBG_ERR("tmsize overflow: bandsize [%zu] nbands [%zu]\n", + DBG_ERR("tm total size overflow: bandsize [%zu] nbands [%zu]\n", bandsize, nbands); return false; } diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index a1d32bf10cb..ab1e6aa4dcf 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -236,8 +236,8 @@ static off_t recycle_get_file_size(vfs_handle_struct *handle, } if (SMB_VFS_STAT(handle->conn, smb_fname_tmp) != 0) { - DEBUG(0,("recycle: stat for %s returned %s\n", - smb_fname_str_dbg(smb_fname_tmp), strerror(errno))); + DBG_DEBUG("stat for %s returned %s\n", + smb_fname_str_dbg(smb_fname_tmp), strerror(errno)); size = (off_t)0; goto out; } diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c index 32efe90757d..690301f31b1 100644 --- a/source4/torture/ndr/ndr.c +++ b/source4/torture/ndr/ndr.c @@ -708,6 +708,7 @@ struct torture_suite *torture_local_ndr(TALLOC_CTX *mem_ctx) torture_suite_add_suite(suite, ndr_krb5pac_suite(suite)); torture_suite_add_suite(suite, ndr_cabinet_suite(suite)); torture_suite_add_suite(suite, ndr_charset_suite(suite)); + torture_suite_add_suite(suite, ndr_svcctl_suite(suite)); torture_suite_add_simple_test(suite, "string terminator", test_check_string_terminator); diff --git a/source4/torture/ndr/svcctl.c b/source4/torture/ndr/svcctl.c new file mode 100644 index 00000000000..6592beda02e --- /dev/null +++ b/source4/torture/ndr/svcctl.c @@ -0,0 +1,88 @@ +/* + Unix SMB/CIFS implementation. + test suite for svcctl ndr operations + + Copyright (C) Guenther Deschner 2020 + + 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 "torture/ndr/ndr.h" +#include "librpc/gen_ndr/ndr_svcctl.h" +#include "torture/ndr/proto.h" +#include "param/param.h" + +static const uint8_t svcctl_ChangeServiceConfigW_req_data[] = { + 0x00, 0x00, 0x00, 0x00, 0xcd, 0x94, 0x05, 0x40, 0x30, 0x28, 0x00, 0x49, + 0x8d, 0xe4, 0x8e, 0x85, 0xb7, 0x19, 0x5c, 0x83, 0x10, 0x01, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static bool svcctl_ChangeServiceConfigW_req_check(struct torture_context *tctx, + struct svcctl_ChangeServiceConfigW *r) +{ + struct policy_handle handle = { 0 }; + GUID_from_string("400594cd-2830-4900-8de4-8e85b7195c83", &handle.uuid); + + torture_assert_guid_equal(tctx, r->in.handle->uuid, handle.uuid, "handle"); + torture_assert_u32_equal(tctx, r->in.type, 0x00000110, "type"); + torture_assert_u32_equal(tctx, r->in.start_type, SVCCTL_AUTO_START, "start_type"); + torture_assert_u32_equal(tctx, r->in.error_control, SVCCTL_SVC_ERROR_NORMAL, "error_control"); + torture_assert_str_equal(tctx, r->in.binary_path, NULL, "binary_path"); + torture_assert_str_equal(tctx, r->in.load_order_group, NULL, "load_order_group"); + torture_assert(tctx, r->in.tag_id == NULL, "tag_id"); + torture_assert_str_equal(tctx, r->in.dependencies, NULL, "dependencies"); + torture_assert_u32_equal(tctx, r->in.dwDependSize, 0, "dwDependSize"); + torture_assert_str_equal(tctx, r->in.service_start_name, NULL, "service_start_name"); + torture_assert_str_equal(tctx, r->in.password, NULL, "password"); + torture_assert_u32_equal(tctx, r->in.dwPwSize, 0, "dwPwSize"); + torture_assert_str_equal(tctx, r->in.display_name, NULL, "display_name"); + + return true; +} + +static const uint8_t svcctl_ChangeServiceConfigW_rep_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static bool svcctl_ChangeServiceConfigW_rep_check(struct torture_context *tctx, + struct svcctl_ChangeServiceConfigW *r) +{ + torture_assert(tctx, r->out.tag_id == NULL, "tag_id"); + torture_assert_werr_ok(tctx, r->out.result, "result"); + + return true; +} + +struct torture_suite *ndr_svcctl_suite(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "svcctl"); + + torture_suite_add_ndr_pull_fn_test(suite, + svcctl_ChangeServiceConfigW, + svcctl_ChangeServiceConfigW_req_data, + NDR_IN, + svcctl_ChangeServiceConfigW_req_check); + + torture_suite_add_ndr_pull_fn_test(suite, + svcctl_ChangeServiceConfigW, + svcctl_ChangeServiceConfigW_rep_data, + NDR_OUT, + svcctl_ChangeServiceConfigW_rep_check); + return suite; +} diff --git a/source4/torture/rpc/svcctl.c b/source4/torture/rpc/svcctl.c index ebb2bc6ad0e..746b399360e 100644 --- a/source4/torture/rpc/svcctl.c +++ b/source4/torture/rpc/svcctl.c @@ -3,7 +3,7 @@ test suite for svcctl rpc operations Copyright (C) Jelmer Vernooij 2004 - Copyright (C) Guenther Deschner 2008,2009 + Copyright (C) Guenther Deschner 2008,2009,2020 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 @@ -623,6 +623,83 @@ static bool test_SCManager(struct torture_context *tctx, return true; } +static bool test_ChangeServiceConfigW(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + struct svcctl_ChangeServiceConfigW r; + struct svcctl_QueryServiceConfigW q; + struct policy_handle h, s; + NTSTATUS status; + struct dcerpc_binding_handle *b = p->binding_handle; + struct QUERY_SERVICE_CONFIG query; + bool ok; + + uint32_t offered = 0; + uint32_t needed = 0; + + ok = test_OpenSCManager(b, tctx, &h); + if (!ok) { + return false; + } + + ok = test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s); + if (!ok) { + return false; + } + + q.in.handle = &s; + q.in.offered = offered; + q.out.query = &query; + q.out.needed = &needed; + + status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &q); + torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!"); + + if (W_ERROR_EQUAL(q.out.result, WERR_INSUFFICIENT_BUFFER)) { + q.in.offered = needed; + status = dcerpc_svcctl_QueryServiceConfigW_r(b, tctx, &q); + torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfigW failed!"); + } + torture_assert_werr_ok(tctx, q.out.result, "QueryServiceConfigW failed!"); + + r.in.handle = &s; + r.in.type = query.service_type; + r.in.start_type = query.start_type; + r.in.error_control = query.error_control; + + /* + * according to MS-SCMR 3.1.4.11 NULL params are supposed to leave the + * existing values intact. + */ + + r.in.binary_path = NULL; + r.in.load_order_group = NULL; + r.in.dependencies = NULL; + r.in.dwDependSize = 0; + r.in.service_start_name = NULL; + r.in.password = NULL; + r.in.dwPwSize = 0; + r.in.display_name = NULL; + r.in.tag_id = NULL; + r.out.tag_id = NULL; + + status = dcerpc_svcctl_ChangeServiceConfigW_r(b, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "ChangeServiceConfigW failed!"); + torture_assert_werr_ok(tctx, r.out.result, "ChangeServiceConfigW failed!"); + + ok = test_CloseServiceHandle(b, tctx, &s); + if (!ok) { + return false; + } + + ok = test_CloseServiceHandle(b, tctx, &h); + if (!ok) { + return false; + } + + return true; +} + struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "svcctl"); @@ -652,6 +729,8 @@ struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx) test_StartServiceW); torture_rpc_tcase_add_test(tcase, "ControlService", test_ControlService); + torture_rpc_tcase_add_test(tcase, "ChangeServiceConfigW", + test_ChangeServiceConfigW); return suite; } diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build index 65af160b322..05a6fbcbf14 100644 --- a/source4/torture/wscript_build +++ b/source4/torture/wscript_build @@ -71,6 +71,7 @@ bld.SAMBA_SUBSYSTEM('TORTURE_NDR', ndr/winspool.c ndr/cabinet.c ndr/charset.c + ndr/svcctl.c ''', autoproto='ndr/proto.h', deps='torture krb5samba', -- Samba Shared Repository