• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 511
  • Last Modified:

KDE: need a customized shutdown script for kdm

I'm using kde 1.1.1 and running kdm. I want to customize the shutdown and reboot options that appear as button items from kdm. I see that I can choose different commands using kdmconfig.

This is my problem: my lab computer also runs Windows95 (a problem in and of itself, of course!) with which a lab colleague of mine does some analysis. The computer runs linux at all times except when he uses it to run Windows. Sometimes, I am using the computer remotely from my office at the same that he needs to reboot into Windows. I've instructed him to always call me first before rebooting out of kdm, but he consistently forgets, which boots me off the system in the middle of doing something. I realize I could just disable shutdown and reboot so that he couldn't do this, but that's not what I want. I want him to be able to reboot, but not if someone (i.e., me) is logged on. What's the best way to do this? The only way I can think of is to link shutdown to some script which runs "who" or something like that to see if someone is logged on, and if so, disallow him to reboot (in which case he gets on the phone, calls me, and we arrange something). I don't know how to write such a script. So, could someone either provide a nice, clean script, or alternatively a better solution? Ideally, the script would pop up a console window or something telling him who's logged on if it can't reboot.
Thanks!
Dave
0
djc2
Asked:
djc2
  • 5
  • 4
1 Solution
 
jlevieCommented:
I've always had a problem with folks who conviently "consistantly forget" to do the right thing. If it were me I'd take away his privs to shutdown or reboot the box for a while (and threaten him with serious mayhem if he touches the power switch). You might find that his memory improves drastically afterwards.

It can be a bit tricky to properly wrap the normal shutdown process in a script and have it do the right thing. I'd need to experiment a bit to make sure it would work, but I can think of a couple of ways to do it.
0
 
alien_life_formCommented:
Greetings.

Offhand, I can think of two alternatives:

o) Tweak the scripts that are run before shutdown.(On redhat, that would be /etc/rc.d/init.d/halt, among others)

o)PAM can provide some way of doing what you're after, if it doesn't already.

I'd have to work on the mechanics of both - and none of them will orevent him from pulling the power cord, hit the off button, or other similarly radical actions. So the physical intimidation jlevie suggests may be the way to go.

CHeers,
    alf
0
 
djc2Author Commented:
In theory I agree with the proposal of
taking away his shutdown privileges, and I certainly have a problem with him consistently forgetting. But, there's not much I can do: the
problem is that he uses the computer for
important experiments that have
to happen at a certain time, and if he
doesn't have shutdown privileges and he
can't track me down, he'll have no choice but to do a hard reboot. So, taking away his privileges is not a viable option.

What I had in mind was more in the line
of tweaking the scripts, but I wouldn't
have much of a clue how to do it.

-Dave
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jlevieCommented:
I'd like to propose a compromise solution that doesn't require major surgery to the normal system installation. However it does require a different method of invoking the shutdown and thus may or may not be acceptable.

The difference in the process is that it would have to be done on a command line login to the console. It's easy enough to get to, just do ctrl-alt-F1. He'd then have to log in and execute my script, which will check for any users other than root and his login. To cover the case of it being required to reboot, even when there are looged on users, the script can ask for confirmation before proceeding. That would be preferable to just hitting the reset.

0
 
djc2Author Commented:
jlevie, I think your script is what I'm looking for. But one thing I would prefer is for it to be usable from kdm. Using kdmconfig, I could easily redirect reboot and shutdown from the normal scripts to a modified script such as yours. Is there then a way for the scripts interaction to take place in the console window that can (somehow, but I don't know how) appear on the bottom right of the kdm login screen?
0
 
jlevieCommented:
I'll see, but there are problems in trying to do this sort of thing from a X session. Mostly because one of the first things that happens is that the shutdown kills X, which in turn makes the controlling tty for the script disappear, which in turn creates error handling problems. Like I said, it can be tricky.
0
 
djc2Author Commented:
jlevie,
      If your console window script
is functional, I'd like to have that. Tell you what, I'll give you the 150 points for that, and then if you feel like coming up with something that can work straight from kdm, I could give you more points for that when you get it working. Thanks!
-Dave
0
 
jlevieCommented:
I'll have the console tool for you this weekend. I've had a few work-related network emergencies over the last few days and have had precious little time to spare.
0
 
jlevieCommented:
This is my "safe reboot" setup. There are two pieces of code required, "safe-reboot" and "oper". "safe-reboot is a perl script that does the checks to see if users other than the current user and those users allowed to be on the system at reboot are found. If anyone else is detected using the system, either remotely or running a background job, the perl script lists the active users and prompts for confirmation as to whether to proceed. The other part is built from an included C program (oper.c). It gets installed as a suid to root program and actually executes the reboot. Instructions for use and installation are in the comments at the top of the respective files.

