[comp.sources.misc] v20i043: us - 'su' type program for Coherent users, Part01/01

gdm@shrdlu.UUCP (Giles D Malet) (06/07/91)

Submitted-by: Giles D Malet <gdm@shrdlu.UUCP>
Posting-number: Volume 20, Issue 43
Archive-name: us/part01

This program is used to overcome the MWC Coherent problem of running cron
as daemon. This results in not being able to 'su' to anything that has a 
password.  Cron should run as root !

syntax : us [-v] userid loadmodule args....

us        : name of this prog - change it if you wish
    -v        : verbose (for debugging, if you like)
    userid    : a valid userid in /etc/passwd
 loadmodule   : runs this prog after setting uid / group as requested
    args...   : optional args passed to called prog

 eg, in crontab : 10 * * * * us news /usr/lib/news/prog arg1 arg2
     runs prog as news, with given 2 args.
 To test, use the -v flag, and redirect stderr to a file, as in
    10 * * * * us -v news /usr/lib/news/prog arg1 arg2 2>/tmp/cron.err
    Check contents of the file after prog has run.

Giles D Malet
{robohack,spocom}shrdlu!gdm	Toronto, Canada
--
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  us.c
# Wrapped by kent@sparky on Thu Jun  6 23:28:49 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive."'
if test -f 'us.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'us.c'\"
else
  echo shar: Extracting \"'us.c'\" \(5101 characters\)
  sed "s/^X//" >'us.c' <<'END_OF_FILE'
