New files for support of initshutdown pipe. Win2k doesn't respond properly
authorJim McDonough <jmcd@samba.org>
Fri, 24 Oct 2003 13:38:13 +0000 (13:38 +0000)
committerJim McDonough <jmcd@samba.org>
Fri, 24 Oct 2003 13:38:13 +0000 (13:38 +0000)
to all requests on the winreg pipe, so we need to handle this new pipe.

First part of fix for bug #534

source/include/rpc_shutdown.h [new file with mode: 0644]
source/rpc_client/cli_shutdown.c [new file with mode: 0644]
source/rpc_parse/parse_shutdown.c [new file with mode: 0644]
source/rpcclient/cmd_shutdown.c [new file with mode: 0644]

diff --git a/source/include/rpc_shutdown.h b/source/include/rpc_shutdown.h
new file mode 100644 (file)
index 0000000..b8e50b8
--- /dev/null
@@ -0,0 +1,70 @@
+/* 
+   Unix SMB/CIFS implementation.
+   SMB parameters and setup
+   Copyright (C) Jim McDonough (jmcd@us.ibm.com)      2003.
+   
+   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.
+*/
+
+#ifndef _RPC_SHUTDOWN_H /* _RPC_SHUTDOWN_H */
+#define _RPC_SHUTDOWN_H 
+
+
+/* Implemented */
+#define SHUTDOWN_INIT          0x00
+#define SHUTDOWN_ABORT         0x01
+/* NOT IMPLEMENTED
+#define SHUTDOWN_INIT_EX       0x02
+*/
+
+/* SHUTDOWN_Q_INIT */
+typedef struct q_shutodwn_init_info
+{
+       uint32 ptr_server;
+       uint16 server;
+       uint32 ptr_msg;
+       UNIHDR hdr_msg;         /* shutdown message */
+       UNISTR2 uni_msg;        /* seconds */
+       uint32 timeout;         /* seconds */
+       uint8 force;            /* boolean: force shutdown */
+       uint8 reboot;           /* boolean: reboot on shutdown */
+               
+} SHUTDOWN_Q_INIT;
+
+/* SHUTDOWN_R_INIT */
+typedef struct r_shutdown_init_info
+{
+       NTSTATUS status;                /* return status */
+
+} SHUTDOWN_R_INIT;
+
+/* SHUTDOWN_Q_ABORT */
+typedef struct q_shutdown_abort_info
+{
+       uint32 ptr_server;
+       uint16 server;
+
+} SHUTDOWN_Q_ABORT;
+
+/* SHUTDOWN_R_ABORT */
+typedef struct r_shutdown_abort_info
+{ 
+       NTSTATUS status; /* return status */
+
+} SHUTDOWN_R_ABORT;
+
+
+#endif /* _RPC_SHUTDOWN_H */
+
diff --git a/source/rpc_client/cli_shutdown.c b/source/rpc_client/cli_shutdown.c
new file mode 100644 (file)
index 0000000..0bf6e90
--- /dev/null
@@ -0,0 +1,104 @@
+/* 
+   Unix SMB/CIFS implementation.
+   RPC Pipe client
+   Copyright (C) Andrew Tridgell              1992-1998,
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+   Copyright (C) Paul Ashton                  1997-1998.
+   Copyright (C) Jeremy Allison                    1999,
+   Copyright (C) Simo Sorce                        2001,
+   Copyright (C) Jim McDonough (jmcd@us.ibm.com)   2003.
+   
+   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"
+
+/* Shutdown a server */
+
+NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+                          const char *msg, uint32 timeout, BOOL do_reboot,
+                          BOOL force)
+{
+       prs_struct qbuf;
+       prs_struct rbuf; 
+       SHUTDOWN_Q_INIT q_s;
+       SHUTDOWN_R_INIT r_s;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;
+
+       ZERO_STRUCT (q_s);
+       ZERO_STRUCT (r_s);
+
+       prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_shutdown_q_init(&q_s, msg, timeout, do_reboot, force);
+
+       if (!shutdown_io_q_init("", &q_s, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, SHUTDOWN_INIT, &qbuf, &rbuf))
+               goto done;
+       
+       /* Unmarshall response */
+       
+       if(shutdown_io_r_init("", &r_s, &rbuf, 0))
+               result = r_s.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+
+/* Abort a server shutdown */
+
+NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       SHUTDOWN_Q_ABORT q_s;
+       SHUTDOWN_R_ABORT r_s;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       ZERO_STRUCT (q_s);
+       ZERO_STRUCT (r_s);
+
+       prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+       
+       /* Marshall data and send request */
+
+       init_shutdown_q_abort(&q_s);
+
+       if (!shutdown_io_q_abort("", &q_s, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, SHUTDOWN_ABORT, &qbuf, &rbuf))
+               goto done;
+       
+               /* Unmarshall response */
+       
+       if (shutdown_io_r_abort("", &r_s, &rbuf, 0))
+               result = r_s.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf );
+
+       return result;
+}
diff --git a/source/rpc_parse/parse_shutdown.c b/source/rpc_parse/parse_shutdown.c
new file mode 100644 (file)
index 0000000..ad2d6e1
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Jim McDonough (jmcd@us.ibm.com)   2003.
+ *  
+ *  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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+
+void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
+                       uint32 timeout, BOOL do_reboot, BOOL force)
+{
+       q_s->ptr_server = 1;
+       q_s->server = 1;
+       q_s->ptr_msg = 1;
+
+       init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
+       init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
+
+       q_s->timeout = timeout;
+
+       q_s->reboot = do_reboot ? 1 : 0;
+       q_s->force = force ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL shutdown_io_q_init(const char *desc, SHUTDOWN_Q_INIT *q_s, prs_struct *ps,
+                       int depth)
+{
+       if (q_s == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "shutdown_io_q_init");
+       depth++;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+               return False;
+       if (!prs_uint16("server", ps, depth, &(q_s->server)))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+       if (!prs_uint32("ptr_msg", ps, depth, &(q_s->ptr_msg)))
+               return False;
+
+       if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
+               return False;
+       if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
+               return False;
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
+               return False;
+       if (!prs_uint8("force  ", ps, depth, &(q_s->force)))
+               return False;
+       if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
+                       int depth)
+{
+       if (r_s == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "shutdown_io_r_init");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_ntstatus("status", ps, depth, &r_s->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+void init_shutdown_q_abort(SHUTDOWN_Q_ABORT *q_s)
+{
+
+       q_s->ptr_server = 0;
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL shutdown_io_q_abort(const char *desc, SHUTDOWN_Q_ABORT *q_s,
+                        prs_struct *ps, int depth)
+{
+       if (q_s == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "shutdown_io_q_abort");
+       depth++;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+               return False;
+       if (q_s->ptr_server != 0)
+               if (!prs_uint16("server", ps, depth, &(q_s->server)))
+                       return False;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL shutdown_io_r_abort(const char *desc, SHUTDOWN_R_ABORT *r_s,
+                        prs_struct *ps, int depth)
+{
+       if (r_s == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "shutdown_io_r_abort");
+       depth++;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_ntstatus("status", ps, depth, &r_s->status))
+               return False;
+
+       return True;
+}
diff --git a/source/rpcclient/cmd_shutdown.c b/source/rpcclient/cmd_shutdown.c
new file mode 100644 (file)
index 0000000..e42ec30
--- /dev/null
@@ -0,0 +1,112 @@
+/* 
+   Unix SMB/CIFS implementation.
+   NT Domain Authentication SMB / MSRPC client
+   Copyright (C) Andrew Tridgell                 1994-1997,
+   Copyright (C) Luke Kenneth Casson Leighton    1996-1997,
+   Copyright (C) Simo Sorce                      2001,
+   Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+   
+   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 "rpcclient.h"
+
+/****************************************************************************
+nt shutdown init
+****************************************************************************/
+static NTSTATUS cmd_shutdown_init(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                 int argc, const char **argv)
+{
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       fstring msg;
+       uint32 timeout = 20;
+       BOOL force = False;
+       BOOL reboot = False;
+       int opt;
+
+       *msg = 0;
+       optind = 0; /* TODO: test if this hack works on other systems too --simo */
+
+       while ((opt = getopt(argc, argv, "m:t:rf")) != EOF)
+       {
+               /*fprintf (stderr, "[%s]\n", argv[argc-1]);*/
+       
+               switch (opt)
+               {
+                       case 'm':
+                               fstrcpy(msg, optarg);
+                               /*fprintf (stderr, "[%s|%s]\n", optarg, msg);*/
+                               break;
+
+                       case 't':
+                               timeout = atoi(optarg);
+                               /*fprintf (stderr, "[%s|%d]\n", optarg, timeout);*/
+                               break;
+
+                       case 'r':
+                               reboot = True;
+                               break;
+
+                       case 'f':
+                               force = True;
+                               break;
+
+               }
+       }
+
+       /* create an entry */
+       result = cli_shutdown_init(cli, mem_ctx, msg, timeout, reboot, force);
+
+       if (NT_STATUS_IS_OK(result))
+               DEBUG(5,("cmd_shutdown_init: query succeeded\n"));
+       else
+               DEBUG(5,("cmd_shutdown_init: query failed\n"));
+
+       return result;
+}
+
+/****************************************************************************
+abort a shutdown
+****************************************************************************/
+static NTSTATUS cmd_shutdown_abort(struct cli_state *cli, 
+                                  TALLOC_CTX *mem_ctx, int argc, 
+                                  const char **argv)
+{
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       result = cli_shutdown_abort(cli, mem_ctx);
+
+       if (NT_STATUS_IS_OK(result))
+               DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
+       else
+               DEBUG(5,("cmd_shutdown_abort: query failed\n"));
+
+       return result;
+}
+
+
+/* List of commands exported by this module */
+struct cmd_set shutdown_commands[] = {
+
+       { "SHUTDOWN"  },
+
+       { "shutdowninit", RPC_RTYPE_NTSTATUS, cmd_shutdown_init, NULL, PI_SHUTDOWN, "Remote Shutdown (over shutdown pipe)",
+                               "syntax: shutdown [-m message] [-t timeout] [-r] [-h] [-f] (-r == reboot, -h == halt, -f == force)" },
+                               
+       { "shutdownabort", RPC_RTYPE_NTSTATUS, cmd_shutdown_abort, NULL, PI_SHUTDOWN, "Abort Shutdown (over shutdown pipe)",
+                               "syntax: shutdownabort" },
+       { NULL }
+};