The way you use this combo is to put both "safe-reboot" and "oper" in /usr/bin so that everyone will have them in their path. You then deny "shutdown privs" to ordinary users and show them how to get to a console screen (ctrl-alt-F1 hotkey). They log in as themselves and execute "safe-reboot". Since oper gets installed suid to root it can reboot the system with the user having to otherwise have shutdown privs (hint: don't mention its existance). Nothing I can do with a script will prevent your nemesis from just saying "Yes, please" without trying to contact you and giving you the time to log off. That's an administrative problem that may well only be solved by a threat of severe retaliation... But at least the script does provide notice that it's not safe to reboot and requires the user to respond.

---begin safe-reboot---
#!/usr/bin/perl
#
# NAME
#       safe-reboot - reboot only if there are no other users on the system
#
# SYNOPSIS
#       safe-reboot
#
# DESCRIPTION
#       Using a built in list, scan the system for any evidence of any other users.
#       If there appears to be other users, print the list and require confirmation
#       as to whether to proceed. It will probably be necessary to modify the list
#       of users that are in "ulst" to suit local conditions.
#
#       To prevent malicious modification, this script should be installed so that
#       only root has write access (mode 711). To safely reboot the system without
#       giving away root privs, this script requires that my oper program be installed.
#       See oper.c for instuctions. Install this script where everyone can use it,
#       something like:
#
#       > cp safe-reboot /usr/bin
#       > chmod 711 /usr/bin/safe-reboot
#
# Author; Jim Levie (jlevie@bellsouth.net)

#
# List all of the users that can be on the system when it's safe to shutdown. Any user
# seen that's not in this list provokes the confirmation dialog.
#
@ulst = ("UID", "root", "bin", "nobody", "daemon", "xfs",);

#
# Lets find out who is running the script and add their name to the list
# (but only if it's not already there).
#
($who) = getpwuid($<);
$add = 1;
foreach $user (@ulst)
{
  if($user eq $who) {$add = 0; last;}
  if($add) {push @ulst, $who;}
}

open(INP, "ps -ef |") || die "Can't get process list\n";

@who = ();
while(<INP>)
{
  ($user, $rest) = split(/\s+/, $_, 2);
  foreach $ok (@ulst)
  {
    if($user eq $ok) {$user = "";}
  }
  if(length($user) > 0)
  {
    $add = 1;
    if($#who >= 0)
    {
      foreach $known (@who) {if($user eq $known) {$add = 0}}
    }
    if($add) {push @who, $user;}
  }
}

$dive = 1;
if($#who >= 0)
{
  print "The following are currently using the system:\n";
  foreach $user (@who) {print "  $user\n";}
  print "Are you certain that you still want to reboot? [Yes, please] ";
  $resp = <STDIN>;
  if($resp ne "Yes, please\n") {$dive = 0;}
}

if($dive)
{
  print "Rebooting\n";
  exec '/usr/bin/oper', 'reboot';
}

---begin oper.c---
/*
 * NAME
 *      oper - provide shutdown & reboot privs to users
 *
 * SYNOPSIS
 *      oper [halt | reboot]
 *
 * DESCRIPTION
 *      This utility allows ordinary users to shutdown or reboot a system by granting
 *      them root privs for only those two actions. It is quite safe if it's been installed
 *      correctly, but it is a suid root program so be careful.
 *
 *      Compile the utility with your favorite C compiler, using gcc you'd do:
 *        > gcc -o oper oper.c
 *      Install the executable someplace in everyones path and make the binary
 *      suid to root and executable by all. Be sure that only root has write access.
 *      I do it like this:
 *        > cp oper /usr/bin
 *        > chown root:root /usr/bin/oper
 *        > chmod 711 /usr/bin/oper
 *        > chmod u+s /usr/bin/oper
 *
 *      Author: Jim Levie (jlevie@bellsouth.net)
 */

#include <stdio.h>

extern char **environ;

char *down[] = {"/sbin/shutdown", "-h", "now", '\0'};
char *bounce[] = {"/sbin/shutdown", "-r", "now", '\0'};

char **cmd;

main(argc, argv)
int argc;
char **argv; {
  int i;

  if(argc <= 1) {
    puts("Usage: oper [halt | reboot]\n");
    exit(1);
  }

  if(!strcmp(argv[1], "halt")) {
    cmd = down;
  }
  else if(!strcmp(argv[1], "reboot")) {  
    cmd = bounce;      
  }
  else {
    puts("Usage: oper [halt | reboot\n");
    exit(1);
  }
  setuid(0);
  execvp(*cmd, cmd);
  puts("\nCan't execute.\n");
}
0
 
djc2Author Commented:
Jim,
      It works great! Thanks a ton!
Dave
0

Featured Post

Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now