summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-11-05 17:46:16 +0000
committerLuke Leighton <lkcl@samba.org>1999-11-05 17:46:16 +0000
commit0d7f9837e282dc1b441c13d99eb7faf3d03ba1de (patch)
treedacb197f9b2b2362cc2886cf1a3fd4c1fe6768bc
parent710922ca3613a36fa96da0256dde2a64c5deee2c (diff)
downloadsamba-0d7f9837e282dc1b441c13d99eb7faf3d03ba1de.tar.gz
samba-0d7f9837e282dc1b441c13d99eb7faf3d03ba1de.tar.bz2
samba-0d7f9837e282dc1b441c13d99eb7faf3d03ba1de.zip
This is an experimental program to shutdown a group of NTws in a
Samba domain via rpcclient. Copyright (c) David Bannon 1999 David Bannon, D.Bannon@latrobe.edu.au, 4th November, 1999 (This used to be commit 51747ecf6adbb89695a1a8b8fbb98e9f6b7d2290)
-rw-r--r--examples/rpcclient/ntsd.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/examples/rpcclient/ntsd.c b/examples/rpcclient/ntsd.c
new file mode 100644
index 0000000000..37976edaa5
--- /dev/null
+++ b/examples/rpcclient/ntsd.c
@@ -0,0 +1,259 @@
+/* This is an experiemental programme to shutdown a group of NTws in a
+ Samba domain via rpcclient.
+
+ Copyright (c) David Bannon 1999
+ David Bannon, D.Bannon@latrobe.edu.au, 4th November, 1999
+
+ Full permission is granted to use this code (for what that is worth) in
+ any way you wish, strictly at your own risk.
+
+ I use it from a cron a job to close a computer lab down at 5:00 pm.
+
+ It has some serious security implications, make sure you understand
+ them before using this code !
+
+ If you find a way to make this 'power down' a machine that is set up to
+ do power down correctly please let me know !!
+
+ Machines to be shutdown must be members of a samba (or NT) domain.
+ You are going to have to offer your domain admin user name/password
+ (see below).
+
+ As you probably don't want your domain admin password appearing in the
+ crontab file or popping up in a 'ps' list, it can be encrypted and the
+ programme will tell you what it should look like. i.e :
+
+ [root@bclab shutdown]# ./ntsd -e
+ Domain Admin User name :dbannon
+ Domain Admin Password
+ Use the string between [] after a -p : [1HCeTcXqOfo7R[hg]
+ [root@bclab shutdown]#
+
+ Now a crontab entry would look like this :
+
+ 00 17 * * 1-5 /usr/local/sbin/ntsd -p'1HCeTcXqOfo7R[hg' -a
+
+ The -p indicates passwd (actually user name and password) and the
+ -a says shutdown all machines. Note that the password string must
+ have inverted commas around it so the shell does not try and expand
+ any special charachers that it is likely to contain.
+
+ Security Alert !!
+ The encryption is pretty weak and its reversable ! Change the key
+ strings, compile and change the key strings again ! You don't need
+ to remember the key but if you leave the unchanged source around
+ someone may use it to reverse the encryption. The Keys are in lumps
+ to stop someone doing a 'cat ntsd' and seeing the key string.
+ (yeah, I know its not very clever, but they should not be able to
+ read the binary or your crontab anyway)
+
+ Ping
+ I ping the target machines before trying to shut them down, you
+ dont't need to, just let rpcclient time out. If you want to ping
+ first (because its nicer !) you need :
+ 1. First element of IP name should be the netbios name. (makes sense)
+ 2. If the server you will run the cron job from does not have the
+ same default domain name as machines being shutdown then you will
+ need to define USE_DOMAIN and put in appropriate ip domain info.
+ This code does ping, get busy with vi if you don't want to.
+
+ Machine Names
+ For this system to be practical, the machine names must be in some
+ sort of sequence, ie bclab1, bclab2, bclab3, not more creative like
+ grumpy, dopey, sneezy. See the code in main() to see how the names
+ are built.
+
+ Configuration
+
+ Machine Names
+ If you have used a naming scheme like mine then you may need to
+ change only LASTMACHINE and PREFIX, otherwise look at main().
+
+ Binary locations.
+ We need to find the rpcclient and ping binaries. The values below
+ are typical. Better check first.
+
+ Compile
+ Known to compile cleanly on linux (RH5.0 - RH6.1) and DEC 4.0. Does
+ not do anything fancy so should compile on most systems easily
+ enough.
+
+ Install
+ Rename the binary (ie ntsd) and put it somewhere safe. It should
+ be rwx root only. Comes up with basic help if run without command
+ line switch, prompts for admin user name and password if used
+ without the -p switch.
+ (Typically)Put entry in your crontab (crontab -e) and watch the
+ fun. Remember, it does not keep them shutdown, try an entry every
+ 5 minutes for a while (or until door is locked).
+*/
+
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<unistd.h>
+#include<pwd.h>
+
+#define PING "/bin/ping"
+#define RPCCLIENT "/usr/local/samba/bin/rpcclient"
+
+
+#define LASTMACHINE 14 /* ie, scans bclab1 through to bclab14 */
+#define PREFIX "bclab"
+
+/* #define USE_DOMAIN Only if you need full ip name to ping machines */
+
+#ifdef USE_DOMAIN
+#define DOMAIN ".biochem.latrobe.edu.au" /* required by ping, possibly.
+ */
+#endif
+
+#define KEY1 "Please"
+#define KEY2 "don't leave"
+#define KEY3 "this"
+#define KEY4 "as it is"
+#define KEY5 "here"
+#define KEY6 "silly."
+
+
+int Shutdown(char *machine, char *PassWord) {
+ char Buff[128], *Ptr;
+ int Res;
+ /* printf("Shutting down %s\n", machine); */
+ sprintf(Buff, "/bin/ping -c 1 -q %s > /dev/null", machine);
+ Res = system(Buff);
+ if (Res == 0) { /* its turned on */
+ Ptr = machine;
+ /* first 'word' in ip name = netbios name, get rid of rest */
+ while (*++Ptr != 0) if (*Ptr == '.') *Ptr = 0;
+ printf("Shutting down %s\n", machine);
+ sprintf(Buff, "%s -c shutdown -U%s -S %s", RPCCLIENT, PassWord,
+machine);
+ system(Buff);
+ }
+}
+
+int Usage(char *prog) {
+ printf("Programme to shutdown NTs in domain.\n");
+ printf("Normally called from cron (using encrypted passwd, see -e and
+-p).\n");
+ printf("Usage \n");
+ printf(" -a shutdown all machines %s1 to %s%d. \n",
+ PREFIX, PREFIX, LASTMACHINE);
+ printf(" -m machine shutdown [machine] (might need full ip
+name).\n");
+ printf(" -e tell me my encrypted name and password to
+use with -p.\n");
+ printf(" -p'pw_string' use encrypted name & password as given by
+-e.\n");
+ printf(" You must have single inverted commas around
+the pw string !");
+ printf(" -h help, give this message.\n");
+ printf("Typical cron line : 00 17 * * 1-5 /usr/local/sbin/ntsd
+-p1HCeTcXqOfo7R[hg -a\n");
+ printf(" David Bannon,
+Nov 1999\n");
+ exit(0);
+}
+
+int GetPassWord(char *Passwd) {
+ char *ptr, *p;
+ char User[128];
+ printf("Domain Admin User name :");
+ fgets(User, 127, stdin);
+ if (strlen(User) < 3) {
+ printf("Short user name, exiting.\n");
+ exit(1);
+ }
+ p = User;
+ while (*p != '\n') p++; /* get rid of newline */
+ *p = 0;
+ ptr = getpass("Domain Admin Password ");
+ if (strlen(ptr) < 3) {
+ printf("Short password, exiting.\n");
+ exit(1);
+ }
+ strcpy(Passwd, User); /* do this with sprintf */
+ strcat(Passwd, "%");
+ strcat(Passwd, ptr);
+ *ptr = 0; /* clean up system buffer */
+ return 0;
+}
+
+int Encrypt(char *InPass) {
+ char Pass[128], Enc[128];
+ int Temp;
+ char *Hash;
+ int Offset = 0;
+ Hash = malloc(256);
+ /* so it a bit harder than just 'cat ntsd' */
+ sprintf(Hash, "%s%s%s%s%s%s", KEY4, KEY3, KEY2, KEY5, KEY1, KEY6);
+ if (InPass == 0) {
+ GetPassWord(Pass); /* may not return */
+ while (*(Pass + Offset) != 0) {
+ Temp = *(Pass + Offset) + *(Hash + Offset) - ' ';
+ if (Temp > '~') Temp = Temp - 95;
+ *(Pass+Offset++) = Temp;
+ }
+ printf("Use the string between [] after a -p : ['%s']\n", Pass);
+ exit(0);
+ } else {
+ while (*(InPass + Offset) != 0) {
+ Temp = *(InPass + Offset) - *(Hash + Offset) + ' ';
+ if (Temp < ' ') Temp = Temp + 95;
+ *(InPass+Offset++) = Temp;
+ }
+ }
+ free(Hash);
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ extern char *optarg;
+ extern int optind;
+ int Ch;
+ static char *prog_name;
+ int MachineNo = 0, AllMachines = 0;
+ char Machine[128], PassWord[128];
+ uid_t UID = getuid();
+ prog_name = argv[0];
+ if (UID != 0) {
+ printf("Sorry, this programme can only be run as root.\n");
+ exit(1);
+ }
+ *Machine = 0;
+ *PassWord = 0;
+ if (argc < 2) Usage(prog_name);
+ while ((Ch = getopt(argc, argv, "haem:p:")) != EOF) {
+ switch(Ch) {
+ case 'e': Encrypt(NULL); break; /* Does not return */
+ case 'a': AllMachines = 1; break;
+ case 'm': strcpy(Machine, optarg); break;
+ case 'p': strcpy(PassWord, optarg); break;
+ case 'h': Usage(prog_name);
+ default: Usage(prog_name);
+ }
+ }
+ if (*PassWord == 0) GetPassWord(PassWord); /* may not return */
+ else Encrypt(PassWord);
+ if (*Machine != 0) {
+ Shutdown(Machine, PassWord);
+ exit(0);
+ }
+ /* printf("exit for safety = %s.\n", PassWord);
+exit(0); */
+ while (++MachineNo < LASTMACHINE+1) {
+ pid_t Proc;
+#ifdef USE_DOMAIN
+ sprintf(Machine, "%s%d%s", PREFIX, MachineNo, DOMAIN);
+#else
+ sprintf(Machine, "%s%d", PREFIX, MachineNo);
+#endif
+ Proc = fork();
+ if (Proc == 0) { /* in child process */
+ Shutdown(Machine, PassWord);
+ exit(0);
+ }
+ }
+ printf("Shutdowns initiated.\n");
+}