Package: linux-ftpd / 0.17-34

002-from_sarge.diff Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
Description: Patches taken from linux-ftpd_0.17-20sarge2.diff.gz.
 Difference constructed against linux-ftpd_0.17-13.diff.gz.
Author: Herber Xu <herbert@debian.org>
        Robert Millan <rmh@debian.org>
	Alberto Gonzalez Iniesta <agi@inittab.org>
X-Comment: Contributions by Dean Gaudet and Paul Szabo.
Forwarded: no
Last-Update: 2006-09-25
diff -u linux-ftpd-0.17/ftpd/ftpcmd.y linux-ftpd-0.17/ftpd/ftpcmd.y
--- linux-ftpd-0.17/ftpd/ftpcmd.y
+++ linux-ftpd-0.17/ftpd/ftpcmd.y
@@ -114,6 +114,7 @@
 %union {
 	intmax_t i;
 	char *s;
+	const char *cs;
 }
 
 %token
@@ -313,12 +314,12 @@
 	| LIST check_login CRLF
 		{
 			if ($2)
-				retrieve("/bin/ls -lgA", "");
+				retrieve("/bin/ls -lA", "");
 		}
 	| LIST check_login SP pathname CRLF
 		{
 			if ($2 && $4 != NULL)
-				retrieve("/bin/ls -lgA %s", $4);
+				retrieve("/bin/ls -lA %s", $4);
 			if ($4 != NULL)
 				free($4);
 		}
@@ -1053,7 +1054,7 @@
 					/* NOTREACHED */
 				}
 				state = p->state;
-				yylval.s = (char *)p->name;  /* XXX */
+				yylval.cs = p->name;
 				return (p->token);
 			}
 			break;
@@ -1079,7 +1080,7 @@
 					/* NOTREACHED */
 				}
 				state = p->state;
-				yylval.s = (char *) p->name;  /* XXX */
+				yylval.cs = p->name;
 				return (p->token);
 			}
 			state = CMD;
diff -u linux-ftpd-0.17/ftpd/ftpd.8 linux-ftpd-0.17/ftpd/ftpd.8
--- linux-ftpd-0.17/ftpd/ftpd.8
+++ linux-ftpd-0.17/ftpd/ftpd.8
@@ -46,7 +46,7 @@
 Internet File Transfer Protocol server
 .Sh SYNOPSIS
 .Nm ftpd
-.Op Fl AdDhlMPSU
+.Op Fl AdDhlMnPSU
 .Op Fl T Ar maxtimeout
 .Op Fl t Ar timeout
 .Op Fl u Ar mask
@@ -105,12 +105,8 @@
 the IP number the client connected to, and located inside
 .Pa ~ftp
 is used instead.
-.It Fl p
-Disable passive mode ftp connections.  This is useful if you are behind
-a firewall that refuses connections to arbitrary high numbered ports.
-Many ftp clients try passive mode first and do not always react gracefully
-to a server that refuses connections to the port it asked the client to
-connect to.
+.It Fl n
+Use numeric IP addresses in logs instead of doing hostname lookup.
 .It Fl P
 Permit illegal port numbers or addresses for PORT command initiated connects.
 By default
@@ -369,7 +365,15 @@
 (or whatever your
 .Xr ls
 command is linked to)
-must be present.  Note that if you're using a 2.2.* or later Linux kernel,
+must be present.
+In order to read 
+.Xr passwd 5
+and
+.Xr group 5 ,
+the library
+.Xr libnss_files.so.2
+is also needed.
+Note that if you're using a 2.2.* or later Linux kernel,
 .Xr ld-linux.so.2
 must be executable as well as readable (555).  All other files should be mode
 444.
diff -u linux-ftpd-0.17/ftpd/ftpd.c linux-ftpd-0.17/ftpd/ftpd.c
--- linux-ftpd-0.17/ftpd/ftpd.c
+++ linux-ftpd-0.17/ftpd/ftpd.c
@@ -165,7 +165,8 @@
 #endif
 int	debug = 0;
 int	timeout = 900;    /* timeout after 15 minutes of inactivity */
-int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
+int	maxtimeout = 7200; /* don't allow idle time to be set beyond 2 hours */
+int	numeric_hosts = 0; /* log numeric IP rather than doing lookup */
 int	logging;
 int	high_data_ports = 0;
 int	anon_only = 0;
@@ -312,7 +313,7 @@
 	socklen_t addrlen;
 	char *cp, line[LINE_MAX];
 	FILE *fd;
-	const char *argstr = "AdDhlMSt:T:u:UvP";
+	const char *argstr = "AdDhlMnSt:T:u:UvP";
 	struct hostent *hp;
 
 #ifdef __linux__
@@ -372,6 +373,10 @@
 			multihome = 1;
 			break;
 
