summaryrefslogtreecommitdiffstats
path: root/contrib/lukemftpd/src/ftpcmd.y
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/lukemftpd/src/ftpcmd.y')
-rw-r--r--contrib/lukemftpd/src/ftpcmd.y213
1 files changed, 138 insertions, 75 deletions
diff --git a/contrib/lukemftpd/src/ftpcmd.y b/contrib/lukemftpd/src/ftpcmd.y
index 68a598b..1039d51 100644
--- a/contrib/lukemftpd/src/ftpcmd.y
+++ b/contrib/lukemftpd/src/ftpcmd.y
@@ -1,7 +1,7 @@
-/* $NetBSD: ftpcmd.y,v 1.66 2001/12/01 10:25:30 lukem Exp $ */
+/* $NetBSD: ftpcmd.y,v 1.71 2002/10/12 08:35:17 darrenr Exp $ */
/*-
- * Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -77,7 +77,41 @@
*/
%{
-#include "lukemftpd.h"
+#include <sys/cdefs.h>
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
+#else
+__RCSID("$NetBSD: ftpcmd.y,v 1.71 2002/10/12 08:35:17 darrenr Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/ftp.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#ifdef KERBEROS5
+#include <krb5/krb5.h>
+#endif
#include "extern.h"
#include "version.h"
@@ -93,7 +127,10 @@ char *fromname;
%}
%union {
- int i;
+ struct {
+ off_t o;
+ int i;
+ } u;
char *s;
}
@@ -128,10 +165,10 @@ char *fromname;
%token <s> STRING
%token <s> ALL
-%token <i> NUMBER
+%token <u> NUMBER
-%type <i> check_login octal_number byte_size
-%type <i> struct_code mode_code type_code form_code decimal_integer
+%type <u.i> check_login octal_number byte_size
+%type <u.i> struct_code mode_code type_code form_code decimal_integer
%type <s> pathstring pathname password username
%type <s> mechanism_name base64data prot_code
@@ -259,32 +296,48 @@ cmd
| LPSV check_login CRLF
{
if ($2) {
- if (epsvall)
- reply(501,
- "LPSV disallowed after EPSV ALL");
- else
- long_passive("LPSV", PF_UNSPEC);
+ if (CURCLASS_FLAGS_ISSET(passive)) {
+ if (epsvall)
+ reply(501,
+ "LPSV disallowed after EPSV ALL");
+ else
+ long_passive("LPSV", PF_UNSPEC);
+ } else
+ reply(500, "LPSV mode not available.");
}
}
| EPSV check_login SP NUMBER CRLF
{
- if ($2)
- long_passive("EPSV", epsvproto2af($4));
+ if ($2) {
+ if (CURCLASS_FLAGS_ISSET(passive))
+ long_passive("EPSV",
+ epsvproto2af($4.i));
+ else
+ reply(500, "EPSV mode not available.");
+ }
}
| EPSV check_login SP ALL CRLF
{
if ($2) {
- reply(200, "EPSV ALL command successful.");
- epsvall++;
+ if (CURCLASS_FLAGS_ISSET(passive)) {
+ reply(200,
+ "EPSV ALL command successful.");
+ epsvall++;
+ } else
+ reply(500, "EPSV mode not available.");
}
}
| EPSV check_login CRLF
{
- if ($2)
- long_passive("EPSV", PF_UNSPEC);
+ if ($2) {
+ if (CURCLASS_FLAGS_ISSET(passive))
+ long_passive("EPSV", PF_UNSPEC);
+ else
+ reply(500, "EPSV mode not available.");
+ }
}
| TYPE check_login SP type_code CRLF
@@ -517,24 +570,28 @@ cmd
{
if ($4) {
reply(200,
- "Current IDLE time limit is %d seconds; max %d",
- curclass.timeout, curclass.maxtimeout);
+ "Current IDLE time limit is " LLF
+ " seconds; max " LLF,
+ (LLT)curclass.timeout,
+ (LLT)curclass.maxtimeout);
}
}
| SITE SP IDLE check_login SP NUMBER CRLF
{
if ($4) {
- if ($6 < 30 || $6 > curclass.maxtimeout) {
+ if ($6.i < 30 || $6.i > curclass.maxtimeout) {
reply(501,
- "IDLE time limit must be between 30 and %d seconds",
- curclass.maxtimeout);
+ "IDLE time limit must be between 30 and "
+ LLF " seconds",
+ (LLT)curclass.maxtimeout);
} else {
- curclass.timeout = $6;
+ curclass.timeout = $6.i;
(void) alarm(curclass.timeout);
reply(200,
- "IDLE time limit set to %d seconds",
- curclass.timeout);
+ "IDLE time limit set to "
+ LLF " seconds",
+ (LLT)curclass.timeout);
}
}
}
@@ -550,19 +607,17 @@ cmd
| SITE SP RATEGET check_login SP STRING CRLF
{
+ char errbuf[100];
char *p = $6;
LLT rate;
if ($4) {
- rate = strsuftoll(p);
- if (rate == -1)
- reply(501, "Invalid RATEGET %s", p);
- else if (curclass.maxrateget &&
- rate > curclass.maxrateget)
- reply(501,
- "RATEGET " LLF " is larger than maximum RATEGET " LLF,
- (LLT)rate,
- (LLT)curclass.maxrateget);
+ rate = strsuftollx("RATEGET", p, 0,
+ curclass.maxrateget
+ ? curclass.maxrateget
+ : LLTMAX, errbuf, sizeof(errbuf));
+ if (errbuf[0])
+ reply(501, "%s", errbuf);
else {
curclass.rateget = rate;
reply(200,
@@ -584,19 +639,17 @@ cmd
| SITE SP RATEPUT check_login SP STRING CRLF
{
+ char errbuf[100];
char *p = $6;
LLT rate;
if ($4) {
- rate = strsuftoll(p);
- if (rate == -1)
- reply(501, "Invalid RATEPUT %s", p);
- else if (curclass.maxrateput &&
- rate > curclass.maxrateput)
- reply(501,
- "RATEPUT " LLF " is larger than maximum RATEPUT " LLF,
- (LLT)rate,
- (LLT)curclass.maxrateput);
+ rate = strsuftollx("RATEPUT", p, 0,
+ curclass.maxrateput
+ ? curclass.maxrateput
+ : LLTMAX, errbuf, sizeof(errbuf));
+ if (errbuf[0])
+ reply(501, "%s", errbuf);
else {
curclass.rateput = rate;
reply(200,
@@ -622,7 +675,7 @@ cmd
{
int oldmask;
- if ($4 && CURCLASS_FLAGS_ISSET(modify)) {
+ if ($4 && check_write("", 0)) {
if (($6 == -1) || ($6 > 0777)) {
reply(501, "Bad UMASK value");
} else {
@@ -827,11 +880,11 @@ cmd
;
rcmd
- : REST check_login SP byte_size CRLF
+ : REST check_login SP NUMBER CRLF
{
if ($2) {
fromname = NULL;
- restart_point = $4; /* XXX: $4 is only "int" */
+ restart_point = $4.o;
reply(350,
"Restarting at " LLF ". Send STORE or RETRIEVE to initiate transfer.",
(LLT)restart_point);
@@ -863,6 +916,9 @@ password
byte_size
: NUMBER
+ {
+ $$ = $1.i;
+ }
;
host_port
@@ -875,9 +931,9 @@ host_port
data_dest.su_len = sizeof(struct sockaddr_in);
data_dest.su_family = AF_INET;
p = (char *)&data_dest.su_port;
- p[0] = $9; p[1] = $11;
+ p[0] = $9.i; p[1] = $11.i;
a = (char *)&data_dest.su_addr;
- a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
+ a[0] = $1.i; a[1] = $3.i; a[2] = $5.i; a[3] = $7.i;
}
;
@@ -892,12 +948,12 @@ host_long_port4
data_dest.su_len = sizeof(struct sockaddr_in);
data_dest.su_family = AF_INET;
p = (char *)&data_dest.su_port;
- p[0] = $15; p[1] = $17;
+ p[0] = $15.i; p[1] = $17.i;
a = (char *)&data_dest.su_addr;
- a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11;
+ a[0] = $5.i; a[1] = $7.i; a[2] = $9.i; a[3] = $11.i;
/* reject invalid LPRT command */
- if ($1 != 4 || $3 != 4 || $13 != 2)
+ if ($1.i != 4 || $3.i != 4 || $13.i != 2)
memset(&data_dest, 0, sizeof(data_dest));
}
;
@@ -917,12 +973,12 @@ host_long_port6
data_dest.su_len = sizeof(struct sockaddr_in6);
data_dest.su_family = AF_INET6;
p = (char *)&data_dest.su_port;
- p[0] = $39; p[1] = $41;
+ p[0] = $39.i; p[1] = $41.i;
a = (char *)&data_dest.si_su.su_sin6.sin6_addr;
- a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11;
- a[4] = $13; a[5] = $15; a[6] = $17; a[7] = $19;
- a[8] = $21; a[9] = $23; a[10] = $25; a[11] = $27;
- a[12] = $29; a[13] = $31; a[14] = $33; a[15] = $35;
+ a[0] = $5.i; a[1] = $7.i; a[2] = $9.i; a[3] = $11.i;
+ a[4] = $13.i; a[5] = $15.i; a[6] = $17.i; a[7] = $19.i;
+ a[8] = $21.i; a[9] = $23.i; a[10] = $25.i; a[11] = $27.i;
+ a[12] = $29.i; a[13] = $31.i; a[14] = $33.i; a[15] = $35.i;
if (his_addr.su_family == AF_INET6) {
/* XXX: more sanity checks! */
data_dest.su_scope_id = his_addr.su_scope_id;
@@ -931,7 +987,7 @@ host_long_port6
memset(&data_dest, 0, sizeof(data_dest));
#endif /* INET6 */
/* reject invalid LPRT command */
- if ($1 != 6 || $3 != 16 || $37 != 2)
+ if ($1.i != 6.i || $3.i != 16.i || $37.i != 2)
memset(&data_dest, 0, sizeof(data_dest));
}
;
@@ -1093,7 +1149,7 @@ octal_number
* Convert a number that was read as decimal number
* to what it would be if it had been read as octal.
*/
- dec = $1;
+ dec = $1.i;
multby = 1;
ret = 0;
while (dec) {
@@ -1124,6 +1180,9 @@ prot_code
decimal_integer
: NUMBER
+ {
+ $$ = $1.i;
+ }
;
check_login
@@ -1231,13 +1290,13 @@ struct tab cmdtab[] = {
};
struct tab sitetab[] = {
- { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
- { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
- { "RATEGET", RATEGET,OSTR, 1, "[ <sp> get-throttle-rate ]" },
- { "RATEPUT", RATEPUT,OSTR, 1, "[ <sp> put-throttle-rate ]" },
- { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
- { NULL, 0, 0, 0, NULL }
+ { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
+ { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
+ { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
+ { "RATEGET", RATEGET,OSTR, 1, "[ <sp> get-throttle-rate ]" },
+ { "RATEPUT", RATEPUT,OSTR, 1, "[ <sp> put-throttle-rate ]" },
+ { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
+ { NULL, 0, 0, 0, NULL }
};
static int check_write(const char *, int);
@@ -1251,6 +1310,8 @@ extern int epsvall;
/*
* Check if a filename is allowed to be modified (isupload == 0) or
* uploaded (isupload == 1), and if necessary, check the filename is `sane'.
+ * If the filename is NULL, fail.
+ * If the filename is "", don't do the sane name check.
*/
static int
check_write(const char *file, int isupload)
@@ -1271,8 +1332,9 @@ check_write(const char *file, int isupload)
reply(502, "No permission to use this command.");
return (0);
}
+
/* checking sanenames */
- if (CURCLASS_FLAGS_ISSET(sanenames)) {
+ if (file[0] != '\0' && CURCLASS_FLAGS_ISSET(sanenames)) {
const char *p;
if (file[0] == '.')
@@ -1392,11 +1454,11 @@ toolong(int signo)
{
reply(421,
- "Timeout (%d seconds): closing control connection.",
- curclass.timeout);
+ "Timeout (" LLF " seconds): closing control connection.",
+ (LLT)curclass.timeout);
if (logging)
- syslog(LOG_INFO, "User %s timed out after %d seconds",
- (pw ? pw->pw_name : "unknown"), curclass.timeout);
+ syslog(LOG_INFO, "User %s timed out after " LLF " seconds",
+ (pw ? pw->pw_name : "unknown"), (LLT)curclass.timeout);
dologout(1);
}
@@ -1548,7 +1610,7 @@ yylex(void)
;
c = cmdp[cpos];
cmdp[cpos] = '\0';
- yylval.i = atoi(cp);
+ yylval.u.i = atoi(cp);
cmdp[cpos] = c;
state = STR1;
return (NUMBER);
@@ -1563,7 +1625,8 @@ yylex(void)
;
c = cmdp[cpos];
cmdp[cpos] = '\0';
- yylval.i = atoi(cp);
+ yylval.u.i = atoi(cp);
+ yylval.u.o = strtoull(cp, (char **)NULL, 10);
cmdp[cpos] = c;
return (NUMBER);
}
@@ -1736,13 +1799,13 @@ help(struct tab *ctab, const char *s)
}
c = lookup(ctab, s);
if (c == (struct tab *)0) {
- reply(502, "Unknown command %s.", s);
+ reply(502, "Unknown command '%s'.", s);
return;
}
if (CMD_IMPLEMENTED(c))
reply(214, "Syntax: %s%s %s", htype, c->name, c->help);
else
- reply(214, "%s%-*s\t%s; not implemented.", htype, width,
+ reply(504, "%s%-*s\t%s; not implemented.", htype, width,
c->name, c->help);
}
OpenPOWER on IntegriCloud