home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hackers Toolkit v2.0
/
Hackers_Toolkit_v2.0.iso
/
HTML
/
archive
/
Unix
/
c-src
/
chusr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-04
|
4KB
|
204 lines
/*
The problem often seems to arise in dealing with terminated
xterms. (This is yet another reason for why we need a real
session manager.) Rebooting to fix utmp is unduly harsh!
Just use a binary editor of some sort or write a single-purpose
script to hammer a null at the beginning of the entry. In
either case, you'll need to understand the format of utmp(5).
Or you could use the following program, written by a younger
version of myself long ago and far away. It's aesthetically
bothersome in various ways, but it still works well enough to
get the job done on the machines I have to deal with, even today.
To clear an entry on say ttyp5, as root type:
chusr '' ttyp5
--tom
*/
/*
* chusr.c -- change user entry in utmp
*
* Tom Christiansen (1984), for BSD4.2 systems
*
* (various minor hacks since then, like 4.3 compat stuff)
*/
#include <stdio.h>
#include <pwd.h>
#include <sys/file.h>
#include <sysexits.h>
#include <syslog.h>
#include <utmp.h>
#define SCPYN(to,from) (void) strncpy(to,from,sizeof(to))
#ifndef BSD42
# define BSD43 1
#endif
char *strncpy ();
char *ttyname ();
char *index ();
char *rindex ();
int strncmp ();
main (ac, av)
char **av;
{
struct utmp utmp; /* new utmp entry for utmp file */
int nentries, /* how many we got */
ufd, /* utmp's fd */
tslot, /* where to put the entry */
tflag = 0; /* update time? */
char *mytty = "/dev/ttyXXXX",
*ufile = "/etc/utmp",
*s;
if (ac < 2 || ac > 4)
usage (*av);
if (!strcmp (av[1], "-t")) {
tflag++;
av++;
ac--;
}
s = av[2];
if ((ufd = open (ufile, O_RDWR)) < 0) {
perror (ufile);
exit (EX_OSFILE);
}
if (ac == 2) {
if ((mytty = ttyname (fileno (stdin))) == NULL) {
fprintf (stderr, "%s: no tty\n", *av);
exit (EX_UNAVAILABLE);
}
} else {
if (strlen (s) == 2) {
if (s[0] == 'c' && s[1] == 'o')
strcpy (rindex (mytty, '/') + 1, "console");
else if (s[0] == 'e' && s[1] == 'x')
strcpy (rindex (mytty, '/') + 1, "express");
else
strcpy (index (mytty, 'X'), s);
} else {
char *i1 = index (mytty, 't');
char *i2 = index (s, 't');
if (!i1) {
printf(stderr,"no t in %s\n", mytty);
exit(17);
}
if (!i2) {
printf(stderr,"no t in %s\n", s);
exit(18);
}
strncpy (i1, i2, 7);
}
}
mytty += 5; /* skip "/dev/" */
if (!(tslot = ttyslot (mytty))) {
fprintf (stderr, "no tty\n");
exit (1);
}
lseek (ufd, (long) (tslot * sizeof (utmp)), 0);
read (ufd, (char *) &utmp, sizeof (utmp));
#ifdef LOG_AUTH
openlog ("chusr", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
#else
openlog ("chusr", LOG_PID);
#endif
syslog (LOG_NOTICE, "\"%.*s\" changed to \"%s\" on %s\n",
sizeof (utmp.ut_name), utmp.ut_name, av[1], mytty);
closelog();
SCPYN (utmp.ut_name, av[1]);
SCPYN (utmp.ut_line, mytty);
if (ac == 4)
SCPYN (utmp.ut_host, av[3]);
if (tflag)
time (&utmp.ut_time);
lseek (ufd, (long) (tslot * sizeof (utmp)), 0);
write (ufd, (char *) &utmp, sizeof (utmp));
(void) close (ufd);
}
usage (name)
char *name;
{
fprintf (stderr, "usage: %s user [-t] [ tty [whence] ]\n", name);
exit (EX_USAGE);
}
/*
/*
* Return the number of the slot in the utmp file
* corresponding to the passed tty.
* returns 0 on error.
*/
char *getttys ();
static char ttys[] = "/etc/ttys";
#define NULL 0
ttyslot (tty)
register char *tty;
{
register char *tp, *p;
register s;
FILE *tf;
tp = tty;
if ((p = rindex (tp, '/')) == NULL)
p = tp;
else
p++;
if ((tf = fopen (ttys, "r")) == NULL)
return (0);
s = 0;
while (tp = getttys (tf)) {
s++;
if (strncmp (p, tp, strlen (p)) == 0) {
fclose (tf);
return (s);
}
}
fclose (tf);
return (0);
}
static char *
getttys (f)
FILE *f;
{
static char line[256];
register char *lp;
do {
if (fgets (line, 256, f) == NULL)
return NULL;
} while (*line == '#'); /* ignore comment lines */
for (lp = line;; lp++) {
if ((*lp == '\t') || (*lp == ' ') || (*lp == '\n')) {
*lp = '\0';
#ifdef BSD43
return (line);
#else
return (line + 2);
#endif
}
}
}