home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-22 | 44.2 KB | 2,273 lines |
- Newsgroups: comp.sources.unix
- From: deraadt@cpsc.ucalgary.ca (Theo Deraadt)
- Subject: v25i153: permissions - access control library for YP/NIS environments, Part02/03
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: deraadt@cpsc.ucalgary.ca (Theo Deraadt)
- Posting-Number: Volume 25, Issue 153
- Archive-Name: permissions/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 3)."
- # Contents: in.ftpd/ftpcmd.y in.ftpd/glob.c login/login.c
- # Wrapped by vixie@cognition.pa.dec.com on Tue Mar 10 23:11:21 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'in.ftpd/ftpcmd.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.ftpd/ftpcmd.y'\"
- else
- echo shar: Extracting \"'in.ftpd/ftpcmd.y'\" \(16052 characters\)
- sed "s/^X//" >'in.ftpd/ftpcmd.y' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1985, 1988 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X */
- X
- X/*
- X * Grammar for FTP commands.
- X * See RFC 765.
- X */
- X
- X%{
- X
- X#ifndef lint
- static char sccsid[] = "@(#)ftpcmd.y 1.1 90/03/23 SMI"; /* from UCB 5.16 12/8/88 */
- X#endif
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X
- X#include <netinet/in.h>
- X
- X#include <arpa/ftp.h>
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <ctype.h>
- X#include <pwd.h>
- X#include <setjmp.h>
- X#include <syslog.h>
- X
- extern struct sockaddr_in data_dest;
- extern int logged_in;
- extern struct passwd *pw;
- extern int guest;
- extern int logging;
- extern int type;
- extern int form;
- extern int debug;
- extern int timeout;
- extern int pdata;
- extern char hostname[];
- extern char *globerr;
- extern int usedefault;
- extern int transflag;
- extern char tmpline[];
- char **glob();
- X
- static int cmd_type;
- static int cmd_form;
- static int cmd_bytesz;
- char cbuf[512];
- char *fromname;
- X
- char *index();
- X%}
- X
- X%token
- X A B C E F I
- X L N P R S T
- X
- X SP CRLF COMMA STRING NUMBER
- X
- X USER PASS ACCT REIN QUIT PORT
- X PASV TYPE STRU MODE RETR STOR
- X APPE MLFL MAIL MSND MSOM MSAM
- X MRSQ MRCP ALLO REST RNFR RNTO
- X ABOR DELE CWD LIST NLST SITE
- X STAT HELP NOOP XMKD XRMD XPWD
- X XCUP STOU
- X
- X LEXERR
- X
- X%start cmd_list
- X
- X%%
- X
- cmd_list: /* empty */
- X | cmd_list cmd
- X = {
- X fromname = (char *) 0;
- X }
- X | cmd_list rcmd
- X ;
- X
- cmd: USER SP username CRLF
- X = {
- X user((char *) $3);
- X free((char *) $3);
- X }
- X | PASS SP password CRLF
- X = {
- X pass((char *) $3);
- X free((char *) $3);
- X }
- X | PORT SP host_port CRLF
- X = {
- X usedefault = 0;
- X if (pdata >= 0) {
- X (void) close(pdata);
- X pdata = -1;
- X }
- X reply(200, "PORT command successful.");
- X }
- X | PASV CRLF
- X = {
- X passive();
- X }
- X | TYPE SP type_code CRLF
- X = {
- X switch (cmd_type) {
- X
- X case TYPE_A:
- X if (cmd_form == FORM_N) {
- X reply(200, "Type set to A.");
- X type = cmd_type;
- X form = cmd_form;
- X } else
- X reply(504, "Form must be N.");
- X break;
- X
- X case TYPE_E:
- X reply(504, "Type E not implemented.");
- X break;
- X
- X case TYPE_I:
- X reply(200, "Type set to I.");
- X type = cmd_type;
- X break;
- X
- X case TYPE_L:
- X if (cmd_bytesz == 8) {
- X reply(200,
- X "Type set to L (byte size 8).");
- X type = cmd_type;
- X } else
- X reply(504, "Byte size must be 8.");
- X }
- X }
- X | STRU SP struct_code CRLF
- X = {
- X switch ($3) {
- X
- X case STRU_F:
- X reply(200, "STRU F ok.");
- X break;
- X
- X default:
- X reply(504, "Unimplemented STRU type.");
- X }
- X }
- X | MODE SP mode_code CRLF
- X = {
- X switch ($3) {
- X
- X case MODE_S:
- X reply(200, "MODE S ok.");
- X break;
- X
- X default:
- X reply(502, "Unimplemented MODE type.");
- X }
- X }
- X | ALLO SP NUMBER CRLF
- X = {
- X reply(202, "ALLO command ignored.");
- X }
- X | RETR check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X retrieve((char *) 0, (char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | STOR check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X store((char *) $4, "w", 0);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | APPE check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X store((char *) $4, "a", 0);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | NLST check_login CRLF
- X = {
- X if ($2)
- X retrieve("/bin/ls", "");
- X }
- X | NLST check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X retrieve("/bin/ls %s", (char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | LIST check_login CRLF
- X = {
- X if ($2)
- X retrieve("/bin/ls -lg", "");
- X }
- X | LIST check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X retrieve("/bin/ls -lg %s", (char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | DELE check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X delete((char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | RNTO SP pathname CRLF
- X = {
- X if (fromname) {
- X renamecmd(fromname, (char *) $3);
- X free(fromname);
- X fromname = (char *) 0;
- X } else {
- X reply(503, "Bad sequence of commands.");
- X }
- X free((char *) $3);
- X }
- X | ABOR CRLF
- X = {
- X reply(225, "ABOR command successful.");
- X }
- X | CWD check_login CRLF
- X = {
- X if ($2)
- X cwd(pw->pw_dir);
- X }
- X | CWD check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X cwd((char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | HELP CRLF
- X = {
- X help((char *) 0);
- X }
- X | HELP SP STRING CRLF
- X = {
- X help((char *) $3);
- X }
- X | NOOP CRLF
- X = {
- X reply(200, "NOOP command successful.");
- X }
- X | XMKD check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X makedir((char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | XRMD check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X removedir((char *) $4);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | XPWD check_login CRLF
- X = {
- X if ($2)
- X pwd();
- X }
- X | XCUP check_login CRLF
- X = {
- X if ($2)
- X cwd("..");
- X }
- X | STOU check_login SP pathname CRLF
- X = {
- X if ($2 && $4 != NULL)
- X store((char *) $4, "w", 1);
- X if ($4 != NULL)
- X free((char *) $4);
- X }
- X | QUIT CRLF
- X = {
- X reply(221, "Goodbye.");
- X dologout(0);
- X }
- X | error CRLF
- X = {
- X yyerrok;
- X }
- X ;
- X
- rcmd: RNFR check_login SP pathname CRLF
- X = {
- X char *renamefrom();
- X
- X if ($2 && $4) {
- X fromname = renamefrom((char *) $4);
- X if (fromname == (char *) 0 && $4) {
- X free((char *) $4);
- X }
- X }
- X }
- X ;
- X
- username: STRING
- X ;
- X
- password: /* empty */
- X = {
- X $$ = (int) "";
- X }
- X | STRING
- X ;
- X
- byte_size: NUMBER
- X ;
- X
- host_port: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
- X NUMBER COMMA NUMBER
- X = {
- X register char *a, *p;
- X
- X a = (char *)&data_dest.sin_addr;
- X a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
- X p = (char *)&data_dest.sin_port;
- X p[0] = $9; p[1] = $11;
- X data_dest.sin_family = AF_INET;
- X }
- X ;
- X
- form_code: N
- X = {
- X $$ = FORM_N;
- X }
- X | T
- X = {
- X $$ = FORM_T;
- X }
- X | C
- X = {
- X $$ = FORM_C;
- X }
- X ;
- X
- type_code: A
- X = {
- X cmd_type = TYPE_A;
- X cmd_form = FORM_N;
- X }
- X | A SP form_code
- X = {
- X cmd_type = TYPE_A;
- X cmd_form = $3;
- X }
- X | E
- X = {
- X cmd_type = TYPE_E;
- X cmd_form = FORM_N;
- X }
- X | E SP form_code
- X = {
- X cmd_type = TYPE_E;
- X cmd_form = $3;
- X }
- X | I
- X = {
- X cmd_type = TYPE_I;
- X }
- X | L
- X = {
- X cmd_type = TYPE_L;
- X cmd_bytesz = 8;
- X }
- X | L SP byte_size
- X = {
- X cmd_type = TYPE_L;
- X cmd_bytesz = $3;
- X }
- X /* this is for a bug in the BBN ftp */
- X | L byte_size
- X = {
- X cmd_type = TYPE_L;
- X cmd_bytesz = $2;
- X }
- X ;
- X
- struct_code: F
- X = {
- X $$ = STRU_F;
- X }
- X | R
- X = {
- X $$ = STRU_R;
- X }
- X | P
- X = {
- X $$ = STRU_P;
- X }
- X ;
- X
- mode_code: S
- X = {
- X $$ = MODE_S;
- X }
- X | B
- X = {
- X $$ = MODE_B;
- X }
- X | C
- X = {
- X $$ = MODE_C;
- X }
- X ;
- X
- pathname: pathstring
- X = {
- X /*
- X * Problem: this production is used for all pathname
- X * processing, but only gives a 550 error reply.
- X * This is a valid reply in some cases but not in others.
- X */
- X if (logged_in && $1 && strncmp((char *) $1, "~", 1) == 0) {
- X $$ = (int)*glob((char *) $1);
- X if (globerr != NULL) {
- X reply(550, globerr);
- X $$ = NULL;
- X }
- X free((char *) $1);
- X } else
- X $$ = $1;
- X }
- X ;
- X
- pathstring: STRING
- X ;
- X
- check_login: /* empty */
- X = {
- X if (logged_in)
- X $$ = 1;
- X else {
- X reply(530, "Please login with USER and PASS.");
- X $$ = 0;
- X }
- X }
- X ;
- X
- X%%
- X
- extern jmp_buf errcatch;
- X
- X#define CMD 0 /* beginning of command */
- X#define ARGS 1 /* expect miscellaneous arguments */
- X#define STR1 2 /* expect SP followed by STRING */
- X#define STR2 3 /* expect STRING */
- X#define OSTR 4 /* optional SP then STRING */
- X#define ZSTR1 5 /* SP then optional STRING */
- X#define ZSTR2 6 /* optional STRING after SP */
- X
- struct tab {
- X char *name;
- X short token;
- X short state;
- X short implemented; /* 1 if command is implemented */
- X char *help;
- X};
- X
- struct tab cmdtab[] = { /* In order defined in RFC 765 */
- X { "USER", USER, STR1, 1, "<sp> username" },
- X { "PASS", PASS, ZSTR1, 1, "<sp> password" },
- X { "ACCT", ACCT, STR1, 0, "(specify account)" },
- X { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
- X { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
- X { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
- X { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
- X { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
- X { "STRU", STRU, ARGS, 1, "(specify file structure)" },
- X { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
- X { "RETR", RETR, STR1, 1, "<sp> file-name" },
- X { "STOR", STOR, STR1, 1, "<sp> file-name" },
- X { "APPE", APPE, STR1, 1, "<sp> file-name" },
- X { "MLFL", MLFL, OSTR, 0, "(mail file)" },
- X { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
- X { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
- X { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
- X { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
- X { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
- X { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
- X { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
- X { "REST", REST, STR1, 0, "(restart command)" },
- X { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
- X { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
- X { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
- X { "DELE", DELE, STR1, 1, "<sp> file-name" },
- X { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
- X { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
- X { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
- X { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
- X { "SITE", SITE, STR1, 0, "(get site parameters)" },
- X { "STAT", STAT, OSTR, 0, "(get server status)" },
- X { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- X { "NOOP", NOOP, ARGS, 1, "" },
- X { "MKD", XMKD, STR1, 1, "<sp> path-name" },
- X { "XMKD", XMKD, STR1, 1, "<sp> path-name" },
- X { "RMD", XRMD, STR1, 1, "<sp> path-name" },
- X { "XRMD", XRMD, STR1, 1, "<sp> path-name" },
- X { "PWD", XPWD, ARGS, 1, "(return current directory)" },
- X { "XPWD", XPWD, ARGS, 1, "(return current directory)" },
- X { "CDUP", XCUP, ARGS, 1, "(change to parent directory)" },
- X { "XCUP", XCUP, ARGS, 1, "(change to parent directory)" },
- X { "STOU", STOU, STR1, 1, "<sp> file-name" },
- X { NULL, 0, 0, 0, 0 }
- X};
- X
- struct tab *
- lookup(cmd)
- X char *cmd;
- X{
- X register struct tab *p;
- X
- X for (p = cmdtab; p->name != NULL; p++)
- X if (strcmp(cmd, p->name) == 0)
- X return (p);
- X return (0);
- X}
- X
- X#include <arpa/telnet.h>
- X
- X/*
- X * getline - a hacked up version of fgets to ignore TELNET escape codes.
- X */
- char *
- getline(s, n, iop)
- X char *s;
- X register FILE *iop;
- X{
- X register c;
- X register char *cs;
- X
- X cs = s;
- X/* tmpline may contain saved command from urgent mode interruption */
- X for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
- X *cs++ = tmpline[c];
- X if (tmpline[c] == '\n') {
- X *cs++ = '\0';
- X if (debug)
- X syslog(LOG_DEBUG, "command: %s", s);
- X tmpline[0] = '\0';
- X return(s);
- X }
- X if (c == 0)
- X tmpline[0] = '\0';
- X }
- X while ((c = getc(iop)) != EOF) {
- X c &= 0377;
- X if (c == IAC) {
- X if ((c = getc(iop)) != EOF) {
- X c &= 0377;
- X switch (c) {
- X case WILL:
- X case WONT:
- X c = getc(iop);
- X printf("%c%c%c", IAC, DONT, 0377&c);
- X (void) fflush(stdout);
- X continue;
- X case DO:
- X case DONT:
- X c = getc(iop);
- X printf("%c%c%c", IAC, WONT, 0377&c);
- X (void) fflush(stdout);
- X continue;
- X case IAC:
- X break;
- X default:
- X continue; /* ignore command */
- X }
- X }
- X }
- X *cs++ = c;
- X if (--n <= 0 || c == '\n')
- X break;
- X }
- X if (c == EOF && cs == s)
- X return (NULL);
- X *cs++ = '\0';
- X if (debug)
- X syslog(LOG_DEBUG, "command: %s", s);
- X return (s);
- X}
- X
- static int
- toolong()
- X{
- X time_t now;
- X extern char *ctime();
- X extern time_t time();
- X
- X reply(421,
- X "Timeout (%d seconds): closing control connection.", timeout);
- X (void) time(&now);
- X if (logging) {
- X syslog(LOG_INFO,
- X "User %s timed out after %d seconds at %s",
- X (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
- X }
- X dologout(1);
- X}
- X
- yylex()
- X{
- X static int cpos, state;
- X register char *cp;
- X register struct tab *p;
- X int n;
- X char c, *strpbrk();
- X
- X for (;;) {
- X switch (state) {
- X
- X case CMD:
- X (void) signal(SIGALRM, toolong);
- X (void) alarm((unsigned) timeout);
- X if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
- X reply(221, "You could at least say goodbye.");
- X dologout(0);
- X }
- X (void) alarm(0);
- X if ((cp = index(cbuf, '\r'))) {
- X *cp++ = '\n';
- X *cp = '\0';
- X }
- X if ((cp = strpbrk(cbuf, " \n")))
- X cpos = cp - cbuf;
- X if (cpos == 0)
- X cpos = 4;
- X c = cbuf[cpos];
- X cbuf[cpos] = '\0';
- X upper(cbuf);
- X p = lookup(cbuf);
- X cbuf[cpos] = c;
- X if (p != 0) {
- X if (p->implemented == 0) {
- X nack(p->name);
- X longjmp(errcatch,0);
- X /* NOTREACHED */
- X }
- X state = p->state;
- X yylval = (int) p->name;
- X return (p->token);
- X }
- X break;
- X
- X case OSTR:
- X if (cbuf[cpos] == '\n') {
- X state = CMD;
- X return (CRLF);
- X }
- X /* FALLTHROUGH */
- X
- X case STR1:
- X case ZSTR1:
- X if (cbuf[cpos] == ' ') {
- X cpos++;
- X state = state == OSTR ? STR2 : ++state;
- X return (SP);
- X }
- X break;
- X
- X case ZSTR2:
- X if (cbuf[cpos] == '\n') {
- X state = CMD;
- X return (CRLF);
- X }
- X /* FALL THRU */
- X
- X case STR2:
- X cp = &cbuf[cpos];
- X n = strlen(cp);
- X cpos += n - 1;
- X /*
- X * Make sure the string is nonempty and \n terminated.
- X */
- X if (n > 1 && cbuf[cpos] == '\n') {
- X cbuf[cpos] = '\0';
- X yylval = copy(cp);
- X cbuf[cpos] = '\n';
- X state = ARGS;
- X return (STRING);
- X }
- X break;
- X
- X case ARGS:
- X if (isdigit(cbuf[cpos])) {
- X cp = &cbuf[cpos];
- X while (isdigit(cbuf[++cpos]))
- X ;
- X c = cbuf[cpos];
- X cbuf[cpos] = '\0';
- X yylval = atoi(cp);
- X cbuf[cpos] = c;
- X return (NUMBER);
- X }
- X switch (cbuf[cpos++]) {
- X
- X case '\n':
- X state = CMD;
- X return (CRLF);
- X
- X case ' ':
- X return (SP);
- X
- X case ',':
- X return (COMMA);
- X
- X case 'A':
- X case 'a':
- X return (A);
- X
- X case 'B':
- X case 'b':
- X return (B);
- X
- X case 'C':
- X case 'c':
- X return (C);
- X
- X case 'E':
- X case 'e':
- X return (E);
- X
- X case 'F':
- X case 'f':
- X return (F);
- X
- X case 'I':
- X case 'i':
- X return (I);
- X
- X case 'L':
- X case 'l':
- X return (L);
- X
- X case 'N':
- X case 'n':
- X return (N);
- X
- X case 'P':
- X case 'p':
- X return (P);
- X
- X case 'R':
- X case 'r':
- X return (R);
- X
- X case 'S':
- X case 's':
- X return (S);
- X
- X case 'T':
- X case 't':
- X return (T);
- X
- X }
- X break;
- X
- X default:
- X fatal("Unknown state in scanner.");
- X }
- X yyerror((char *) 0);
- X state = CMD;
- X longjmp(errcatch,0);
- X }
- X}
- X
- upper(s)
- X register char *s;
- X{
- X while (*s != '\0') {
- X if (islower(*s))
- X *s = toupper(*s);
- X s++;
- X }
- X}
- X
- copy(s)
- X char *s;
- X{
- X char *p;
- X extern char *malloc(), *strcpy();
- X
- X p = malloc((unsigned) strlen(s) + 1);
- X if (p == NULL)
- X fatal("Ran out of memory.");
- X (void) strcpy(p, s);
- X return ((int)p);
- X}
- X
- help(s)
- X char *s;
- X{
- X register struct tab *c;
- X register int width, NCMDS;
- X
- X width = 0, NCMDS = 0;
- X for (c = cmdtab; c->name != NULL; c++) {
- X int len = strlen(c->name) + 1;
- X
- X if (len > width)
- X width = len;
- X NCMDS++;
- X }
- X width = (width + 8) &~ 7;
- X if (s == 0) {
- X register int i, j, w;
- X int columns, lines;
- X
- X lreply(214,
- X "The following commands are recognized (* =>'s unimplemented).");
- X columns = 76 / width;
- X if (columns == 0)
- X columns = 1;
- X lines = (NCMDS + columns - 1) / columns;
- X for (i = 0; i < lines; i++) {
- X printf(" ");
- X for (j = 0; j < columns; j++) {
- X c = cmdtab + j * lines + i;
- X printf("%s%c", c->name,
- X c->implemented ? ' ' : '*');
- X if (c + lines >= &cmdtab[NCMDS])
- X break;
- X w = strlen(c->name) + 1;
- X while (w < width) {
- X putchar(' ');
- X w++;
- X }
- X }
- X printf("\r\n");
- X }
- X (void) fflush(stdout);
- X reply(214, "Direct comments to bugs@Sun.COM.");
- X return;
- X }
- X upper(s);
- X c = lookup(s);
- X if (c == (struct tab *)0) {
- X reply(502, "Unknown command %s.", s);
- X return;
- X }
- X if (c->implemented)
- X reply(214, "Syntax: %s %s", c->name, c->help);
- X else
- X reply(214, "%-*s\t%s; unimplemented.", width, c->name, c->help);
- X}
- END_OF_FILE
- if test 16052 -ne `wc -c <'in.ftpd/ftpcmd.y'`; then
- echo shar: \"'in.ftpd/ftpcmd.y'\" unpacked with wrong size!
- fi
- # end of 'in.ftpd/ftpcmd.y'
- fi
- if test -f 'in.ftpd/glob.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.ftpd/glob.c'\"
- else
- echo shar: Extracting \"'in.ftpd/glob.c'\" \(9587 characters\)
- sed "s/^X//" >'in.ftpd/glob.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved. The Berkeley software License Agreement
- X * specifies the terms and conditions for redistribution.
- X */
- X
- X#ifndef lint
- static char sccsid[] = "@(#)glob.c 5.2 (Berkeley) 3/7/86";
- X#endif not lint
- X
- X/*
- X * C-shell glob for random programs.
- X */
- X
- X#include <sys/param.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <pwd.h>
- X
- X#define QUOTE 0200
- X#define TRIM 0177
- X#define eq(a,b) (strcmp(a, b)==0)
- X#define GAVSIZ (NCARGS/6)
- X#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR)
- X
- static char **gargv; /* Pointer to the (stack) arglist */
- static short gargc; /* Number args in gargv */
- static short gnleft;
- static short gflag;
- static int tglob();
- char **glob();
- char *globerr;
- char *home;
- struct passwd *getpwnam();
- extern int errno;
- static char *strspl(), *strend();
- char *malloc(), *strcpy(), *strcat();
- char **copyblk();
- X
- static int globcnt;
- X
- char *globchars = "`{[*?";
- X
- static char *gpath, *gpathp, *lastgpathp;
- static int globbed;
- static char *entp;
- static char **sortbas;
- X
- char **
- glob(v)
- X register char *v;
- X{
- X char agpath[BUFSIZ];
- X char *agargv[GAVSIZ];
- X char *vv[2];
- X vv[0] = v;
- X vv[1] = 0;
- X gflag = 0;
- X rscan(vv, tglob);
- X if (gflag == 0)
- X return (copyblk(vv));
- X
- X globerr = 0;
- X gpath = agpath; gpathp = gpath; *gpathp = 0;
- X lastgpathp = &gpath[sizeof agpath - 2];
- X ginit(agargv); globcnt = 0;
- X collect(v);
- X if (globcnt == 0 && (gflag&1)) {
- X blkfree(gargv), gargv = 0;
- X return (0);
- X } else
- X return (gargv = copyblk(gargv));
- X}
- X
- static
- ginit(agargv)
- X char **agargv;
- X{
- X
- X agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
- X gnleft = NCARGS - 4;
- X}
- X
- static
- collect(as)
- X register char *as;
- X{
- X if (eq(as, "{") || eq(as, "{}")) {
- X Gcat(as, "");
- X sort();
- X } else
- X acollect(as);
- X}
- X
- static
- acollect(as)
- X register char *as;
- X{
- X register int ogargc = gargc;
- X
- X gpathp = gpath; *gpathp = 0; globbed = 0;
- X expand(as);
- X if (gargc != ogargc)
- X sort();
- X}
- X
- static
- sort()
- X{
- X register char **p1, **p2, *c;
- X char **Gvp = &gargv[gargc];
- X
- X p1 = sortbas;
- X while (p1 < Gvp-1) {
- X p2 = p1;
- X while (++p2 < Gvp)
- X if (strcmp(*p1, *p2) > 0)
- X c = *p1, *p1 = *p2, *p2 = c;
- X p1++;
- X }
- X sortbas = Gvp;
- X}
- X
- static
- expand(as)
- X char *as;
- X{
- X register char *cs;
- X register char *sgpathp, *oldcs;
- X struct stat stb;
- X
- X sgpathp = gpathp;
- X cs = as;
- X if (*cs == '~' && gpathp == gpath) {
- X addpath('~');
- X for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
- X addpath(*cs++);
- X if (!*cs || *cs == '/') {
- X if (gpathp != gpath + 1) {
- X *gpathp = 0;
- X if (gethdir(gpath + 1))
- X globerr = "Unknown user name after ~";
- X (void) strcpy(gpath, gpath + 1);
- X } else
- X (void) strcpy(gpath, home);
- X gpathp = strend(gpath);
- X }
- X }
- X while (!any(*cs, globchars)) {
- X if (*cs == 0) {
- X if (!globbed)
- X Gcat(gpath, "");
- X else if (stat(gpath, &stb) >= 0) {
- X Gcat(gpath, "");
- X globcnt++;
- X }
- X goto endit;
- X }
- X addpath(*cs++);
- X }
- X oldcs = cs;
- X while (cs > as && *cs != '/')
- X cs--, gpathp--;
- X if (*cs == '/')
- X cs++, gpathp++;
- X *gpathp = 0;
- X if (*oldcs == '{') {
- X (void) execbrc(cs, ((char *)0));
- X return;
- X }
- X matchdir(cs);
- endit:
- X gpathp = sgpathp;
- X *gpathp = 0;
- X}
- X
- static
- matchdir(pattern)
- X char *pattern;
- X{
- X struct stat stb;
- X register struct direct *dp;
- X DIR *dirp;
- X
- X dirp = opendir(gpath);
- X if (dirp == NULL) {
- X if (globbed)
- X return;
- X goto patherr2;
- X }
- X if (fstat(dirp->dd_fd, &stb) < 0)
- X goto patherr1;
- X if (!isdir(stb)) {
- X errno = ENOTDIR;
- X goto patherr1;
- X }
- X while ((dp = readdir(dirp)) != NULL) {
- X if (dp->d_ino == 0)
- X continue;
- X if (match(dp->d_name, pattern)) {
- X Gcat(gpath, dp->d_name);
- X globcnt++;
- X }
- X }
- X closedir(dirp);
- X return;
- X
- patherr1:
- X closedir(dirp);
- patherr2:
- X globerr = "Bad directory components";
- X}
- X
- static
- execbrc(p, s)
- X char *p, *s;
- X{
- X char restbuf[BUFSIZ + 2];
- X register char *pe, *pm, *pl;
- X int brclev = 0;
- X char *lm, savec, *sgpathp;
- X
- X for (lm = restbuf; *p != '{'; *lm++ = *p++)
- X continue;
- X for (pe = ++p; *pe; pe++)
- X switch (*pe) {
- X
- X case '{':
- X brclev++;
- X continue;
- X
- X case '}':
- X if (brclev == 0)
- X goto pend;
- X brclev--;
- X continue;
- X
- X case '[':
- X for (pe++; *pe && *pe != ']'; pe++)
- X continue;
- X continue;
- X }
- pend:
- X brclev = 0;
- X for (pl = pm = p; pm <= pe; pm++)
- X switch (*pm & (QUOTE|TRIM)) {
- X
- X case '{':
- X brclev++;
- X continue;
- X
- X case '}':
- X if (brclev) {
- X brclev--;
- X continue;
- X }
- X goto doit;
- X
- X case ','|QUOTE:
- X case ',':
- X if (brclev)
- X continue;
- doit:
- X savec = *pm;
- X *pm = 0;
- X (void) strcpy(lm, pl);
- X (void) strcat(restbuf, pe + 1);
- X *pm = savec;
- X if (s == 0) {
- X sgpathp = gpathp;
- X expand(restbuf);
- X gpathp = sgpathp;
- X *gpathp = 0;
- X } else if (amatch(s, restbuf))
- X return (1);
- X sort();
- X pl = pm + 1;
- X if (brclev)
- X return (0);
- X continue;
- X
- X case '[':
- X for (pm++; *pm && *pm != ']'; pm++)
- X continue;
- X if (!*pm)
- X pm--;
- X continue;
- X }
- X if (brclev)
- X goto doit;
- X return (0);
- X}
- X
- static
- match(s, p)
- X char *s, *p;
- X{
- X register int c;
- X register char *sentp;
- X char sglobbed = globbed;
- X
- X if (*s == '.' && *p != '.')
- X return (0);
- X sentp = entp;
- X entp = s;
- X c = amatch(s, p);
- X entp = sentp;
- X globbed = sglobbed;
- X return (c);
- X}
- X
- static
- amatch(s, p)
- X register char *s, *p;
- X{
- X register int scc;
- X int ok, lc;
- X char *sgpathp;
- X struct stat stb;
- X int c, cc;
- X
- X globbed = 1;
- X for (;;) {
- X scc = *s++ & TRIM;
- X switch (c = *p++) {
- X
- X case '{':
- X return (execbrc(p - 1, s - 1));
- X
- X case '[':
- X ok = 0;
- X lc = 077777;
- X while (cc = *p++) {
- X if (cc == ']') {
- X if (ok)
- X break;
- X return (0);
- X }
- X if (cc == '-') {
- X if (lc <= scc && scc <= *p++)
- X ok++;
- X } else
- X if (scc == (lc = cc))
- X ok++;
- X }
- X if (cc == 0)
- X if (ok)
- X p--;
- X else
- X return 0;
- X continue;
- X
- X case '*':
- X if (!*p)
- X return (1);
- X if (*p == '/') {
- X p++;
- X goto slash;
- X }
- X s--;
- X do {
- X if (amatch(s, p))
- X return (1);
- X } while (*s++);
- X return (0);
- X
- X case 0:
- X return (scc == 0);
- X
- X default:
- X if (c != scc)
- X return (0);
- X continue;
- X
- X case '?':
- X if (scc == 0)
- X return (0);
- X continue;
- X
- X case '/':
- X if (scc)
- X return (0);
- slash:
- X s = entp;
- X sgpathp = gpathp;
- X while (*s)
- X addpath(*s++);
- X addpath('/');
- X if (stat(gpath, &stb) == 0 && isdir(stb))
- X if (*p == 0) {
- X Gcat(gpath, "");
- X globcnt++;
- X } else
- X expand(p);
- X gpathp = sgpathp;
- X *gpathp = 0;
- X return (0);
- X }
- X }
- X}
- X
- static
- Gmatch(s, p)
- X register char *s, *p;
- X{
- X register int scc;
- X int ok, lc;
- X int c, cc;
- X
- X for (;;) {
- X scc = *s++ & TRIM;
- X switch (c = *p++) {
- X
- X case '[':
- X ok = 0;
- X lc = 077777;
- X while (cc = *p++) {
- X if (cc == ']') {
- X if (ok)
- X break;
- X return (0);
- X }
- X if (cc == '-') {
- X if (lc <= scc && scc <= *p++)
- X ok++;
- X } else
- X if (scc == (lc = cc))
- X ok++;
- X }
- X if (cc == 0)
- X if (ok)
- X p--;
- X else
- X return 0;
- X continue;
- X
- X case '*':
- X if (!*p)
- X return (1);
- X for (s--; *s; s++)
- X if (Gmatch(s, p))
- X return (1);
- X return (0);
- X
- X case 0:
- X return (scc == 0);
- X
- X default:
- X if ((c & TRIM) != scc)
- X return (0);
- X continue;
- X
- X case '?':
- X if (scc == 0)
- X return (0);
- X continue;
- X
- X }
- X }
- X}
- X
- static
- Gcat(s1, s2)
- X register char *s1, *s2;
- X{
- X register int len = strlen(s1) + strlen(s2) + 1;
- X
- X if (len >= gnleft || gargc >= GAVSIZ - 1)
- X globerr = "Arguments too long";
- X else {
- X gargc++;
- X gnleft -= len;
- X gargv[gargc] = 0;
- X gargv[gargc - 1] = strspl(s1, s2);
- X }
- X}
- X
- static
- addpath(c)
- X char c;
- X{
- X
- X if (gpathp >= lastgpathp)
- X globerr = "Pathname too long";
- X else {
- X *gpathp++ = c;
- X *gpathp = 0;
- X }
- X}
- X
- static
- rscan(t, f)
- X register char **t;
- X int (*f)();
- X{
- X register char *p, c;
- X
- X while (p = *t++) {
- X if (f == tglob)
- X if (*p == '~')
- X gflag |= 2;
- X else if (eq(p, "{") || eq(p, "{}"))
- X continue;
- X while (c = *p++)
- X (*f)(c);
- X }
- X}
- X/*
- static
- scan(t, f)
- X register char **t;
- X int (*f)();
- X{
- X register char *p, c;
- X
- X while (p = *t++)
- X while (c = *p)
- X *p++ = (*f)(c);
- X} */
- X
- static
- tglob(c)
- X register char c;
- X{
- X
- X if (any(c, globchars))
- X gflag |= c == '{' ? 2 : 1;
- X return (c);
- X}
- X/*
- static
- trim(c)
- X char c;
- X{
- X
- X return (c & TRIM);
- X} */
- X
- X
- letter(c)
- X register char c;
- X{
- X
- X return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
- X}
- X
- digit(c)
- X register char c;
- X{
- X
- X return (c >= '0' && c <= '9');
- X}
- X
- any(c, s)
- X register int c;
- X register char *s;
- X{
- X
- X while (*s)
- X if (*s++ == c)
- X return(1);
- X return(0);
- X}
- blklen(av)
- X register char **av;
- X{
- X register int i = 0;
- X
- X while (*av++)
- X i++;
- X return (i);
- X}
- X
- char **
- blkcpy(oav, bv)
- X char **oav;
- X register char **bv;
- X{
- X register char **av = oav;
- X
- X while (*av++ = *bv++)
- X continue;
- X return (oav);
- X}
- X
- blkfree(av0)
- X char **av0;
- X{
- X register char **av = av0;
- X
- X while (*av)
- X free(*av++);
- X free((char *)av0);
- X}
- X
- static
- char *
- strspl(cp, dp)
- X register char *cp, *dp;
- X{
- X register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));
- X
- X if (ep == (char *)0)
- X fatal("Out of memory");
- X (void) strcpy(ep, cp);
- X (void) strcat(ep, dp);
- X return (ep);
- X}
- X
- char **
- copyblk(v)
- X register char **v;
- X{
- X register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
- X sizeof(char **)));
- X if (nv == (char **)0)
- X fatal("Out of memory");
- X
- X return (blkcpy(nv, v));
- X}
- X
- static
- char *
- strend(cp)
- X register char *cp;
- X{
- X
- X while (*cp)
- X cp++;
- X return (cp);
- X}
- X/*
- X * Extract a home directory from the password file
- X * The argument points to a buffer where the name of the
- X * user whose home directory is sought is currently.
- X * We write the home directory of the user back there.
- X */
- gethdir(home)
- X char *home;
- X{
- X register struct passwd *pp = getpwnam(home);
- X
- X if (pp == 0)
- X return (1);
- X (void) strcpy(home, pp->pw_dir);
- X return (0);
- X}
- END_OF_FILE
- if test 9587 -ne `wc -c <'in.ftpd/glob.c'`; then
- echo shar: \"'in.ftpd/glob.c'\" unpacked with wrong size!
- fi
- # end of 'in.ftpd/glob.c'
- fi
- if test -f 'login/login.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'login/login.c'\"
- else
- echo shar: Extracting \"'login/login.c'\" \(15072 characters\)
- sed "s/^X//" >'login/login.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved. The Berkeley software License Agreement
- X * specifies the terms and conditions for redistribution.
- X */
- X
- X#ifndef lint
- char copyright[] =
- X"@(#) Copyright (c) 1980 Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif not lint
- X
- X#ifndef lint
- static char sccsid[] = "@(#)login.c 5.15 (Berkeley) 4/12/86";
- X#endif not lint
- X
- X/*
- X * login [ name ]
- X * login -r hostname (for rlogind)
- X * login -h hostname (for telnetd, etc.)
- X */
- X
- X#include <sys/param.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X#include <sys/file.h>
- X
- X#include <sgtty.h>
- X#include <utmp.h>
- X#include <signal.h>
- X#include <pwd.h>
- X#include <stdio.h>
- X#include <lastlog.h>
- X#include <errno.h>
- X#include <ttyent.h>
- X#include <syslog.h>
- X#include <grp.h>
- X
- X#ifdef MAILPING
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- char mailhost[] = "mailhost";
- X#endif
- X
- X#ifdef PERMS
- char *strdup(), *grpnames[NGROUPS+1];
- int ngrps, lp;
- struct group *grp;
- extern int permcheck();
- X#endif
- X
- X#define TTYGRPNAME "tty" /* name of group to own ttys */
- X#define TTYGID(gid) tty_gid(gid) /* gid that owns all ttys */
- X
- X#define SCMPN(a, b) strncmp(a, b, sizeof(a))
- X#define SCPYN(a, b) strncpy(a, b, sizeof(a))
- X
- X#define NMAX sizeof(utmp.ut_name)
- X#define HMAX sizeof(utmp.ut_host)
- X
- X#define FALSE 0
- X#define TRUE -1
- X
- X#define QUOTAWARN "/usr/ucb/quota -q" /* warn user about quotas */
- X
- char nolog[] = "/etc/nologin";
- char qlog[] = ".hushlogin";
- char maildir[30] = "/usr/spool/mail/";
- char lastlog[] = "/usr/adm/lastlog";
- struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" };
- struct sgttyb ttyb;
- struct utmp utmp;
- char minusnam[16] = "-";
- char *envinit[] = { 0 }; /* now set by setenv calls */
- X/*
- X * This bounds the time given to login. We initialize it here
- X * so it can be patched on machines where it's too small.
- X */
- int timeout = 60;
- X
- char term[64];
- X
- struct passwd *pwd;
- char *strcat(), *rindex(), *index(), *malloc(), *realloc();
- int timedout();
- char *ttyname();
- char *crypt();
- char *getpass();
- char *stypeof();
- extern char **environ;
- extern int errno;
- X
- struct tchars tc = {
- X CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
- X};
- struct ltchars ltc = {
- X CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
- X};
- X
- struct winsize win = { 0, 0, 0, 0 };
- X
- int rflag;
- int usererr = -1;
- char rusername[NMAX+1], lusername[NMAX+1];
- char rpassword[NMAX+1];
- char name[NMAX+1];
- char *rhost;
- X
- main(argc, argv)
- X char *argv[];
- X{
- X register char *namep;
- X int pflag = 0, hflag = 0, t, f, c;
- X int invalid, quietlog;
- X FILE *nlfd;
- X char *ttyn, *tty;
- X int ldisc = 0, zero = 0, i;
- X char **envnew;
- X
- X signal(SIGALRM, timedout);
- X alarm(timeout);
- X signal(SIGQUIT, SIG_IGN);
- X signal(SIGINT, SIG_IGN);
- X setpriority(PRIO_PROCESS, 0, 0);
- X /*
- X * -p is used by getty to tell login not to destroy the environment
- X * -r is used by rlogind to cause the autologin protocol;
- X * -h is used by other servers to pass the name of the
- X * remote host to login so that it may be placed in utmp and wtmp
- X */
- X while (argc > 1) {
- X if (strcmp(argv[1], "-r") == 0) {
- X if (rflag || hflag) {
- X printf("Only one of -r and -h allowed\n");
- X exit(1);
- X }
- X rflag = 1;
- X usererr = doremotelogin(argv[2]);
- X SCPYN(utmp.ut_host, argv[2]);
- X argc -= 2;
- X argv += 2;
- X continue;
- X }
- X if (strcmp(argv[1], "-h") == 0 && getuid() == 0) {
- X if (rflag || hflag) {
- X printf("Only one of -r and -h allowed\n");
- X exit(1);
- X }
- X hflag = 1;
- X SCPYN(utmp.ut_host, argv[2]);
- X argc -= 2;
- X argv += 2;
- X continue;
- X }
- X if (strcmp(argv[1], "-p") == 0) {
- X argc--;
- X argv++;
- X pflag = 1;
- X continue;
- X }
- X break;
- X }
- X ioctl(0, TIOCLSET, &zero);
- X ioctl(0, TIOCNXCL, 0);
- X ioctl(0, FIONBIO, &zero);
- X ioctl(0, FIOASYNC, &zero);
- X ioctl(0, TIOCGETP, &ttyb);
- X /*
- X * If talking to an rlogin process,
- X * propagate the terminal type and
- X * baud rate across the network.
- X */
- X if (rflag)
- X doremoteterm(term, &ttyb);
- X ttyb.sg_erase = CERASE;
- X ttyb.sg_kill = CKILL;
- X ioctl(0, TIOCSLTC, <c);
- X ioctl(0, TIOCSETC, &tc);
- X ioctl(0, TIOCSETP, &ttyb);
- X for (t = getdtablesize(); t > 2; t--)
- X close(t);
- X ttyn = ttyname(0);
- X if (ttyn == (char *)0 || *ttyn == '\0')
- X ttyn = "/dev/tty??";
- X tty = rindex(ttyn, '/');
- X if (tty == NULL)
- X tty = ttyn;
- X else
- X tty++;
- X openlog("login", LOG_ODELAY, LOG_AUTH);
- X t = 0;
- X invalid = FALSE;
- X do {
- X ldisc = 0;
- X ioctl(0, TIOCSETD, &ldisc);
- X SCPYN(utmp.ut_name, "");
- X /*
- X * Name specified, take it.
- X */
- X if (argc > 1) {
- X SCPYN(utmp.ut_name, argv[1]);
- X argc = 0;
- X }
- X /*
- X * If remote login take given name,
- X * otherwise prompt user for something.
- X */
- X if (rflag && !invalid)
- X SCPYN(utmp.ut_name, lusername);
- X else
- X getloginname(&utmp);
- X invalid = FALSE;
- X if (!strcmp(pwd->pw_shell, "/bin/csh")) {
- X ldisc = NTTYDISC;
- X ioctl(0, TIOCSETD, &ldisc);
- X }
- X /*
- X * If no remote login authentication and
- X * a password exists for this user, prompt
- X * for one and verify it.
- X */
- X if (usererr == -1 && *pwd->pw_passwd != '\0') {
- X char *pp;
- X
- X setpriority(PRIO_PROCESS, 0, -4);
- X pp = getpass("Password:");
- X namep = crypt(pp, pwd->pw_passwd);
- X setpriority(PRIO_PROCESS, 0, 0);
- X if (strcmp(namep, pwd->pw_passwd))
- X invalid = TRUE;
- X }
- X /*
- X * If user not super-user, check for logins disabled.
- X */
- X if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) {
- X while ((c = getc(nlfd)) != EOF)
- X putchar(c);
- X fflush(stdout);
- X sleep(5);
- X exit(0);
- X }
- X /*
- X * If valid so far and root is logging in,
- X * see if root logins on this terminal are permitted.
- X */
- X if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) {
- X if (utmp.ut_host[0])
- X syslog(LOG_CRIT,
- X "ROOT LOGIN REFUSED ON %s FROM %.*s",
- X tty, HMAX, utmp.ut_host);
- X else
- X syslog(LOG_CRIT,
- X "ROOT LOGIN REFUSED ON %s", tty);
- X invalid = TRUE;
- X }
- X#ifdef PERMS
- X /* build groups so we can look them up in 'permissions'
- X * this check is not run for uid 0
- X */
- X if(!invalid && pwd->pw_uid != 0) {
- X setgrent();
- X ngrps = 0;
- X if(!(grp=getgrgid(pwd->pw_gid))) {
- X syslog(LOG_CRIT,
- X "cannot find group name for %d\n", pwd->pw_gid);
- X goto broken_groups;
- X }
- X grpnames[ngrps++] = strdup(grp->gr_name);
- X while( grp=getgrent() ) {
- X if(pwd->pw_gid == grp->gr_gid)
- X continue;
- X while(*grp->gr_mem) {
- X if( !strcmp(lusername, *grp->gr_mem)) {
- X grpnames[ngrps++] = strdup(grp->gr_name);
- X }
- X grp->gr_mem++;
- X }
- X }
- X endgrent();
- X grpnames[ngrps] = NULL;
- X lp = permcheck(lusername, tty, grpnames, NULL);
- X if(!lp) {
- X syslog(LOG_CRIT,
- X "%s:%s not permitted", tty, lusername);
- X printf("Permission denied.\n");
- X exit(1);
- X }
- X }
- broken_groups:
- X#endif
- X if (invalid) {
- X printf("Login incorrect\n");
- X if (++t >= 5) {
- X if (utmp.ut_host[0])
- X syslog(LOG_CRIT,
- X "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
- X tty, HMAX, utmp.ut_host,
- X NMAX, utmp.ut_name);
- X else
- X syslog(LOG_CRIT,
- X "REPEATED LOGIN FAILURES ON %s, %.*s",
- X tty, NMAX, utmp.ut_name);
- X ioctl(0, TIOCHPCL, (struct sgttyb *) 0);
- X close(0), close(1), close(2);
- X sleep(10);
- X exit(1);
- X }
- X }
- X if (*pwd->pw_shell == '\0')
- X pwd->pw_shell = "/bin/sh";
- X if (chdir(pwd->pw_dir) < 0 && !invalid ) {
- X if (chdir("/") < 0) {
- X printf("No directory!\n");
- X invalid = TRUE;
- X } else {
- X printf("No directory! %s\n",
- X "Logging in with home=/");
- X pwd->pw_dir = "/";
- X }
- X }
- X /*
- X * Remote login invalid must have been because
- X * of a restriction of some sort, no extra chances.
- X */
- X if (!usererr && invalid)
- X exit(1);
- X } while (invalid);
- X/* committed to login turn off timeout */
- X alarm(0);
- X
- X time(&utmp.ut_time);
- X t = ttyslot();
- X if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) {
- X lseek(f, (long)(t*sizeof(utmp)), 0);
- X SCPYN(utmp.ut_line, tty);
- X write(f, (char *)&utmp, sizeof(utmp));
- X close(f);
- X }
- X if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) {
- X write(f, (char *)&utmp, sizeof(utmp));
- X close(f);
- X }
- X quietlog = access(qlog, F_OK) == 0;
- X if ((f = open(lastlog, O_RDWR)) >= 0) {
- X struct lastlog ll;
- X
- X lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
- X if (read(f, (char *) &ll, sizeof ll) == sizeof ll &&
- X ll.ll_time != 0 && !quietlog) {
- X printf("Last login: %.*s ",
- X 24-5, (char *)ctime(&ll.ll_time));
- X if (*ll.ll_host != '\0')
- X printf("from %.*s\n",
- X sizeof (ll.ll_host), ll.ll_host);
- X else
- X printf("on %.*s\n",
- X sizeof (ll.ll_line), ll.ll_line);
- X }
- X lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
- X time(&ll.ll_time);
- X SCPYN(ll.ll_line, tty);
- X SCPYN(ll.ll_host, utmp.ut_host);
- X write(f, (char *) &ll, sizeof ll);
- X close(f);
- X }
- X chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid));
- X if (!hflag && !rflag) /* XXX */
- X ioctl(0, TIOCSWINSZ, &win);
- X chmod(ttyn, 0620);
- X setgid(pwd->pw_gid);
- X strncpy(name, utmp.ut_name, NMAX);
- X name[NMAX] = '\0';
- X initgroups(name, pwd->pw_gid);
- X setuid(pwd->pw_uid);
- X /* destroy environment unless user has asked to preserve it */
- X if (!pflag)
- X environ = envinit;
- X
- X /* set up environment, this time without destruction */
- X /* copy the environment before setenving */
- X i = 0;
- X while (environ[i] != NULL)
- X i++;
- X envnew = (char **) malloc(sizeof (char *) * (i + 1));
- X for (; i >= 0; i--)
- X envnew[i] = environ[i];
- X environ = envnew;
- X
- X setenv("HOME=", pwd->pw_dir, 1);
- X setenv("SHELL=", pwd->pw_shell, 1);
- X if (term[0] == '\0')
- X strncpy(term, stypeof(tty), sizeof(term));
- X setenv("TERM=", term, 0);
- X setenv("USER=", pwd->pw_name, 1);
- X setenv("PATH=", ":/usr/ucb:/bin:/usr/bin", 0);
- X
- X if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
- X namep = pwd->pw_shell;
- X else
- X namep++;
- X strcat(minusnam, namep);
- X if (tty[sizeof("tty")-1] == 'd')
- X syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
- X if (pwd->pw_uid == 0)
- X if (utmp.ut_host[0])
- X syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
- X tty, HMAX, utmp.ut_host);
- X else
- X syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
- X if (!quietlog) {
- X struct stat st;
- X
- X showmotd();
- X strcat(maildir, pwd->pw_name);
- X#ifdef MAILPING
- X if(!serverup())
- X printf("No idea if you have mail.\n");
- X else
- X#endif
- X if (stat(maildir, &st) == 0 && st.st_size != 0)
- X printf("You have %smail.\n",
- X (st.st_mtime > st.st_atime) ? "new " : "");
- X system(QUOTAWARN);
- X }
- X signal(SIGALRM, SIG_DFL);
- X signal(SIGQUIT, SIG_DFL);
- X signal(SIGINT, SIG_DFL);
- X signal(SIGTSTP, SIG_IGN);
- X execlp(pwd->pw_shell, minusnam, 0);
- X perror(pwd->pw_shell);
- X printf("No shell\n");
- X exit(0);
- X}
- X
- getloginname(up)
- X register struct utmp *up;
- X{
- X register char *namep;
- X char c;
- X
- X while (up->ut_name[0] == '\0') {
- X namep = up->ut_name;
- X printf("login: ");
- X while ((c = getchar()) != '\n') {
- X if (c == ' ')
- X c = '_';
- X if (c == EOF)
- X exit(0);
- X if (namep < up->ut_name+NMAX)
- X *namep++ = c;
- X }
- X }
- X strncpy(lusername, up->ut_name, NMAX);
- X lusername[NMAX] = 0;
- X if ((pwd = getpwnam(lusername)) == NULL)
- X pwd = &nouser;
- X}
- X
- timedout()
- X{
- X
- X printf("Login timed out after %d seconds\n", timeout);
- X exit(0);
- X}
- X
- int stopmotd;
- catch()
- X{
- X
- X signal(SIGINT, SIG_IGN);
- X stopmotd++;
- X}
- X
- rootterm(tty)
- X char *tty;
- X{
- X register struct ttyent *t;
- X
- X if ((t = getttynam(tty)) != NULL) {
- X if (t->ty_status & TTY_SECURE)
- X return (1);
- X }
- X return (0);
- X}
- X
- showmotd()
- X{
- X FILE *mf;
- X register c;
- X
- X signal(SIGINT, catch);
- X if ((mf = fopen("/etc/motd", "r")) != NULL) {
- X while ((c = getc(mf)) != EOF && stopmotd == 0)
- X putchar(c);
- X fclose(mf);
- X }
- X signal(SIGINT, SIG_IGN);
- X}
- X
- X#undef UNKNOWN
- X#define UNKNOWN "su"
- X
- char *
- stypeof(ttyid)
- X char *ttyid;
- X{
- X register struct ttyent *t;
- X
- X if (ttyid == NULL || (t = getttynam(ttyid)) == NULL)
- X return (UNKNOWN);
- X return (t->ty_type);
- X}
- X
- doremotelogin(host)
- X char *host;
- X{
- X getstr(rusername, sizeof (rusername), "remuser");
- X getstr(lusername, sizeof (lusername), "locuser");
- X getstr(term, sizeof(term), "Terminal type");
- X if (getuid()) {
- X pwd = &nouser;
- X return(-1);
- X }
- X pwd = getpwnam(lusername);
- X if (pwd == NULL) {
- X pwd = &nouser;
- X return(-1);
- X }
- X return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername));
- X}
- X
- getstr(buf, cnt, err)
- X char *buf;
- X int cnt;
- X char *err;
- X{
- X char c;
- X
- X do {
- X if (read(0, &c, 1) != 1)
- X exit(1);
- X if (--cnt < 0) {
- X printf("%s too long\r\n", err);
- X exit(1);
- X }
- X *buf++ = c;
- X } while (c != 0);
- X}
- X
- char *speeds[] =
- X { "0", "50", "75", "110", "134", "150", "200", "300",
- X "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
- X#define NSPEEDS (sizeof (speeds) / sizeof (speeds[0]))
- X
- doremoteterm(term, tp)
- X char *term;
- X struct sgttyb *tp;
- X{
- X register char *cp = index(term, '/'), **cpp;
- X char *speed;
- X
- X if (cp) {
- X *cp++ = '\0';
- X speed = cp;
- X cp = index(speed, '/');
- X if (cp)
- X *cp++ = '\0';
- X for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
- X if (strcmp(*cpp, speed) == 0) {
- X tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
- X break;
- X }
- X }
- X tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
- X}
- X
- X/*
- X * Set the value of var to be arg in the Unix 4.2 BSD environment env.
- X * Var should end with '='.
- X * (bindings are of the form "var=value")
- X * This procedure assumes the memory for the first level of environ
- X * was allocated using malloc.
- X */
- setenv(var, value, clobber)
- X char *var, *value;
- X{
- X extern char **environ;
- X int index = 0;
- X int varlen = strlen(var);
- X int vallen = strlen(value);
- X
- X for (index = 0; environ[index] != NULL; index++) {
- X if (strncmp(environ[index], var, varlen) == 0) {
- X /* found it */
- X if (!clobber)
- X return;
- X environ[index] = malloc(varlen + vallen + 1);
- X strcpy(environ[index], var);
- X strcat(environ[index], value);
- X return;
- X }
- X }
- X environ = (char **) realloc(environ, sizeof (char *) * (index + 2));
- X if (environ == NULL) {
- X fprintf(stderr, "login: malloc out of memory\n");
- X exit(1);
- X }
- X environ[index] = malloc(varlen + vallen + 1);
- X strcpy(environ[index], var);
- X strcat(environ[index], value);
- X environ[++index] = NULL;
- X}
- X
- tty_gid(default_gid)
- X int default_gid;
- X{
- X struct group *getgrnam(), *gr;
- X int gid = default_gid;
- X
- X gr = getgrnam(TTYGRPNAME);
- X if (gr != (struct group *) 0)
- X gid = gr->gr_gid;
- X
- X endgrent();
- X
- X return (gid);
- X}
- X
- X#ifdef MAILPING
- X/* ping mailhost, at port echo/udp
- X * determine if server is up=1
- X * if unable, default to down=0
- X */
- serverup()
- X{
- X struct sockaddr_in sin;
- X struct hostent *hent;
- X struct servent *sent;
- X struct timeval tv;
- X int s, count, tsize;
- X fd_set fdin;
- X
- X if( !(hent=gethostbyname(mailhost)))
- X return 0;
- X if( !(sent=getservbyname("echo", "udp")))
- X return 0;
- X
- X bzero(&sin, sizeof sin);
- X sin.sin_family = hent->h_addrtype;
- X bcopy((char *)hent->h_addr, (char *)&sin.sin_addr, hent->h_length);
- X sin.sin_port = sent->s_port;
- X
- X if( (s=socket(AF_INET, SOCK_DGRAM, 0)) <0)
- X return 0;
- X
- X tsize = getdtablesize();
- X tv.tv_sec = 1;
- X tv.tv_usec = 0;
- X for(count=0; count<10; count++) {
- X FD_ZERO(&fdin);
- X FD_SET(s, &fdin);
- X switch( select(tsize, &fdin, NULL, NULL, &tv) ) {
- X case -1:
- X perror("select");
- X break;
- X case 0:
- X if( sendto(s, "UP?", 3, 0, &sin, sizeof sin) < 0)
- X perror("sendto");
- X break;
- X case 1:
- X close(s);
- X return 1;
- X }
- X }
- X
- X close(s);
- X return 0;
- X}
- X#endif
- END_OF_FILE
- if test 15072 -ne `wc -c <'login/login.c'`; then
- echo shar: \"'login/login.c'\" unpacked with wrong size!
- fi
- # end of 'login/login.c'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-