home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume3
/
chsh
< prev
next >
Wrap
Text File
|
1986-11-30
|
3KB
|
134 lines
Subject: chsh chfn for SV
Newsgroups: mod.sources
Approved: jpn@panda.UUCP
Mod.sources: Volume 3, Issue 98
Submitted by: decvax!cwruecmp!rexago1!rich (K. Richard Magill)
I got tired of editting passwd files so...
This is tested & running on a 3b2/300 SV.2.2. It uses a lot of library
routines that probably don't exist outside SV. (sorry).
----hack & slash here----
/*
* I AM NOT A SHELL ARCHIVE!
*
* This file is chsh.c and contains a public domain version
* of chsh/chfn intended for SV. Calling sequence is
*
* chfn user new_name
* or chsh user new_shell
*
* A null name means a null name. A null shell means /bin/sh.
* Your old passwd file is stored in /etc/passwd~. Protections
* and passwd requests work like su. To install use:
*
* make chsh
* chmod 4555 chsh
* ln chsh /usr/lbin (or some such)
* ln chsh /usr/lbin/chfn
*
* AAAAnyway, you get the idea.
*
* K. Richard Magill, 26-jan-86.
* Last Mod 26-jan-86, rich.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#define WATCH(x) if(x){perror(argv[0]);return(-1);}
char *PASSWD = "/etc/passwd";
char *BACKUP = "/etc/passwd~";
char *TEMP = "/tmp/chshXXXXXX";
void endpwent(), perror();
char *crypt(), *getpass(), *mktemp();
struct passwd *getpwent(), *getpwnam(), *fgetpwent();
main(argc, argv)
int argc;
char **argv;
{
register int i;
register struct passwd *p;
FILE *fin, *fout;
int target_id;
struct stat stat_buf;
if (argc < 2 || argc > 3) {
(void) fprintf(stderr, "usage: %s login shell\n", argv[0]);
return(-1);
} /* if usage error */
/* is this person real? */
if ((p = getpwnam(argv[1])) == NULL) {
(void) fprintf(stderr, "%s: don't know %s\n",
argv[0], argv[1]);
return(-1);
} /* if person isn't real */
/* do we have permission to do this? */
target_id = p->pw_uid;
if ((i = getuid()) != 0 && i != target_id) {
char salt[3];
salt[0] = p->pw_passwd[0];
salt[1] = p->pw_passwd[1];
salt[3] = '\0';
if (*p->pw_passwd != '\0'
&& strncmp(crypt(getpass("Password: "), salt),
p->pw_passwd, 8)) {
(void) fprintf(stderr, "Sorry.\n");
return(-1);
} /* passwd didn't match */
} /* check for permission */
/* set up files */
endpwent(); /* close passwd file */
WATCH((fin = fopen(PASSWD, "r")) == NULL);
WATCH((fout = fopen(mktemp(TEMP), "w")) == NULL);
while ((p = fgetpwent(fin)) != NULL) {
if (p->pw_uid == target_id) {
if (strcmp(argv[0], "chsh")) {
p->pw_gecos = argv[2];
} else {
p->pw_shell = argv[2] == NULL ? "/bin/sh"
: argv[2];
}
} /* if this is entry to be changed */
WATCH(putpwent(p, fout));
} /* while not eof (we couldn't recognize an error) */
/* close files */
WATCH(fclose(fin) || fclose(fout));
/* remove old backup if it exists */
WATCH(!stat(BACKUP, &stat_buf) && unlink(BACKUP));
/* make current passwd file backup */
WATCH(link(PASSWD, BACKUP) || unlink(PASSWD));
/* make new file passwd */
WATCH(link(TEMP, PASSWD) || unlink(TEMP));
/* must have succeeded */
return(0);
} /* main */
/* EOF */