Date: Sun, 10 Aug 1997 19:57:20 -0700 (PDT) From: Ulf Zimmermann <ulf@Alameda.net> To: wu-ftpd-bugs@academ.com Cc: hackers@freebsd.org, bsdnet@Melmac.org Subject: Diffs for further virtual settings Message-ID: <199708110257.TAA07795@Melmac.org>
next in thread | raw e-mail | index | archive | help
Hello. Below the signarture is a diff file for "access.c", "extensions.c", "ftpcmd.y" and "ftpd.c". The diffs allow further virtual settings like: limit upload overwrite rename umask noretrieve deny email log commands log transfers chmod delete I used the FreeBSD port based version of wu-ftpd-2.4.2BETA13 and tried not to include the patches, which the port system applies. The changes are also not very throughoutly tested. -- Regards, Ulf. -------------------------------------------------------------------------- Ulf Zimmermann, 1525 Pacific Ave., Alameda, CA-94501, #: 510-769-2936 Alameda Networks, Inc. | http://www.Alameda.net | Fax#: 510-521-5073 diff -c -r src.orig/access.c src/access.c *** src.orig/access.c Sun Aug 10 19:44:44 1997 --- src/access.c Sun Aug 10 18:55:32 1997 *************** *** 43,48 **** --- 43,55 ---- #else #include <syslog.h> #endif + #ifdef VIRTUAL + #include <netinet/in.h> + #include <netinet/in_systm.h> + #include <netinet/ip.h> + #include <sys/socket.h> + #include <arpa/inet.h> + #endif #include <time.h> #include <ctype.h> #include <pwd.h> *************** *** 335,340 **** --- 342,352 ---- #endif { char class[1024]; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif extern int log_incoming_xfers, log_outbound_xfers, *************** *** 396,402 **** } /* plan on expanding command syntax to include classes for each of these */ - entry = (struct aclmember *) NULL; while (getaclentry("log", &entry)) { if (!strcasecmp(ARG0, "commands")) { --- 408,413 ---- *************** *** 425,430 **** --- 436,481 ---- log_outbound_xfers = outbound; } } + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "log")) { + if (!strcasecmp(ARG2, "commands")) { + if (anonymous && strcasestr(ARG3, "anonymous")) + log_commands = 1; + if (guest && strcasestr(ARG3, "guest")) + log_commands = 1; + if (!guest && !anonymous && strcasestr(ARG3, "real")) + log_commands = 1; + } + if (!strcasecmp(ARG2, "transfers")) { + set = 0; + if (strcasestr(ARG1, "anonymous") && anonymous) + set = 1; + if (strcasestr(ARG1, "guest") && guest) + set = 1; + if (strcasestr(ARG1, "real") && !guest && !anonymous) + set = 1; + if (strcasestr(ARG2, "inbound")) + inbound = 1; + if (strcasestr(ARG2, "outbound")) + outbound = 1; + if (set) + log_incoming_xfers = inbound; + if (set) + log_outbound_xfers = outbound; + } + } + } + } + } + #endif /* VIRTUAL */ } /*************************************************************************/ *************** *** 485,494 **** --- 536,575 ---- { int limit; struct aclmember *entry = NULL; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif if (msgpathbuf) *msgpathbuf = '\0'; + #ifdef VIRTUAL + /* virtual ip_addr limit <class> <n> <times> [<message_file>] */ + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3 || !ARG4) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "limit")) { + if (!strcmp(class, ARG2)) { + limit = atoi(ARG3); + if (validtime(ARG4)) { + if (ARG5 && msgpathbuf) + strcpy(msgpathbuf, ARG5); + return (limit); + } + } + } + } + } + } + #endif /* VIRTUAL */ + /* limit <class> <n> <times> [<message_file>] */ while (getaclentry("limit", &entry)) { if (!ARG0 || !ARG1 || !ARG2) *************** *** 520,528 **** --- 601,641 ---- #endif { struct aclmember *entry = NULL; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif if (msgpathbuf) *msgpathbuf = (char) NULL; + + #ifdef VIRTUAL + /* virtual ip_addr deny <addrglob> [<message_file>] */ + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "deny")) { + if (!nameserved && !strcmp(ARG2, "!nameserved")) { + if (ARG3) + strcpy(msgpathbuf, entry->arg[3]); + return(1); + } + if (hostmatch(ARG2)) { + if (ARG3) + strcpy(msgpathbuf, entry->arg[3]); + return(1); + } + } + } + } + } + #endif /* VIRTUAL */ /* deny <addrglob> [<message_file>] */ while (getaclentry("deny", &entry)) { diff -c -r src.orig/extensions.c src/extensions.c *** src.orig/extensions.c Sun Aug 10 19:44:44 1997 --- src/extensions.c Sun Aug 10 19:29:23 1997 *************** *** 42,47 **** --- 42,54 ---- #else #include <syslog.h> #endif + #ifdef VIRTUAL + #include <netinet/in.h> + #include <netinet/in_systm.h> + #include <netinet/ip.h> + #include <sys/socket.h> + #include <arpa/inet.h> + #endif #include <time.h> #include <pwd.h> #include <grp.h> *************** *** 55,60 **** --- 62,69 ---- #include <sys/statvfs.h> #elif defined(HAVE_SYS_VFS) #include <sys/vfs.h> + #elif defined(__FreeBSD__) + #include <sys/mount.h> #endif #include <arpa/ftp.h> *************** *** 157,163 **** return(buf.f_bavail * buf.f_frsize / 1024); } ! #elif defined(HAVE_SYS_VFS) int getSize(s) char *s; { --- 166,172 ---- return(buf.f_bavail * buf.f_frsize / 1024); } ! #elif defined(HAVE_SYS_VFS) || defined(__FreeBSD__) int getSize(s) char *s; { *************** *** 194,199 **** --- 203,213 ---- int limit; extern struct passwd *pw; struct aclmember *entry = NULL; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif (void) time(&curtime); (void) acl_getclass(buffer); *************** *** 206,213 **** --- 220,248 ---- else { switch (*++inptr) { case 'E': + #ifdef VIRTUAL + /* virtual ip_addr email <name> */ + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "email")) { + sprintf(outptr, "%s", ARG2); + goto email_breakout; + } + } + } + } + #endif /* VIRTUAL */ if ( (getaclentry("email", &entry)) && ARG0 ) sprintf(outptr, "%s", ARG0); + #ifdef VIRTUAL + email_breakout: + #endif /* VIRTUAL */ break; case 'N': sprintf(outptr, "%d", acl_countusers(buffer)); *************** *** 222,228 **** break; case 'F': ! #if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) sprintf(outptr, "%lu", getSize(".")); #endif break; --- 257,263 ---- break; case 'F': ! #if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined(__FreeBSD__) sprintf(outptr, "%lu", getSize(".")); #endif break; *************** *** 806,811 **** --- 841,851 ---- struct passwd *pwent; struct group *grent; char buf[BUFSIZ]; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif while (getaclentry("upload", &entry) && ARG0 && ARG1 && ARG2 != NULL) { if (ARG3 && ARG4) { *************** *** 824,829 **** --- 864,900 ---- endgrent(); } } + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3 || !ARG4) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "upload")) { + if (ARG5 && ARG6) { + pwent = getpwnam(ARG5); + grent = getgrnam(ARG6); + + if (pwent) sprintf(buf, "%d", pwent->pw_uid); + else sprintf(buf, "%d", 0); + ARG5 = (char *) malloc(strlen(buf) + 1); + strcpy(ARG5, buf); + + if (grent) sprintf(buf, "%d", grent->gr_gid); + else sprintf(buf, "%d", 0); + ARG6 = (char *) malloc(strlen(buf) + 1); + strcpy(ARG6, buf); + endgrent(); + } + } + } + } + } + #endif /* VIRTUAL */ + } int *************** *** 956,961 **** --- 1027,1037 ---- char path[BUFSIZ]; char *sp; extern struct passwd *pw; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif *valid = 0; /* what's our current directory? */ *************** *** 981,986 **** --- 1057,1088 ---- else ap6 = NULL; } } + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3 || !ARG4) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "upload")) { + if ( (!strcmp(ARG2, pw->pw_dir)) && + ((i = path_compare(ARG3, cwdir)) >= match_value) ) { + match_value = i; + ap2 = ARG4; + if (ARG5) ap3 = ARG5; + else ap3 = NULL; + if (ARG6) ap4 = ARG6; + else ap4 = NULL; + if (ARG8) ap6 = ARG8; + else ap6 = NULL; + } + } + } + } + } + #endif /* VIRTUAL */ if ( ((ap2 && !strcasecmp(ap2, "no")) && (ap3 && strcasecmp(ap3, "dirs"))) || (ap3 && !strcasecmp(ap3, "nodirs")) || (ap6 && !strcasecmp(ap6, "nodirs")) ) { *************** *** 1022,1027 **** --- 1124,1134 ---- struct aclmember *entry = NULL; extern struct passwd *pw; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif *valid = 0; *************** *** 1053,1058 **** --- 1160,1192 ---- else ap5 = NULL; } } + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3 || !ARG4) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "upload")) { + if ( (!strcmp(ARG2, pw->pw_dir)) && + ((i = path_compare(ARG3, cwdir)) >= match_value) ) { + match_value = i; + ap1 = ARG3; + ap2 = ARG4; + if (ARG5) ap3 = ARG5; + else ap3 = NULL; + if (ARG6) ap4 = ARG6; + else ap4 = NULL; + if (ARG7) ap5 = ARG7; + else ap5 = NULL; + } + } + } + } + } + #endif /* VIRTUAL */ if (ap3 && ( (!strcasecmp("dirs",ap3)) || (!strcasecmp("nodirs", ap3)) )) ap3 = NULL; *************** *** 1092,1104 **** { int pdelete = 1; struct aclmember *entry = NULL; while (getaclentry("delete", &entry) && ARG0 && ARG1 != NULL) { if (type_match(ARG1)) if (*ARG0 == 'n') pdelete = 0; } ! /* H* fix: no deletion, period. You put a file here, I get to look at it. */ #ifdef PARANOID pdelete = 0; --- 1226,1264 ---- { int pdelete = 1; struct aclmember *entry = NULL; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif while (getaclentry("delete", &entry) && ARG0 && ARG1 != NULL) { if (type_match(ARG1)) if (*ARG0 == 'n') pdelete = 0; } ! #ifdef VIRTUAL ! virtual_len = sizeof(virtual_addr); ! if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { ! virtual_ptr = (struct sockaddr_in *) &virtual_addr; ! entry = (struct aclmember *) NULL; ! while (getaclentry("virtual", &entry)) { ! if (!ARG0 || !ARG1 || !ARG2 || !ARG3) ! continue; ! if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { ! if(!strcmp(ARG1, "delete")) { ! if (type_match(ARG3)) { ! if (*ARG2 == 'n') ! pdelete = 0; ! else ! pdelete = 1; ! } ! } ! } ! } ! } ! #endif /* VIRTUAL */ ! /* H* fix: no deletion, period. You put a file here, I get to look at it. */ #ifdef PARANOID pdelete = 0; *************** *** 1127,1132 **** --- 1287,1297 ---- char cwd[MAXPATHLEN+1], realwd[MAXPATHLEN+1], realname[MAXPATHLEN+1]; int i; struct aclmember *entry = NULL; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif if (name == (char *)NULL || *name == '\0') return 0; *************** *** 1139,1144 **** --- 1304,1334 ---- realpath (cwd, realwd); realpath (name, realname); + + #ifdef VIRTUAL + /* virtual ip_addr noretrieve <filename> <filename> */ + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "noretrieve")) { + for (i = 2; i< MAXARGS && + (entry->arg[i] != (char *)NULL) && (*(entry->arg[i]) !='\0'); i++) + if (strcmp (((*(entry->arg[i]) == '/') ? realname : + lbasename (realname)), entry->arg[i]) == 0) + { + reply (550, "%s is marked unretrievable", entry->arg[i]); + return 1; + } + } + } + } + } + #endif /* VIRTUAL */ while (getaclentry("noretrieve", &entry)) { if (ARG0 == (char *)NULL) diff -c -r src.orig/ftpcmd.y src/ftpcmd.y *** src.orig/ftpcmd.y Sun Aug 10 19:44:44 1997 --- src/ftpcmd.y Sun Aug 10 18:55:31 1997 *************** *** 61,66 **** --- 61,73 ---- #else #include <syslog.h> #endif + #ifdef VIRTUAL + #include <netinet/in.h> + #include <netinet/in_systm.h> + #include <netinet/ip.h> + #include <sys/socket.h> + #include <arpa/inet.h> + #endif #include <time.h> #include <string.h> #include <limits.h> *************** *** 480,485 **** --- 487,497 ---- mode_t oldmask; struct aclmember *entry = NULL; int ok = 1; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif /* VIRTUAL */ if (log_commands) syslog(LOG_INFO, "SITE UMASK %03o", $6); if ($4) { *************** *** 488,493 **** --- 500,522 ---- if (type_match(ARG1)) if (*ARG0 == 'n') ok = 0; } + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "umask")) { + if (type_match(ARG3)) + if (*ARG2 == 'n') ok = 0; + } + } + } + } + #endif /* VIRTUAL */ if (ok) { if (($6 < 0) || ($6 > 0777)) { reply(501, "Bad UMASK value"); *************** *** 503,508 **** --- 532,542 ---- = { struct aclmember *entry = NULL; int ok = 1; + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif /* VIRTUAL */ if (log_commands) syslog(LOG_INFO, "SITE CHMOD %03o %s", $6, $8); if ($4 && $8) { *************** *** 511,516 **** --- 545,567 ---- if (type_match(ARG1)) if (*ARG0 == 'n') ok = 0; } + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "chmod")) { + if (type_match(ARG3)) + if (*ARG2 == 'n') ok = 0; + } + } + } + } + #endif /* VIRTUAL */ if (ok) { if (($6 < 0) || ($6 > 0777)) reply(501, diff -c -r src.orig/ftpd.c src/ftpd.c *** src.orig/ftpd.c Sun Aug 10 19:44:44 1997 --- src/ftpd.c Sun Aug 10 18:55:31 1997 *************** *** 1978,1983 **** --- 1978,1988 ---- char *gunique(); #endif time_t start_time = time(NULL); + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif struct aclmember *entry = NULL; *************** *** 2023,2029 **** open_flags |= O_EXCL; } } ! #ifdef PARANOID overwrite = 0; #endif --- 2028,2055 ---- open_flags |= O_EXCL; } } ! #ifdef VIRTUAL ! virtual_len = sizeof(virtual_addr); ! if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { ! virtual_ptr = (struct sockaddr_in *) &virtual_addr; ! entry = (struct aclmember *) NULL; ! while (getaclentry("virtual", &entry)) { ! if (!ARG0 || !ARG1 || !ARG2 || !ARG3) ! continue; ! if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { ! if(!strcmp(ARG1, "overwrite")) { ! if (type_match(ARG3)) { ! if (strcmp(ARG2, "yes") != 0) { ! overwrite = 0; ! open_flags |= O_EXCL; ! } ! } ! } ! } ! } ! } ! #endif /* VIRTUAL */ ! #ifdef PARANOID overwrite = 0; #endif *************** *** 3059,3064 **** --- 3085,3095 ---- { struct stat st; struct aclmember *entry = NULL; /* Added: fixes a bug. _H*/ + #ifdef VIRTUAL + int virtual_len; + struct sockaddr_in virtual_addr; + struct sockaddr_in *virtual_ptr; + #endif if (lstat(name, &st) < 0) { perror_reply(550, name); *************** *** 3068,3073 **** --- 3099,3126 ---- /* if rename permission denied and file exists... then deny the user * permission to rename the file. */ + #ifdef VIRTUAL + virtual_len = sizeof(virtual_addr); + if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { + virtual_ptr = (struct sockaddr_in *) &virtual_addr; + entry = (struct aclmember *) NULL; + while (getaclentry("virtual", &entry)) { + if (!ARG0 || !ARG1 || !ARG2 || !ARG3) + continue; + if (!strcmp(ARG0, inet_ntoa(virtual_ptr->sin_addr))) { + if(!strcmp(ARG1, "rename")) { + if (type_match(ARG3)) { + if (strcmp(ARG2, "yes")) { + reply(553, "%s: Permission denied. (rename)", name); + return ((char *) 0); + } + } + } + } + } + } + #endif /* VIRTUAL */ + while (getaclentry("rename", &entry) && ARG0 && ARG1 != NULL) { if (type_match(ARG1)) if (strcmp(ARG0, "yes")) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199708110257.TAA07795>
