New Messages
Dear Mr. Ward,
A statement was made in the Question and Answer section
of your November/December
issue which I believe is unfounded.
On page 28, Bjorn Satdeva says, regarding Job Accounting
software
packages, "the few commercial packages I have come
across have
been buggy and cumbersome to deal with."
I think your readers should know that our resource accounting
package
is neither of those things. We have many satisfied customers
using
UNISOL JobAcct. Furthermore, many customers call us
because
they have tried to write their own system accounting
packages and
have run into difficulties. The biggest complaint we
hear about other
commercial packages concerns performance, which is not
a problem with
UNISOL JobAcct.
Sincerely,
Laurie Craig
Director of Marketing
UniSolutions Associates
Redondo Beach, CA 90278
Bjorn's comments reflected his own experience, but should
not be read to imply that all commercial packages are
subject to the
same criticism. Thanks for writing to us.
Editor,
I saw the letter from Guido Beijerwellen in your November/December
1993 issue in which he complains about the availability
of the sysadmin
files via your telephone number.
You suggest CompuServe, but did you know that uunet
keeps copies too?
ftp to ftp.uu.net, go to the directory /published/sysadmin,
and there
you will find the files for 1992 and 1993 in the directories
1992
and 1993.
Other sites where the files are stored can be found
using archie.
I found the following places:
ftp.cs.umn.edu:/pub/doc/published/sysadmin
ftp.uu.net:/published/sysadmin
ftp.ccu.edu.tw:/pub1/document/published/sysadmin
nctuccca.edu.tw:/documents/published/sysadmin
unix.hensa.ac.uk:/pub/uunet/published/sysadmin
src.doc.ic.ac.uk:/media/literary/published/sysadmin
For those close to the Netherlands, we keep a mirror
of some of the published documents on our archive server
ftp.nl.net,
in the directory /pub/published. This server can also
be reached via
our mail server: send mail to mail-server@nl.net and
you will get
help from the mailserver.
Since this would be the easiest way fo Mr. Beijerwellen
to obtain
the files, I have sent him a copy of this e-mail.
Jan Christiaan van Winkel
archive maintainer jc@inter.nl.net
Alternative e-mail addresses: jc@oreo.atcmp.nl and jc@atcmp.nl
Many thanks to you for this useful information. Readers
unfamiliar with "archie" can look to Chris
Bush's article,
"Internet Online Services: archie," beginning
on p. 37 of
this issue, for an explanation.
Dear SysAdm:
Nice magazine, I enjoy reading it.
I have a question though:
Does anybody at SysAdm know where I may obtain information
about the
CM University Mach project and also about the GNU or
Free Software
Foundation Hurd project? I have very little info on
either, all of
it coming from my GNU magazine.
I appreciate your time and effort.
Thank you.
Ennis McCaffrey
emccaff@pica.army.mil
We're not able to provide this information, but feel
sure
that our readers can. If you can help Mr. McCaffrey
out, e-mail him
at the address above.
Editor:
A curious reader not to long ago sent me a question
regarding UUCP
and alarm messages. Before I reply to this forum with
a general response,
I am asking that individual to re-send his message to
me. You can
reach me via e-mail at chare@unilabs.org, or chare@choreo.ca.
Thanks.
Chris Hare
chare@unilabs.org
If you had this question for Chris, please contact him
again.
Sys Admin Editor,
One of the great things about system administration
is that there
can be so many ways to solve a problem! In your checkcron
script from
Nov/Dec 1993, you have the following line:
ps -fu root | sed '/grep/d' | grep cron
For those who are not as familiar with using sed, the
following line should accomplish the same thing:
ps -fu root | grep cron | grep -v grep
Here I use the -v option of grep to remove any lines
containing grep. Again, due to the way the pipeline
works, the second
grep not only filters out the search for cron, but itself
as well!
Jason Vogel
System Administrator
Sunbelt Business Computers
jason@sunbelt.com
Thanks for the elaboration -- the greater thing about
system administration is system administrators' willingness
to share
such tips with each other!
From: Chris Linstruth <cjl@aop.com>
Subject: New Messages November/December 1993
To: saletter@rdpub.com
A reader queried about VMS-like virtual terminals in
this issue [Nov/Dec
1993]. I think the freeware 'screen' package from the
FSF should fill
their needs...
It allows multiple sessions to be run (each on a pty)
on regular ASCII
terminals (vt100 works best). Screen can be configured
to not drop
these sessions when it terminates so they can be reattached
at a later
time. It works like a champ. I don't know of an ftp
site but I'm sure
it's on all the major GNU archives.
Here's what it looks like.
$ screen -?
Use: screen [-opts] [cmd [args]]
or: screen -r [host.tty]
Options:
-a -- Force all capabilities into each window's termcap.
-A -[r|R] -- Adapt all windows to the new display width & height.
-c file -- Read configuration file instead of '.screenrc'.
-d (-r) -- Detach the elsewhere running screen (and reattach here).
-D (-r) -- Detach and logout remote (and reattach here).
-e xy -- Change command characters.
-f -- Flow control on, -fn = off, -fa = auto.
-h -- lines Set the size of the scrollback history buffer.
-i -- Interrupt output sooner when flow control is on.
-l -- Login mode on (update /etc/utmp), -ln = off.
-list or -ls. -- Do nothing, just list our SockDir.
-L -- Terminal's last character can be safely updated.
-m -- ignore $STY variable, do create a new screen session.
-O -- Choose optimal output rather than exact vt100 emulation.
-q -- Quiet startup. Exits with non-zero return code if unsuccessful.
-r -- Reattach to a detached screen process.
-R -- Reattach if possible, otherwise start a new session.
-s -- shell Shell to execute rather than $SHELL.
-S sockname -- Name this session <pid>.sockname instead of <pid>.<tty>.<host>.
-t title -- Set command's a.k.a. (window title).
-T term -- Use term as $TERM for windows, rather than "screen".
-v -- Print "Screen version 3.05.00 (FAU) 22-Jul-93".
-wipe -- Do nothing, just clean up SockDir.
-x -- Attach to a not detached screen. (Multi display mode).
Chris Linstruth
Capitol Heights, Maryland
cjl@aop.com
This is one I'm not familiar with -- let's hope it does
the trick.
Editor:
In your November/December 1993 issue of Sys Admin, you
printed an
article by Don Pipkin titled "A Revised sudo: Managing
Super-User
Privileges."
I ftp-ed the source code from this article and was mildly
disappointed
when it failed to work on our Pyramid MIServer-ES (running
SVR4).
A cursory examination of the code showed that it was
not using the
function calls that were created to handle the shadow
password file
(/etc/shadow). I asked a colleague, Paul Ready, to add
in the corresponding
functions, which he did. With those changes, together
with a couple
of minor changes elsewhere, the code now compiles and
runs successfully
on our Pyramid box.
The code that Paul added tests the length of the password
field in
/etc/passwd and, if it is not 13 chars long, calls the
shadow password
functions. So this code works with both shadow and non-shadow
passwords.
We have tested in on both the Pyramid (1.1-93c062 dcosx
MIServer-ES
4/256 r3000) and under SCO Xenix 2.3.4.
Because of the changes from tabs to spaces and back
again over the
many transfers this source has had, the 'diff' between
the two versions
does not help too much!, so, here is the whole source.
Ben Thomas, P.Eng
ben@ShoppersDrugMart.CA
Thanks for taking the time to investigate and solve
the problem. Interested readers will find the code in below.
Listing 1: new sudo.c, revised by Ben Thomas and Paul Ready
/*
** sudo.c
*/
/*
** Configurable constants
*/
#define SECURE_PATH
"/bin:/usr/sbin:/sbin:/usr/lbin:/opt/x25/bin/usr/bin/X11"
#define USERFILE "/usr/local/adm/sudoers"
#define LOGFILE "/usr/local/adm/sudolog"
#define TIMEDIR "/usr/local/adm/sudocheck/"
#define TIME 5 /* minutes */
#define SUDO_COP "root@localhost"
/*
** To install create the directories in the SECURE_PATH
** and TIMEDIR and the files USERFILE and LOGFILE.
** Set the owner of these files to root and the permissions
** to og-rw. Change the owner to root for the sudo program
** and set the permissions to 4111 (--s--x--x).
*/
#define BUFSIZE 256
#define SUCCESS 1
#define FAILED -1
#define CONFIG_ERR "Configuration error. " \
"Contact your security manager."
#define CONFIG_SUB "Invalid sudo configuration!"
#define SUID_ERR "Set UID bit not set."
#define STAT_ERR "Couldn't stat user file"
#define OWNER_ERR "User file not owned by root"
#define PERM_ERR "Invalid permissions on user file"
#define OPEN_ERR "Couldn't open user file"
#define USER_ERR "You are not set up to execute " \
"sudo on this machine."
#define USER_SUB "SECURITY** Invalid sudo user!"
#include <ctype.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <grp.h>
#include <shadow.h>
char *getpass();
char *crypt();
char *find_passwd(int user_id);
FILE *check_config(user)
char *user;
{
struct stat statb;
FILE *fp;
if ((setuid(0)) < 0) /* no setuid */
mail(CONFIG_SUB, user, SUID_ERR, CONFIG_ERR);
if (stat(USERFILE, &statb)) /* couldn't stat */
mail(CONFIG_SUB, user, STAT_ERR, CONFIG_ERR);
if (statb.st_uid != 0) /* must be owned by root */
mail(CONFIG_SUB, user, OWNER_ERR, CONFIG_ERR);
if (statb.st_mode & 044) /* should be og-rw */
mail(CONFIG_SUB, user, PERM_ERR, CONFIG_ERR);
if ((fp = fopen(USERFILE, "r")) == 0) /* open err */
mail(CONFIG_SUB, user, OPEN_ERR, CONFIG_ERR);
return(fp);
}
char *get_command_list(fp, name, password)
FILE *fp; char *name; char *password;
{
char buffer[BUFSIZ];
while ((fgets(buffer, BUFSIZ, fp)) != NULL) {
if (buffer[0] == '#') continue; /* skip remarks */
if ((strncmp(buffer, name, strlen(name))) == 0)
if ((get_password(name, password)) == SUCCESS)
return(buffer); /* valid user */
else
return(NULL); /* invalid password */
}
return(NULL); /* invalid user */
}
int get_password(name, password)
char *name; char *password;
{
char fname[200];
char *paswd;
char *encrypted;
struct stat stab;
sprintf (fname, "%s/%s", TIMEDIR, name);
if (stat(fname, &stab) == 0) {
if ((time(NULL) - stab.st_mtime) < (TIME * 60)) {
create_file(fname);
return (SUCCESS);
}
}
paswd = getpass("Password:");
encrypted = crypt(paswd, password);
if (strcmp(password, encrypted)) {
fprintf (stderr, "Password incorrect\n");
return(FAILED);
}
fflush (stderr);
fflush (stdout);
create_file(fname);
return (SUCCESS);
}
create_file(file)
char *file;
{
int descrip;
long timep[2];
if ((descrip = open(file, O_TRUNC|O_CREAT|O_WRONLY, 0700)) > 0) {
close (descrip);
timep[0] = timep[1] = time(0);
utime (file, timep);
}
}
int checkdoer (dp, ap)
char *dp; char *ap;
{
char *cp0, *cp1;
int not_flag = 0;
cp0 = dp;
while (isalnum (*cp0))
cp0++; /* skip past user */
while (*cp0) { /* search until end of line */
while (isspace (*cp0))
cp0++; /* skip to cmd */
if (strncmp (cp0, "not", 3) == 0)
not_flag = 1;
if (strncmp (cp0, "all", 3) == 0)
return (SUCCESS);
cp1 = cp0;
/* find end of this entry */
while (*cp1 != '\n' && !isspace(*cp1))
cp1++;
if (strncmp (cp0, ap, strlen(ap)) == 0) {
cp1 = '\0';
if (not_flag)
return(FAILED);
else
return(SUCCESS);
}
/* move pointer past and keep looking */
while (!isspace (*cp0) && *cp0 != '\n')
cp0++;
if (*cp0 == '\n')
break; /* if EOL then fail */
else
continue;
}
if (not_flag)
return(SUCCESS);
else
return(FAILED);
}
char *log(username, info, argc, argv)
char *username; char *info; int argc; char **argv;
{
FILE *fp;
long now;
char ret_st[BUFSIZ];
if ((fp = fopen(LOGFILE, "a")) == NULL)
mail("WARNING sudo can't open logfile.", username, LOGFILE,
"");
now = time((long*) 0);
fprintf (fp, "%20.20s :", ctime(&now));
fprintf (fp, "%10.10s", info);
fprintf (fp, "%9.9s :",username);
while (argc--) {
fprintf (fp, "%s ", *argv++);
sprintf (ret_st, "%s ", *argv++);
}
fprintf (fp, "\n");
(void) fclose (fp);
return(ret_st);
}
int mail(subject, user, text, err_msg)
char *subject; char *user; char *text; char *err_msg;
{
char hostname[MAXHOSTNAMELEN];
FILE *fd;
FILE *popen();
char cmd[80];
firsthostname (hostname, MAXHOSTNAMELEN);
(void) sprintf (cmd, "/usr/bin/mailx -s \"%s\" %s ", subject,
SUDO_COP);
if ((fd = popen (cmd, "w")) == NULL)
return;
(void) fputs(text, fd);
(void) fputs ("\n\nThought you might want to know.", fd);
(void) pclose(fd);
fprintf(stderr, "%s %s", err_msg, "\n");
exit(1);
}
int firsthostname(n, l)
char *n; int l;
{
(void) gethostname(n, l); /* get full hostname */
n[l - 1] = 0; /* make sure null terminated */
if (n = strchr(n, '.'))
*n = 0; /* put null on '.'*/
}
int main(int argc, char **argv)
{
FILE *userfile;
struct passwd *user;
long uid;
char *valid_cmds;
char *progname;
char *cmd_line;
char *real_passwd;
progname = argv[0];
if (argc < 2) {
fprintf(stderr, "usage: %s cmd\n", progname);
exit(1);
}
uid = getuid();
user = getpwuid(uid);
userfile = check_config(user);
real_passwd = find_passwd(uid);
if ((valid_cmds = get_command_list(userfile, user->pw_name,
real_passwd)) != NULL) {
argv++, argc--;
if (checkdoer(valid_cmds, *argv) != FAILED) {
putenv("PATH=" SECURE_PATH);
putenv("SHELL=/bin/false");
(void) log(user->pw_name, "", argc, argv);
execvp(*argv, argv); /* then do it */
perror(*argv);
} else {
(void) log(user->pw_name, "FAIL ", argc, argv);
fprintf(stderr, "%s: You are not set up to "
"execute %s with sudo on this machine.\n",
progname, *argv);
exit(1);
}
} else {
cmd_line = log(user->pw_name, "FAIL ", argc, argv);
mail(USER_SUB, user->pw_name, cmd_line, USER_ERR);
}
}
char *find_passwd(int user_id)
{
struct passwd *pw, *getpwuid();
struct group *gr, *getgrgid();
struct spwd *spw, *getspnam();
if ((pw = getpwuid(user_id)) == NULL)
return("unknown");
if (strlen(pw->pw_passwd) == 13) {
if ((pw = getpwuid(user_id)) == NULL) {
return("unknown");
} else {
return(pw->pw_passwd);
}
} else {
if ((spw = getspnam(pw->pw_name)) == NULL) {
return("unknown");
} else {
return(spw->sp_pwdp);
}
}
return("unknown");
}
|