X/* us.c
X * Program to overcome the MWC Coherent problem of running cron as daemon.
X * This results in not being able to 'su' to anything that has a password.
X * Cron should run as root !
X *
X * syntax : us [-v] userid loadmodule args....
X *
X * us		: name of this prog - change it if you wish
X * -v		: verbose (for debugging, if you like)
X * userid	: a valid userid in /etc/passwd
X * loadmodule   : runs this prog after setting uid / group as requested
X * args...	: optional args passed to called prog
X *
X * eg, in crontab : 10 * * * * us news /usr/lib/news/prog arg1 arg2
X *     runs prog as news, with given 2 args.
X * To test, use the -v flag, and redirect stderr to a file, as in
X *	10 * * * * us -v news /usr/lib/news/prog arg1 arg2 2>/tmp/cron.err
X *	Check contents of the file after prog has run.
X *
X * Note: To execute a shell script, must invoke the shell first.
X *  eg	01 00 * * *	us uucp sh /usr/lib/uucp/uumvlog 5
X *  Thus, us switched to uucp id, then invokes sh to run script uumlog,
X *  passing parm '5'.
X *
X * Compile program -	cc -O us.c
X * Ensure cron can find it - put in /bin or somewhere in 'system' path,
X *  or specify full path to it on command line in crontab.
X * This program must be owner / group / setuid / setgrp root !
X * ie chown root us
X *    chgrp root us
X *    chmod 6511 us
X * Prog will fail if this is not done after installing.
X * Will only run if caller is root or daemon.
X *
X * Mail me if you have problems or need help.
X * Author: Giles D Malet ( gdm@shrdlu.UUCP ) Toronto, Canada 5/5/91          
X *			or mwcbbs!shrdlu!gdm if you prefer.
X *
X * Do what you want to this program - it is public domain, and whoever wants
X * to use / hack it, may. I accept no responsibility for it's use, and all
X * the usual disclaimers......
X */
X
X#include	<stdio.h>
X#include	<string.h>
X
Xextern  int     optind, opterr;
Xextern  char    *optarg;
X
X#define TRUE 1
X#define FALSE 0
X
Xchar 	**Gargv;
Xint     Verbose = FALSE;	/* -v flag */
Xint	usr,grp;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	int c;
X	Gargv = argv;	/* Give global access */
X
X	while ((c = getopt(argc, argv, "v")) != EOF)
X	{
X		switch (c)
X		{
X		case 'v':
X			Verbose = TRUE;
X			fprintf(stderr,"%s: Verbose requested\n", argv[0]);
X			break;
X		default:
X			usage();	/* does not return */
X		}
X	}
X
X	if ( argc < (optind+2) )
X		usage();
X
X	c = getuid();
X	if (Verbose == TRUE)
X		fprintf(stderr,"running as uid %d\n", c);
X
X	if ( ( c != find_id("root") ) &&
X	     ( c != find_id("daemon") )) {
X		fprintf(stderr,"%s: can only be run by root or daemon\n", argv[0]);
X		exit(1);
X	}
X
X	if (Verbose == TRUE)
X		fprintf(stderr," - Okay\n", c);
X
X	if ( find_id(argv[optind]) == -1 ) {
X		fprintf(stderr,
X			"%s: can't find user %s in /etc/passwd\n",
X			argv[0], argv[optind]);
X		exit(1);
X	}
X	
X	if ( setgid(grp) == -1) {
X		fprintf(stderr,"%s: setgid to %d failed\n", argv[0],grp);
X		exit (1);
X	}
X
X	if ( setuid(usr) == -1) {	
X		fprintf(stderr,"%s: setuid to %d failed\n", argv[0],usr);
X		exit (1);
X	}
X
X	if (Verbose == TRUE)
X		fprintf(stderr,"execvp()'ing %s...\n", argv[optind+1]);
X
X	fflush(stderr);
X
X	execvp(argv[optind+1], &argv[optind+1]);
X
X	fprintf(stderr,"execvp(%s,...) failed.\n", argv[optind+1]);
X	fflush(stderr);
X	exit(1);
X}
X
Xusage()
X{
X	(void) fprintf(stderr,
X		"usage: %s [-v] filename args...\n", Gargv[0]);
X	exit(1);
X}
X
X/* Search /etc/passwd for given name.
X * Returns uid value, also stores uid in usr, group in grp (globals).
X * Returns -1 if not found.
X * Assumes passwd format of user:password:uid:group:.... 
X */
Xfind_id(name)
Xchar *name;
X{
X	FILE *fp;
X	char *cp;
X	char buf[128];
X	int len = strlen(name);
X
X	if (Verbose == TRUE)
X		fprintf(stderr,"Looking for user %s\n", name);
X
X	if ( (fp = fopen("/etc/passwd","r")) == NULL ) {
X		fprintf(stderr,"%s: unable to open /etc/passwd\n", Gargv[0]);
X		exit(1);
X	}
X
X	for (;;) {
X		if ( (cp = fgets(buf, 127, fp)) == NULL ) {
X			if (Verbose == TRUE)
X				fprintf(stderr,"EOF - not found.\n");
X			fclose(fp);
X			return -1;
X		}
X
X		if ( strlen(buf) < len + 5 ) {
X			if (Verbose == TRUE)
X				fprintf(stderr,"%s - too short\n", buf);
X			continue;
X		}
X
X		if ( strncmp(cp, name, len) != 0 ) {
X			if (Verbose == TRUE)
X				fprintf(stderr,"%s - no match\n", buf);
X			continue;
X		}
X
X		if ( buf[len] != ':' ) {
X			if (Verbose == TRUE)
X				fprintf(stderr,"%s - nearly !\n", buf);
X			continue;	/* name too short */
X		}
X
X		if (Verbose == TRUE)
X			fprintf(stderr,"%s - got it\n", buf);
X
X		for ( cp = &buf[len+1] ; (*cp != ':') && (*cp != '0') ; cp++) ;
X
X		if ( *cp == '0' ) {
X			if (Verbose == TRUE)
X				fprintf(stderr," - unexpected end of string\n");
X			continue;
X		}
X
X
X		for ( cp++,usr=0 ;
X			isdigit(*cp) ;
X			usr = (usr * 10) + (*cp++ -'0') ) ;
X
X		if ( *cp != ':' ) {
X			if (Verbose == TRUE)
X				fprintf(stderr," - don't understand uid format\n");
X			continue;
X		}
X
X		for ( cp++,grp=0 ;
X			isdigit(*cp) ;
X			grp = (grp * 10) + (*cp++ -'0') ) ;
X
X		if ( *cp != ':' ) {
X			if (Verbose == TRUE)
X				fprintf(stderr," - don't understand grp format\n");
X			continue;
X		}
X
X		fclose(fp);
X		break;
X	}
X
X	if (Verbose == TRUE)
X		fprintf(stderr," user %s - uid is %d, grp id %d\n", name,usr,grp);			
X	
X	return usr;
X}
END_OF_FILE
  if test 5101 -ne `wc -c <'us.c'`; then
    echo shar: \"'us.c'\" unpacked with wrong size!
  fi
  # end of 'us.c'
fi
echo shar: End of archive.
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.