+		case 'n':
+			numeric_hosts = 1;
+			break;
+
 		case 'S':
 			stats = 1;
 			break;
@@ -906,7 +911,6 @@
 
 static int pam_doit(void)
 {
-	char *user;
 	int error;
 
 	error = pam_authenticate(pamh, 0);
@@ -926,6 +930,8 @@
 		return 1;
 	}
 	if (error == PAM_SUCCESS) {
+		const void *vp;
+
 		/* Alright, we got it */
 		error = pam_acct_mgmt(pamh, 0);
 		if (error == PAM_SUCCESS)
@@ -933,8 +939,10 @@
 		if (error == PAM_SUCCESS)
 			error = pam_setcred(pamh, PAM_ESTABLISH_CRED);
 		if (error == PAM_SUCCESS)
-			error = pam_get_item(pamh, PAM_USER, (const void **) &user);
+			error = pam_get_item(pamh, PAM_USER, &vp);
 		if (error == PAM_SUCCESS) {
+			const char *user = vp;
+
 			if (strcmp(user, "ftp") == 0) {
 				guest = 1;
 			}
@@ -1151,6 +1159,13 @@
 		}
 		strcpy(pw->pw_dir, "/");
 		setenv("HOME", "/", 1);
+	}
+	/* PSz 25 Aug 06  chdir for real users done after setting UID */
+	if (seteuid((uid_t)pw->pw_uid) < 0) {
+		reply(550, "Can't set uid.");
+		goto bad;
+	}
+	if (guest || dochroot) { /* do nothing, handled above */
 	} else if (chdir(pw->pw_dir) < 0) {
 		if (chdir("/") < 0) {
 			reply(530, "User %s: can't change directory to %s.",
@@ -1159,10 +1174,7 @@
 		} else
 			lreply(230, "No directory! Logging in with home=/");
 	}
-	if (seteuid((uid_t)pw->pw_uid) < 0) {
-		reply(550, "Can't set uid.");
-		goto bad;
-	}
+
 	sigfillset(&allsigs);
 	sigprocmask(SIG_UNBLOCK,&allsigs,NULL);
 
@@ -1400,7 +1412,8 @@
 			goto bad;
 		sleep(tries);
 	}
-	(void) seteuid((uid_t)pw->pw_uid);
+/* PSz 25 Aug 06  Check return status */
+	if (seteuid((uid_t)pw->pw_uid) != 0) _exit(1);
 	sigfillset(&allsigs);
 	sigprocmask (SIG_UNBLOCK, &allsigs, NULL);
 
@@ -1432,7 +1445,8 @@
 bad:
 	/* Return the real value of errno (close may change it) */
 	t = errno;
-	(void) seteuid((uid_t)pw->pw_uid);
+/* PSz 25 Aug 06  Check return status */
+	if (seteuid((uid_t)pw->pw_uid) != 0) _exit(1);
 	sigfillset (&allsigs);
 	sigprocmask (SIG_UNBLOCK, &allsigs, NULL);
 	(void) close(s);
@@ -1786,7 +1800,7 @@
 	int c;
 	char line[LINE_MAX];
 
-	(void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename);
+	(void)snprintf(line, sizeof(line), "/bin/ls -lA %s", filename);
 	fin = ftpd_popen(line, "r");
 	lreply(211, "status of %s:", filename);
 	while ((c = getc(fin)) != EOF) {
@@ -2063,10 +2077,11 @@
 
 static void dolog(struct sockaddr_in *sn)
 {
-	struct hostent *hp = gethostbyaddr((char *)&sn->sin_addr,
-		sizeof(struct in_addr), AF_INET);
+	struct hostent *hp;
 
-	if (hp)
+	if (!numeric_hosts &&
+		(hp = gethostbyaddr((char *)&sn->sin_addr,
+				    sizeof(struct in_addr), AF_INET)))
 		(void) strncpy(remotehost, hp->h_name, sizeof(remotehost)-1);
 	else
 		(void) strncpy(remotehost, inet_ntoa(sn->sin_addr),
--- linux-ftpd-0.17.orig/ftpd/popen.c
+++ linux-ftpd-0.17/ftpd/popen.c
@@ -169,8 +169,13 @@
 		 * XXX: this doesn't seem right... and shouldn't
 		 * we initgroups, or at least setgroups(0,0)?
 		 */
-		setgid(getegid());
-		setuid(i);
+
+/*
+ * PSz 25 Aug 06  Must check the return status of these setgid/setuid calls,
+ * see  http://www.bress.net/blog/archives/34-setuid-madness.html
+ */
+		if ( setgid(geteuid())	!= 0 ) _exit(1);
+		if ( setuid(i)		!= 0 ) _exit(1);
  
 #ifndef __linux__
 /*