summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/include/doserr.h2
-rw-r--r--source4/libcli/util/doserr.c2
-rw-r--r--source4/librpc/config.mk14
-rw-r--r--source4/librpc/idl/initshutdown.idl46
-rw-r--r--source4/librpc/idl/winreg.idl6
-rw-r--r--source4/librpc/ndr/ndr_basic.c14
-rw-r--r--source4/torture/config.mk5
-rw-r--r--source4/torture/rpc/initshutdown.c146
-rw-r--r--source4/torture/rpc/winreg.c20
-rw-r--r--source4/torture/torture.c1
10 files changed, 244 insertions, 12 deletions
diff --git a/source4/include/doserr.h b/source4/include/doserr.h
index 36eb3b07f1..fa4f2f48e9 100644
--- a/source4/include/doserr.h
+++ b/source4/include/doserr.h
@@ -222,6 +222,8 @@
#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued)
#define WERR_CLASS_NOT_REGISTERED W_ERROR(0x40154)
+#define WERR_NO_SHUTDOWN_IN_PROGRESS W_ERROR(0x45c)
+#define WERR_SHUTDOWN_ALREADY_IN_PROGRESS W_ERROR(0x45b)
#ifndef NERR_BASE
diff --git a/source4/libcli/util/doserr.c b/source4/libcli/util/doserr.c
index 83553448a3..577c004422 100644
--- a/source4/libcli/util/doserr.c
+++ b/source4/libcli/util/doserr.c
@@ -90,6 +90,8 @@ static const struct werror_code_struct dos_errs[] =
{ "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
{ "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED },
+ { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS },
+ { "WERR_SHUTDOWN_ALREADY_IN_PROGRESS", WERR_SHUTDOWN_ALREADY_IN_PROGRESS },
{ NULL, W_ERROR(0) }
};
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index bf34207872..37a1614345 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -191,6 +191,12 @@ INIT_OBJ_FILES = librpc/gen_ndr/ndr_winreg.o
NOPROTO = YES
REQUIRED_SUBSYSTEMS = LIBNDR
+[SUBSYSTEM::NDR_INITSHUTDOWN]
+INIT_FUNCTION = dcerpc_initshutdown_init
+INIT_OBJ_FILES = librpc/gen_ndr/ndr_initshutdown.o
+NOPROTO = YES
+REQUIRED_SUBSYSTEMS = LIBNDR
+
[SUBSYSTEM::NDR_MGMT]
INIT_FUNCTION = dcerpc_mgmt_init
INIT_OBJ_FILES = librpc/gen_ndr/ndr_mgmt.o
@@ -317,7 +323,8 @@ REQUIRED_SUBSYSTEMS = NDR_AUDIOSRV NDR_ECHO NDR_DCERPC NDR_EXCHANGE \
NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \
NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
- NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL LIB_SECURITY_NDR
+ NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL LIB_SECURITY_NDR \
+ NDR_INITSHUTDOWN
[SUBSYSTEM::RPC_NDR_ROT]
ADD_OBJ_FILES = librpc/gen_ndr/ndr_rot_c.o
@@ -439,6 +446,11 @@ ADD_OBJ_FILES = librpc/gen_ndr/ndr_winreg_c.o
REQUIRED_SUBSYSTEMS = LIBRPC NDR_WINREG
NOPROTO = YES
+[SUBSYSTEM::RPC_NDR_INITSHUTDOWN]
+ADD_OBJ_FILES = librpc/gen_ndr/ndr_initshutdown_c.o
+REQUIRED_SUBSYSTEMS = LIBRPC NDR_INITSHUTDOWN
+NOPROTO = YES
+
[SUBSYSTEM::RPC_NDR_MGMT]
ADD_OBJ_FILES = librpc/gen_ndr/ndr_mgmt_c.o
REQUIRED_SUBSYSTEMS = LIBRPC NDR_MGMT
diff --git a/source4/librpc/idl/initshutdown.idl b/source4/librpc/idl/initshutdown.idl
new file mode 100644
index 0000000000..e84edb47b8
--- /dev/null
+++ b/source4/librpc/idl/initshutdown.idl
@@ -0,0 +1,46 @@
+#include "idl_types.h"
+
+/*
+ initshutdown interface definition
+*/
+
+[
+ uuid("894de0c0-0d55-11d3-a322-00c04fa321a1"),
+ version(1.0),
+ endpoint("ncacn_np:[\\pipe\\InitShutdown]"),
+ pointer_default(unique),
+ helpstring("Init shutdown service")
+] interface initshutdown
+{
+ typedef struct {
+ [value(strlen_m_term(r->name))] uint32 name_size;
+ [flag(STR_LEN4|STR_NOTERM)] string name;
+ } initshutdown_String_sub;
+
+ typedef [public] struct {
+ [value(strlen_m(r->name->name)*2)] uint16 name_len;
+ [value(strlen_m_term(r->name->name)*2)] uint16 name_size;
+ initshutdown_String_sub *name;
+ } initshutdown_String;
+
+ WERROR initshutdown_Init(
+ [in] uint16 *hostname,
+ [in] initshutdown_String *message,
+ [in] uint32 timeout,
+ [in] uint8 force_apps,
+ [in] uint8 reboot
+ );
+
+ WERROR initshutdown_Abort(
+ [in] uint16 *server
+ );
+
+ WERROR initshutdown_InitEx(
+ [in] uint16 *hostname,
+ [in] initshutdown_String *message,
+ [in] uint32 timeout,
+ [in] uint8 force_apps,
+ [in] uint8 reboot,
+ [in] uint32 reason
+ );
+}
diff --git a/source4/librpc/idl/winreg.idl b/source4/librpc/idl/winreg.idl
index 3d11af790b..47531d4710 100644
--- a/source4/librpc/idl/winreg.idl
+++ b/source4/librpc/idl/winreg.idl
@@ -10,7 +10,7 @@
endpoint("ncacn_np:[\\pipe\\winreg]","ncacn_ip_tcp:","ncalrpc:"),
pointer_default(unique),
helpstring("Remote Registry Service"),
- depends(lsa)
+ depends(lsa,initshutdown)
] interface winreg
{
typedef struct {
@@ -270,7 +270,7 @@
/* Function: 0x18 */
WERROR winreg_InitiateSystemShutdown(
[in] uint16 *hostname,
- [in] winreg_String *message,
+ [in] initshutdown_String *message,
[in] uint32 timeout,
[in] uint8 force_apps,
[in] uint8 reboot
@@ -326,7 +326,7 @@
/* Function: 0x1e */
WERROR winreg_InitiateSystemShutdownEx(
[in] uint16 *hostname,
- [in] winreg_String *message,
+ [in] initshutdown_String *message,
[in] uint32 timeout,
[in] uint8 force_apps,
[in] uint8 reboot,
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 3e192d03a2..8284375be5 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -918,6 +918,20 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
ndr->offset += byte_mul*(c_len+1);
break;
+ case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_NOTERM:
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
+ NDR_PUSH_NEED_BYTES(ndr, byte_mul*c_len);
+ ret = convert_string(CH_UNIX, chset,
+ s, s_len,
+ ndr->data+ndr->offset, byte_mul*c_len);
+ if (ret == -1) {
+ return ndr_push_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
+ ndr->offset += byte_mul*c_len;
+ break;
+
case LIBNDR_FLAG_STR_SIZE4:
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len + c_len_term));
NDR_PUSH_NEED_BYTES(ndr, byte_mul*(c_len+1));
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 4bd2ce6d5d..80fdefcf36 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -85,6 +85,7 @@ ADD_OBJ_FILES = \
torture/rpc/eventlog.o \
torture/rpc/epmapper.o \
torture/rpc/winreg.o \
+ torture/rpc/initshutdown.o \
torture/rpc/oxidresolve.o \
torture/rpc/remact.o \
torture/rpc/mgmt.o \
@@ -102,8 +103,8 @@ ADD_OBJ_FILES = \
torture/rpc/dssetup.o \
torture/rpc/alter_context.o
REQUIRED_SUBSYSTEMS = \
- NDR_ALL RPC_NDR_SAMR RPC_NDR_WINREG RPC_NDR_OXIDRESOLVER \
- RPC_NDR_EVENTLOG RPC_NDR_ECHO RPC_NDR_SVCCTL \
+ NDR_ALL RPC_NDR_SAMR RPC_NDR_WINREG RPC_NDR_INITSHUTDOWN \
+ RPC_NDR_OXIDRESOLVER RPC_NDR_EVENTLOG RPC_NDR_ECHO RPC_NDR_SVCCTL \
RPC_NDR_MGMT RPC_NDR_NETLOGON RPC_NDR_ATSVC RPC_NDR_DRSUAPI \
RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_SPOOLSS \
RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \
diff --git a/source4/torture/rpc/initshutdown.c b/source4/torture/rpc/initshutdown.c
new file mode 100644
index 0000000000..0aa64e3eb2
--- /dev/null
+++ b/source4/torture/rpc/initshutdown.c
@@ -0,0 +1,146 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for initshutdown operations
+
+ Copyright (C) Tim Potter 2003
+ Copyright (C) Jelmer Vernooij 2004-2005
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_initshutdown.h"
+
+static void init_initshutdown_String(TALLOC_CTX *mem_ctx, struct initshutdown_String *name, const char *s)
+{
+ name->name = talloc(mem_ctx, struct initshutdown_String_sub);
+ name->name->name = s;
+}
+
+static BOOL test_Init(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ const char *msg, uint32_t timeout)
+{
+ struct initshutdown_Init r;
+ NTSTATUS status;
+ uint16_t hostname = 0x0;
+
+ r.in.hostname = &hostname;
+ r.in.message = talloc(mem_ctx, struct initshutdown_String);
+ init_initshutdown_String(mem_ctx, r.in.message, msg);
+ r.in.force_apps = 1;
+ r.in.timeout = timeout;
+ r.in.reboot = 1;
+
+ status = dcerpc_initshutdown_Init(p, mem_ctx, &r);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("initshutdown_Init failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("initshutdown_Init failed - %s\n", win_errstr(r.out.result));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL test_InitEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ const char *msg, uint32_t timeout)
+{
+ struct initshutdown_InitEx r;
+ NTSTATUS status;
+ uint16_t hostname = 0x0;
+
+ r.in.hostname = &hostname;
+ r.in.message = talloc(mem_ctx, struct initshutdown_String);
+ init_initshutdown_String(mem_ctx, r.in.message, msg);
+ r.in.force_apps = 1;
+ r.in.timeout = timeout;
+ r.in.reboot = 1;
+ r.in.reason = 0;
+
+ status = dcerpc_initshutdown_InitEx(p, mem_ctx, &r);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("initshutdown_InitEx failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("initshutdown_InitEx failed - %s\n", win_errstr(r.out.result));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL test_Abort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+{
+ struct initshutdown_Abort r;
+ NTSTATUS status;
+ uint16_t server = 0x0;
+
+ r.in.server = &server;
+
+ status = dcerpc_initshutdown_Abort(p, mem_ctx, &r);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("initshutdown_Abort failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("initshutdown_Abort failed - %s\n", win_errstr(r.out.result));
+ return False;
+ }
+
+ return True;
+}
+
+BOOL torture_rpc_initshutdown(void)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *mem_ctx;
+ BOOL ret = True;
+
+ mem_ctx = talloc_init("torture_rpc_initshutdown");
+
+ status = torture_rpc_connection(&p,
+ DCERPC_INITSHUTDOWN_NAME,
+ DCERPC_INITSHUTDOWN_UUID,
+ DCERPC_INITSHUTDOWN_VERSION);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
+ printf("initshutdown tests disabled - enable dangerous tests to use\n");
+ } else {
+ ret &= test_Init(p, mem_ctx, "spottyfood", 30);
+ ret &= test_Abort(p, mem_ctx);
+ ret &= test_InitEx(p, mem_ctx, "spottyfood", 30);
+ ret &= test_Abort(p, mem_ctx);
+ }
+
+ talloc_free(mem_ctx);
+
+ torture_rpc_close(p);
+
+ return ret;
+}
diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c
index 9d259ae47a..df0114b669 100644
--- a/source4/torture/rpc/winreg.c
+++ b/source4/torture/rpc/winreg.c
@@ -23,6 +23,12 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_winreg.h"
+static void init_initshutdown_String(TALLOC_CTX *mem_ctx, struct initshutdown_String *name, const char *s)
+{
+ name->name = talloc(mem_ctx, struct initshutdown_String_sub);
+ name->name->name = s;
+}
+
static void init_winreg_String(struct winreg_String *name, const char *s)
{
name->name = s;
@@ -555,10 +561,11 @@ static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_c
{
struct winreg_InitiateSystemShutdown r;
NTSTATUS status;
+ uint16_t hostname = 0x0;
- r.in.hostname = NULL;
- r.in.message = talloc(mem_ctx, struct winreg_String);
- init_winreg_String(r.in.message, msg);
+ r.in.hostname = &hostname;
+ r.in.message = talloc(mem_ctx, struct initshutdown_String);
+ init_initshutdown_String(mem_ctx, r.in.message, msg);
r.in.force_apps = 1;
r.in.timeout = timeout;
r.in.reboot = 1;
@@ -583,10 +590,11 @@ static BOOL test_InitiateSystemShutdownEx(struct dcerpc_pipe *p, TALLOC_CTX *mem
{
struct winreg_InitiateSystemShutdownEx r;
NTSTATUS status;
+ uint16_t hostname = 0x0;
- r.in.hostname = NULL;
- r.in.message = talloc(mem_ctx, struct winreg_String);
- init_winreg_String(r.in.message, msg);
+ r.in.hostname = &hostname;
+ r.in.message = talloc(mem_ctx, struct initshutdown_String);
+ init_initshutdown_String(mem_ctx, r.in.message, msg);
r.in.force_apps = 1;
r.in.timeout = timeout;
r.in.reboot = 1;
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index 09be1e1fe3..32c258068b 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -2394,6 +2394,7 @@ static struct {
{"RPC-EVENTLOG", torture_rpc_eventlog, 0},
{"RPC-EPMAPPER", torture_rpc_epmapper, 0},
{"RPC-WINREG", torture_rpc_winreg, 0},
+ {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
{"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
{"RPC-REMACT", torture_rpc_remact, 0},
{"RPC-MGMT", torture_rpc_mgmt, 0},