Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

讓 Pureftpd 1.0.21 使用 -T (--userbandwidth) 或 -y (--peruserlimits) 的設定時, 有例外情形
post by tommy @ 11 九月, 2006 14:50
想限制使用 ftp 的連線數, 以及所佔用的頻寬大小. 雖然 pure-ftpd 有 -T 與 -y 參數可以達到我的要求, 不過... 我又不想限制我自己. 所以, 就利用之前修改的 -A-P 的例外功能, 來限制所有非內部網路連線, 且會 chroot 的使用者.

這個 patch 可以由這個抓取: http://www.teatime.com.tw/~tommy/mypatch/pureftpd_no_bandwidth.patch

diff -Nur src.orig/ftpd.c src/ftpd.c
--- src.orig/ftpd.c 2006-06-12 18:44:25.000000000 +0800
+++ src/ftpd.c 2006-09-11 14:33:30.885922891 +0800
@@ -405,6 +405,48 @@
(void) title;
}

+// add by twu2 20060612 begin
+// check local net in /etc/localnet
+static void check_local_net(const struct sockaddr_storage * const addr)
+{
+ FILE *fp;
+ unsigned long a1 = 0U;
+ unsigned long a2 = 0U;
+ unsigned long mask = 0U;
+ unsigned int b1, b2, b3, b4;
+ unsigned int m1, m2, m3, m4;
+ char buf[1024];
+
+ if (addr == NULL) return;
+ // only for IPV4 now
+ if (STORAGE_FAMILY(*addr) != AF_INET) return;
+ a1 = ntohl(STORAGE_SIN_ADDR(*addr));
+ fp = fopen("/etc/localnet", "rt");
+ // no localnet file
+ if (fp == NULL) return;
+ while (1) {
+ if (fgets(buf, 1024, fp) == NULL) break;
+ b1 = b2 = b3 = b4 = m1 = m2 = m3 = m4 = 0;
+ if ((sscanf(buf, "%u.%u.%u.%u/%u.%u.%u.%u", &b1, &b2, &b3, &b4, &m1, &m2, &m3, &m4) != 8) ||
+ b1 > 255U || b2 > 255U || b3 > 255U || b4 > 255U ||
+ (b1 | b2 | b3 | b4) == 0U ||
+ m1 > 255U || m2 > 255U || m3 > 255U || m4 > 255U ||
+ (m1 | m2 | m3 | m4) == 0U)
+ continue;
+ a2 = b1 << 24 | b2 << 16 | b3 << 8 | b4;
+ mask = m1 << 24 | m2 << 16 | m3 << 8 | m4;
+ // correct format
+ if ((a1 & mask) == (a2 & mask)) {
+ // same subnet
+ is_local = 1;
+ break;
+ }
+ }
+ fclose(fp);
+ return;
+}
+// add by twu2 20060612 end
+
/* Check whether an address is valid, return 1 if ok, 0 otherwise.
* Unfortunately, multicasting with the FTP protocol is impossible,
* you have to use things like MTP instead. So prohibit multicast.
@@ -1531,6 +1573,31 @@
return chdir(home);
}

+// add by twu2 20060612 begin
+int is_no_chroot_user(char *username)
+{
+ FILE *fp;
+ char buf[1024];
+ char *p;
+ int match = 0;
+
+ if (username == NULL || *username == '\0') return 0;
+ fp = fopen("/etc/pure-ftpd/nochroot.user", "rt");
+ if (fp == NULL) return 0;
+ while (1) {
+ if (fgets(buf, 1024, fp) == NULL) break;
+ p = strtok(buf, " \t\r\n");
+ if (p == NULL) continue;
+ if (strcmp(p, username) == 0) {
+ match = 1;
+ break;
+ }
+ }
+ fclose(fp);
+ return match;
+}
+// add by twu2 20060612 end
+
void dopass(char *password)
{
static unsigned int tapping;
@@ -1545,6 +1612,9 @@
#ifdef WITH_RFC2640
char *nwd = NULL;
#endif
+// add by twu2 20060911 begin
+ int skip_chroot = 0;
+// add by twu2 20060911 end

if (loggedin != 0) {
if (guest != 0) {
@@ -1594,6 +1664,10 @@
goto randomsleep;
}

+// add by twu2 20060911 begin
+ skip_chroot = is_no_chroot_user(account);
+ if (is_local == 0 && skip_chroot == 0) {
+// add by twu2 200606911 end
#ifdef PER_USER_LIMITS
if (per_user_max > 0U && ftpwho_read_count(account) >= per_user_max) {
addreply(421, MSG_PERUSER_MAX, (unsigned long) per_user_max);
@@ -1601,6 +1675,9 @@
_EXIT(1);
}
#endif
+// add by twu2 20060911 begin
+ }
+// add by twu2 200606911 end

/* Add username to the uid/name cache */
(void) getname(authresult.uid);
@@ -1689,6 +1766,17 @@
if (loggedin == 0) {
candownload = 1; /* real users can always download */
}
+// add by twu2 20060911 begin
+ if (userchroot == 2 && skip_chroot) {
+ addreply_noformat(0, "You are not in CHROOT mode!");
+ userchroot = 0;
+ throttling = 0;
+ }
+ if (is_local) {
+ addreply_noformat(0, "You are from local network!");
+ throttling = 0;
+ }
+// add by twu2 200606911 end
#ifdef THROTTLING
if ((throttling == 2) || (guest != 0 && throttling == 1)) {
addreply_noformat(0, MSG_BANDWIDTH_RESTRICTED);
@@ -2123,7 +2211,11 @@
}
switch (psvtype) {
case 0:
- if (STORAGE_FAMILY(force_passive_ip) == 0) {
+// add by twu2 20060612 begin
+ // if the connection from local subnet, don't do force passive ip convert
+ //if (STORAGE_FAMILY(force_passive_ip) == 0) {
+ if (is_local || STORAGE_FAMILY(force_passive_ip) == 0) {
+// add by twu2 20060612 end
a = ntohl(STORAGE_SIN_ADDR(dataconn));
} else if (STORAGE_FAMILY(force_passive_ip) == AF_INET6) {
(void) close(datafd);
@@ -3438,14 +3530,14 @@
# define FEAT_UTF8 ""
#endif

- char feat[] = FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV FEAT_ESTA FEAT_TLS FEAT_UTF8;
+ char feat[] = FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV FEAT_ESTA FEAT_UTF8 FEAT_TLS;

if (disallow_passive != 0) {
- feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP] = 0;
+ feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_UTF8 FEAT_TLS] = 0;
}
#ifndef MINIMAL
else if (STORAGE_FAMILY(force_passive_ip) != 0) {
- feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV] = 0;
+ feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV FEAT_UTF8 FEAT_TLS] = 0;
}
#endif
addreply_noformat(0, feat);
@@ -4448,6 +4540,9 @@
die(421, LOG_ERR, MSG_GETPEERNAME ": %s" , strerror(errno));
}
fourinsix(&peer);
+// add by twu2 20060612 begin
+ check_local_net(&peer);
+// add by twu2 20060612 end
if (checkvalidaddr(&peer) == 0) {
die(425, LOG_ERR, MSG_INVALID_IP);
}
@@ -4486,6 +4581,9 @@
#endif
iptropize(&peer);
logfile(LOG_INFO, MSG_NEW_CONNECTION, host);
+// add by twu2 20060612 begin
+ logfile(LOG_INFO, is_local == 1 ? "from local" : "from remote");
+// add by twu2 20060612 end

#ifndef NO_BANNER
# ifdef BORING_MODE
diff -Nur src.orig/globals.h src/globals.h
--- src.orig/globals.h 2006-02-15 16:55:00.000000000 +0800
+++ src/globals.h 2006-06-12 21:34:39.361685000 +0800
@@ -73,6 +73,9 @@
GLOBAL0(signed char force_ls_a);
GLOBAL0(struct sockaddr_storage peer);
GLOBAL0(struct sockaddr_storage force_passive_ip);
+// add by twu2 20060612 begin
+GLOBAL(signed char is_local, 0);
+// add by twu2 20060612 end
GLOBAL0(const char *force_passive_ip_s);
GLOBAL0(unsigned short int peerdataport);
GLOBAL0(double maxload);

這樣子, 就可以限制連線與頻寬, 又不會影響到我自己.

PS. 這個 patch, 會包含之前的 -A 與 -P 那兩個 patch.

Del.icio.us Furl HEMiDEMi Technorati MyShare
迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 92 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS