Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Aug 2001 20:11:02 +0200
From:      Joerg Wunsch <j@ida.interface-business.de>
To:        audit@freebsd.org
Cc:        security@freebsd.org
Subject:   why does telnetd run as root?
Message-ID:  <20010830201102.O69247@ida.interface-business.de>

next in thread | raw e-mail | index | archive | help
Upon answering the question in <subject>, i noticed that the only
reason for it is that login(1) currently requires root permissions in
case -h hostname is given on its invocation.  (Port 23 is bound by
inetd anyway.)  But then, it's IMHO much safer to run telnetd as user
`daemon', and have login(1) allow user daemon to pass -h.  This
minimally increases the chance that someone might fake a hostname to
be logged in utmp/wtmp (although user dameon is not supposed to be a
usable account anyway), but adds us the ability to run telnetd with
the little-privileged ID of daemon, so the next buffer overflow at
least won't pose a root compromise...

Index: login.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/login/login.c,v
retrieving revision 1.51.2.11
diff -u -r1.51.2.11 login.c
--- login.c	2001/08/07 09:28:52	1.51.2.11
+++ login.c	2001/08/30 16:17:46
@@ -131,6 +131,7 @@
 #define	DEFAULT_RETRIES	10
 #define	DEFAULT_PROMPT		"login: "
 #define	DEFAULT_PASSWD_PROMPT	"Password:"
+#define	DAEMONUSER	"daemon"
 
 /*
  * This bounds the time given to login.  Not a define so it can
@@ -158,7 +159,7 @@
 	struct utmp utmp;
 	int rootok, retries, backoff;
 	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
-	int changepass;
+	int changepass, allowhopt;
 	time_t warntime;
 	uid_t uid, euid;
 	gid_t egid;
@@ -167,6 +168,7 @@
 	char tname[sizeof(_PATH_TTY) + 10];
 	char *shell = NULL;
 	login_cap_t *lc = NULL;
+	struct passwd *daemonuser;
 #ifdef USE_PAM
 	pid_t pid;
 	int e;
@@ -201,13 +203,26 @@
 	uid = getuid();
 	euid = geteuid();
 	egid = getegid();
+	/*
+	 * Try finding user "daemon".  If it exists, we will allow it to
+	 * set the -h option, in addition to uid == 0.  This allows telnetd
+	 * to be run as daemon instead of root.
+	 */
+	allowhopt = 0;
+	if (uid == 0)
+		allowhopt = 1;
+	else {
+		daemonuser = getpwnam(DAEMONUSER);
+		if (daemonuser && uid == daemonuser->pw_uid)
+			allowhopt = 1;
+	}
 	while ((ch = getopt(argc, argv, "fh:p")) != -1)
 		switch (ch) {
 		case 'f':
 			fflag = 1;
 			break;
 		case 'h':
-			if (uid)
+			if (!allowhopt)
 				errx(1, "-h option: %s", strerror(EPERM));
 			hflag = 1;
 			strncpy(full_hostname, optarg, sizeof(full_hostname)-1);

-- 
J"org Wunsch					       Unix support engineer
joerg_wunsch@interface-systems.de        http://www.interface-systems.de/~j/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010830201102.O69247>