summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2004-11-18 10:02:28 +0000
committeryar <yar@FreeBSD.org>2004-11-18 10:02:28 +0000
commit750c66145333daf5110b186b9fa5225f120fa574 (patch)
treec23dfacce99c744fff42d289816da493039495e7 /libexec
parent6cd7428b1336c7f507e72507e5ddb09a2ae2aeba (diff)
downloadFreeBSD-src-750c66145333daf5110b186b9fa5225f120fa574.zip
FreeBSD-src-750c66145333daf5110b186b9fa5225f120fa574.tar.gz
Log pathname arguments to ftp commands as the user specified them;
add the working directory pathname to the log message if any of such arguments isn't absolute. This has advantage over the old way of logging that an admin can see what users are actually trying to do, and where. The old code was also not too robust when it came to a chrooted session and an absolute pathname. Pointed out by: Nick Leuta MFC after: 2 weeks
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ftpd/ftpd.c88
1 files changed, 55 insertions, 33 deletions
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 0e9651e..2b8ba9f 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -215,25 +215,9 @@ char *LastArgv = NULL; /* end of argv */
char proctitle[LINE_MAX]; /* initial part of title */
#endif /* SETPROCTITLE */
-#define LOGCMD(cmd, file) \
- if (logging > 1) \
- syslog(LOG_INFO,"%s %s%s", cmd, \
- *(file) == '/' ? "" : curdir(), file);
-#define LOGCMD2(cmd, file1, file2) \
- if (logging > 1) \
- syslog(LOG_INFO,"%s %s%s %s%s", cmd, \
- *(file1) == '/' ? "" : curdir(), file1, \
- *(file2) == '/' ? "" : curdir(), file2);
-#define LOGBYTES(cmd, file, cnt) \
- if (logging > 1) { \
- if (cnt == -1) \
- syslog(LOG_INFO,"%s %s%s", cmd, \
- *(file) == '/' ? "" : curdir(), file); \
- else \
- syslog(LOG_INFO, "%s %s%s = %jd bytes", \
- cmd, (*(file) == '/') ? "" : curdir(), file, \
- (intmax_t)cnt); \
- }
+#define LOGCMD(cmd, file) logcmd((cmd), (file), NULL, -1)
+#define LOGCMD2(cmd, file1, file2) logcmd((cmd), (file1), (file2), -1)
+#define LOGBYTES(cmd, file, cnt) logcmd((cmd), (file), NULL, (cnt))
#ifdef VIRTUAL_HOSTING
static void inithosts(void);
@@ -245,7 +229,6 @@ static void myoob(void);
static int checkuser(char *, char *, int, char **);
static FILE *dataconn(char *, off_t, char *);
static void dolog(struct sockaddr *);
-static char *curdir(void);
static void end_login(void);
static FILE *getdatasock(char *);
static int guniquefd(char *, char **);
@@ -257,23 +240,12 @@ static struct passwd *
sgetpwnam(char *);
static char *sgetsave(char *);
static void reapchild(int);
+static void appendf(char **, char *, ...);
+static void logcmd(char *, char *, char *, off_t);
static void logxfer(char *, off_t, time_t);
static char *doublequote(char *);
static int *socksetup(int, char *, const char *);
-static char *
-curdir(void)
-{
- static char path[MAXPATHLEN+1+1]; /* path + '/' + '\0' */
-
- if (getcwd(path, sizeof(path)-2) == NULL)
- return ("");
- if (path[1] != '\0') /* special case for root dir. */
- strcat(path, "/");
- /* For guest account, skip / since it's chrooted */
- return (guest ? path+1 : path);
-}
-
int
main(int argc, char *argv[], char **envp)
{
@@ -3169,6 +3141,56 @@ setproctitle(const char *fmt, ...)
#endif /* OLD_SETPROCTITLE */
static void
+appendf(char **strp, char *fmt, ...)
+{
+ va_list ap;
+ char *ostr, *p;
+
+ va_start(ap, fmt);
+ vasprintf(&p, fmt, ap);
+ va_end(ap);
+ if (p == NULL)
+ fatalerror("Ran out of memory.");
+ if (*strp == NULL)
+ *strp = p;
+ else {
+ ostr = *strp;
+ asprintf(strp, "%s%s", ostr, p);
+ if (*strp == NULL)
+ fatalerror("Ran out of memory.");
+ free(ostr);
+ }
+}
+
+static void
+logcmd(char *cmd, char *file1, char *file2, off_t cnt)
+{
+ char *msg = NULL;
+ char wd[MAXPATHLEN + 1];
+
+ if (logging <= 1)
+ return;
+ /* If either filename isn't absolute, get current dir for log message. */
+ if ((file1 && file1[0] != '/') || (file2 && file2[0] != '/')) {
+ if (getcwd(wd, sizeof(wd) - 1) == NULL)
+ strcpy(wd, strerror(errno));
+ } else
+ wd[0] = '\0';
+
+ appendf(&msg, "%s", cmd);
+ if (file1)
+ appendf(&msg, " %s", file1);
+ if (file2)
+ appendf(&msg, " %s", file2);
+ if (cnt >= 0)
+ appendf(&msg, " = %jd bytes", (intmax_t)cnt);
+ if (wd[0])
+ appendf(&msg, " (wd: %s)", wd);
+ syslog(LOG_INFO, "%s", msg);
+ free(msg);
+}
+
+static void
logxfer(char *name, off_t size, time_t start)
{
char buf[MAXPATHLEN + 1024];
OpenPOWER on IntegriCloud