221 lines
4.2 KiB
C
221 lines
4.2 KiB
C
/* Copyright (c) 1984 AT&T */
|
|
/* All Rights Reserved */
|
|
|
|
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
|
/* The copyright notice above does not evidence any */
|
|
/* actual or intended publication of such source code. */
|
|
|
|
#ifndef lint
|
|
static char sccsid[] = "@(#)pwck.c 1.1 94/10/31 SMI"; /* from S5R3 1.6 */
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/param.h>
|
|
#include <sys/signal.h>
|
|
#include <sys/sysmacros.h>
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#define ERROR1 "Too many/few fields"
|
|
#define ERROR2 "Bad character(s) in login name"
|
|
#define ERROR2a "First char in login name not lower case alpha"
|
|
#define ERROR2b "No login name"
|
|
#define ERROR2c "No netgroup name"
|
|
#define ERROR2d "First char in netgroup name not lower case alpha"
|
|
#define ERROR2e "Bad character(s) in netgroup name"
|
|
#define ERROR3 "Login name too long"
|
|
#define ERROR4 "Invalid UID"
|
|
#define ERROR5 "Invalid GID"
|
|
#define ERROR6 "Login directory not found"
|
|
#define ERROR6a "No login directory"
|
|
#define ERROR7 "Optional shell file not found"
|
|
|
|
int eflag, code=0;
|
|
int badc;
|
|
char buf[512];
|
|
|
|
main(argc,argv)
|
|
|
|
int argc;
|
|
char **argv;
|
|
|
|
{
|
|
int delim[512];
|
|
char logbuf[80];
|
|
FILE *fopen(), *fptr;
|
|
char *fgets();
|
|
int error();
|
|
struct stat obuf;
|
|
long uid, gid;
|
|
int len;
|
|
register int i, j, colons;
|
|
int yellowpages, netgroup;
|
|
int nlognamec;
|
|
char *pw_file;
|
|
|
|
if(argc == 1) pw_file="/etc/passwd";
|
|
else pw_file=argv[1];
|
|
|
|
if((fptr=fopen(pw_file,"r"))==NULL) {
|
|
fprintf(stderr,"cannot open %s\n",pw_file);
|
|
exit(1);
|
|
}
|
|
|
|
while(fgets(buf,512,fptr)!=NULL) {
|
|
|
|
colons=0;
|
|
badc=0;
|
|
uid=gid=0l;
|
|
eflag=0;
|
|
yellowpages=0;
|
|
netgroup=0;
|
|
|
|
/* See if this is a NIS reference */
|
|
|
|
if(buf[0] == '+') {
|
|
yellowpages++;
|
|
}
|
|
|
|
/* Check number of fields */
|
|
|
|
for(i=0 ; buf[i]!=NULL; i++) {
|
|
if(buf[i]==':') {
|
|
delim[colons]=i;
|
|
++colons;
|
|
}
|
|
delim[6]=i;
|
|
delim[7]=NULL;
|
|
}
|
|
if(colons != 6) {
|
|
if(!yellowpages) error(ERROR1);
|
|
continue;
|
|
}
|
|
|
|
/* Check that first character is alpha and rest alphanumeric */
|
|
|
|
i = 0;
|
|
if(yellowpages) {
|
|
i++;
|
|
if(buf[1] == '\0' || buf[1] == ':') continue;
|
|
if(buf[1] == '@') {
|
|
i++;
|
|
netgroup++;
|
|
if(buf[0] == ':') {
|
|
error(ERROR2c);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if(buf[0] == ':') {
|
|
error(ERROR2b);
|
|
}
|
|
}
|
|
if(!(islower(buf[i]))) {
|
|
error(netgroup? ERROR2d: ERROR2a);
|
|
}
|
|
for(nlognamec=0; buf[i]!=':'; nlognamec++, i++) {
|
|
if(islower(buf[i]));
|
|
else if(isdigit(buf[i]));
|
|
else ++badc;
|
|
}
|
|
if(badc > 0) {
|
|
error(netgroup? ERROR2e: ERROR2);
|
|
}
|
|
|
|
/* Check for valid number of characters in logname */
|
|
|
|
if(!netgroup && nlognamec > 8) {
|
|
error(ERROR3);
|
|
}
|
|
|
|
/* Check that UID is numeric and <= 65535 */
|
|
|
|
len = (delim[2]-delim[1])-1;
|
|
if(len > 5 || (!yellowpages && len == 0)) {
|
|
error(ERROR4);
|
|
}
|
|
else {
|
|
for (i=(delim[1]+1); i < delim[2]; i++) {
|
|
if(!(isdigit(buf[i]))) {
|
|
error(ERROR4);
|
|
break;
|
|
}
|
|
uid = uid*10+(buf[i])-'0';
|
|
}
|
|
if(uid > 65535l || uid < 0l) {
|
|
error(ERROR4);
|
|
}
|
|
}
|
|
|
|
/* Check that GID is numeric and <= 65535 */
|
|
|
|
len = (delim[3]-delim[2])-1;
|
|
if(len > 5 || (!yellowpages && len == 0)) {
|
|
error(ERROR5);
|
|
}
|
|
else {
|
|
for(i=(delim[2]+1); i < delim[3]; i++) {
|
|
if(!(isdigit(buf[i]))) {
|
|
error(ERROR5);
|
|
break;
|
|
}
|
|
gid = gid*10+(buf[i])-'0';
|
|
}
|
|
if(gid > 65535l || gid < 0l) {
|
|
error(ERROR5);
|
|
}
|
|
}
|
|
|
|
/* Stat initial working directory */
|
|
|
|
for(j=0, i=(delim[4]+1); i<delim[5]; j++, i++) {
|
|
logbuf[j]=buf[i];
|
|
}
|
|
if(!yellowpages && logbuf[0] == NULL) {
|
|
error(ERROR6a);
|
|
}
|
|
else {
|
|
if((stat(logbuf,&obuf)) == -1) {
|
|
error(ERROR6);
|
|
}
|
|
}
|
|
for(j=0;j<80;j++) logbuf[j]=NULL;
|
|
|
|
/* Stat of program to use as shell */
|
|
|
|
if((buf[(delim[5]+1)]) != '\n') {
|
|
for(j=0, i=(delim[5]+1); i<delim[6]; j++, i++) {
|
|
logbuf[j]=buf[i];
|
|
}
|
|
if((stat(logbuf,&obuf)) == -1) {
|
|
error(ERROR7);
|
|
}
|
|
for(j=0;j<80;j++) logbuf[j]=NULL;
|
|
}
|
|
}
|
|
fclose(fptr);
|
|
exit(code);
|
|
/* NOTREACHED */
|
|
}
|
|
/* Error printing routine */
|
|
|
|
error(msg)
|
|
|
|
char *msg;
|
|
{
|
|
if(!(eflag)) {
|
|
fprintf(stderr,"\n%s",buf);
|
|
code = 1;
|
|
++eflag;
|
|
}
|
|
if(!(badc)) {
|
|
fprintf(stderr,"\t%s\n",msg);
|
|
return;
|
|
}
|
|
else {
|
|
fprintf(stderr,"\t%d %s\n",badc,msg);
|
|
badc=0;
|
|
return;
|
|
}
|
|
}
|