Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Jul 2002 16:58:07 +0100
From:      Tony Finch <dot@dotat.at>
To:        freebsd-net@freebsd.org, freebsd-audit@freebsd.org
Cc:        dwmalone@freebsd.org, dot@dotat.at
Subject:   [PATCH] inetd auth logging
Message-ID:  <20020722165807.D13903@chiark.greenend.org.uk>

next in thread | raw e-mail | index | archive | help
The patch below adds a -l option to turn on logging of the inetd builtin
auth (RFC 1413) service. It's mainly intended for use with the -g option,
so that there is a record in the logs of the correspondence between
the nonce that inetd returns and the real username associated with the
connection.

Tony.
-- 
f.a.n.finch <dot@dotat.at> http://dotat.at/
VIKING NORTH UTSIRE: NORTHWEST 5 OR 6 DECREASING 4. SHOWERS. MODERATE OR GOOD.



--- src/usr.sbin/inetd/builtins.c	17 Jul 2001 10:45:03 -0000	1.19.2.6
+++ src/usr.sbin/inetd/builtins.c	22 Jul 2002 15:52:21 -0000
@@ -327,25 +327,6 @@
 
 /* ARGSUSED */
 void
-iderror(lport, fport, s, er)	/* Generic ident_stream error-sending func */
-	int lport, fport, s;
-	const char *er;
-{
-	char *p;
-
-	asprintf(&p, "%d , %d : ERROR : %s\r\n", lport, fport, er);
-	if (p == NULL) {
-		syslog(LOG_ERR, "asprintf: %m");
-		exit(EX_OSERR);
-	}
-	send(s, p, strlen(p), MSG_EOF);
-	free(p);
-
-	exit(0);
-}
-
-/* ARGSUSED */
-void
 ident_stream(s, sep)		/* Ident service (AKA "auth") */
 	int s;
 	struct servtab *sep;
@@ -366,10 +347,11 @@
 	fd_set fdset;
 	char buf[BUFSIZE], *p, **av, *osname = NULL, e;
 	char idbuf[MAXLOGNAME] = ""; /* Big enough to hold uid in decimal. */
+	const char *error = ID_UNKNOWN;
 	socklen_t socklen;
 	ssize_t ssize;
 	size_t size, bufsiz;
-	int c, fflag = 0, nflag = 0, rflag = 0, argc = 0;
+	int c, fflag = 0, lflag = 0, nflag = 0, rflag = 0, argc = 0;
 	int gflag = 0, iflag = 0, Fflag = 0, getcredfail = 0, onreadlen;
 	u_short lport, fport;
 
@@ -392,7 +374,7 @@
 		size_t i;
 		u_int32_t rnd32;
 
-		while ((c = getopt(argc, sep->se_argv, "d:fFgino:rt:")) != -1)
+		while ((c = getopt(argc, sep->se_argv, "d:fFgilno:rt:")) != -1)
 			switch (c) {
 			case 'd':
 				if (!gflag)
@@ -431,6 +413,9 @@
 			case 'i':
 				iflag = 1;
 				break;
+			case 'l':
+				lflag = 1;
+				break;
 			case 'n':
 				nflag = 1;
 				break;
@@ -460,7 +445,7 @@
 	}
 	if (osname == NULL) {
 		if (uname(&un) == -1)
-			iderror(0, 0, s, ID_UNKNOWN);
+			goto printerror;
 		osname = un.sysname;
 	}
 
@@ -493,14 +478,14 @@
 			break;
 		FD_SET(s, &fdset);
 		if (select(s + 1, &fdset, NULL, NULL, &tv) == -1)
-			iderror(0, 0, s, ID_UNKNOWN);
+			goto printerror;
 		if (ioctl(s, FIONREAD, &onreadlen) == -1)
-			iderror(0, 0, s, ID_UNKNOWN);
+			goto printerror;
 		if ((size_t)onreadlen > bufsiz)
 			onreadlen = bufsiz;
 		ssize = read(s, &buf[size], (size_t)onreadlen);
 		if (ssize == -1)
-			iderror(0, 0, s, ID_UNKNOWN);
+			goto printerror;
 		else if (ssize == 0)
 			break;
 		bufsiz -= ssize;
@@ -510,22 +495,22 @@
  	}
 	buf[size] = '\0';
 	/* Read two characters, and check for a delimiting character */
-	if (sscanf(buf, "%hu , %hu%c", &lport, &fport, &e) != 3 || isdigit(e))
-		iderror(0, 0, s, ID_INVALID);
-
-	/* Send garbage? */
-	if (gflag)
-		goto printit;
+	if (sscanf(buf, "%hu , %hu%c", &lport, &fport, &e) != 3 || isdigit(e)) {
+		error = ID_INVALID;
+		goto printerror;
+	}
 
 	/*
 	 * If not "real" (-r), send a HIDDEN-USER error for everything.
-	 * If -d is used to set a fallback username, this is used to
-	 * override it, and the fallback is returned instead.
+	 * If -d or -g is used to set a fallback username, this is used
+	 * to override it, and the fallback is returned instead.
+	 * If we are logging we have to do a bit more work.
 	 */
-	if (!rflag) {
-		if (*idbuf == '\0')
-			iderror(lport, fport, s, ID_HIDDEN);
-		goto printit;
+	if (!lflag && (gflag || !rflag)) {
+		if (*idbuf != '\0')
+			goto printit;
+		error = ID_HIDDEN;
+		goto printerror;
 	}
 
 	/*
@@ -537,12 +522,12 @@
 	 */
 	socklen = sizeof(ss[0]);
 	if (getsockname(s, (struct sockaddr *)&ss[0], &socklen) == -1)
-		iderror(lport, fport, s, ID_UNKNOWN);
+		goto printerror;
 	socklen = sizeof(ss[1]);
 	if (getpeername(s, (struct sockaddr *)&ss[1], &socklen) == -1)
-		iderror(lport, fport, s, ID_UNKNOWN);
+		goto printerror;
 	if (ss[0].ss_family != ss[1].ss_family)
-		iderror(lport, fport, s, ID_UNKNOWN);
+		goto printerror;
 	size = sizeof(uc);
 	switch (ss[0].ss_family) {
 	case AF_INET:
@@ -570,17 +555,31 @@
 		break;
 	}
 	if (getcredfail != 0) {
-		if (*idbuf == '\0')
-			iderror(lport, fport, s,
-			    getcredfail == ENOENT ? ID_NOUSER : ID_UNKNOWN);
-		goto printit;
+		if (*idbuf != '\0')
+			goto printit;
+		if (getcredfail == ENOENT)
+			error = ID_NOUSER;
+		goto printerror;
 	}
 
 	/* Look up the pw to get the username and home directory*/
 	errno = 0;
 	pw = getpwuid(uc.cr_uid);
-	if (pw == NULL)
-		iderror(lport, fport, s, errno == 0 ? ID_NOUSER : ID_UNKNOWN);
+	if (pw == NULL) {
+		if (*idbuf != '\0')
+			goto printit;
+		if (errno == 0)
+			error = ID_NOUSER;
+		goto printerror;
+	}
+
+	/* Now do the stuff that we deferred because we are logging. */
+	if (gflag || !rflag) {
+		if (*idbuf != '\0')
+			goto printit;
+		error = ID_HIDDEN;
+		goto printerror;
+	}
 
 	if (iflag)
 		snprintf(idbuf, sizeof(idbuf), "%u", (unsigned)pw->pw_uid);
@@ -593,10 +592,11 @@
 	 */
 	if (nflag) {
 		if (asprintf(&p, "%s/.noident", pw->pw_dir) == -1)
-			iderror(lport, fport, s, ID_UNKNOWN);
+			goto printerror;
 		if (lstat(p, &sb) == 0) {
 			free(p);
-			iderror(lport, fport, s, ID_HIDDEN);
+			error = ID_HIDDEN;
+			goto printerror;
 		}
 		free(p);
 	}
@@ -615,9 +615,9 @@
 		 * symbolic links to sensitive root-owned files or devices.
 		 */
 		if (initgroups(pw->pw_name, pw->pw_gid) == -1)
-			iderror(lport, fport, s, ID_UNKNOWN);
+			goto printerror;
 		if (seteuid(pw->pw_uid) == -1)
-			iderror(lport, fport, s, ID_UNKNOWN);
+			goto printerror;
 		/*
 		 * We can't stat() here since that would be a race
 		 * condition.
@@ -626,7 +626,7 @@
 		 * returning the user's real username.
 		 */
 		if (asprintf(&p, "%s/.fakeid", pw->pw_dir) == -1)
-			iderror(lport, fport, s, ID_UNKNOWN);
+			goto printerror;
 		fakeid_fd = open(p, O_RDONLY | O_NONBLOCK);
 		free(p);
 		if (fakeid_fd == -1 || fstat(fakeid_fd, &sb) == -1 ||
@@ -675,14 +675,32 @@
 
 printit:
 	/* Finally, we make and send the reply. */
-	if (asprintf(&p, "%d , %d : USERID : %s : %s\r\n", lport, fport, osname,
-	    idbuf) == -1) {
+	ssize = asprintf(&p, "%d , %d : USERID : %s : %s\r\n", lport, fport,
+	    osname, idbuf);
+	if (p == NULL) {
 		syslog(LOG_ERR, "asprintf: %m");
 		exit(EX_OSERR);
 	}
-	send(s, p, strlen(p), MSG_EOF);
+	if (lflag)
+		syslog(LOG_INFO, "auth: %.*s (really %s)",
+		    ssize - 2, p, pw ? pw->pw_name : "???");
+	send(s, p, ssize, MSG_EOF);
 	free(p);
-	
+
+	exit(0);
+
+printerror:
+	ssize = asprintf(&p, "%d , %d : ERROR : %s\r\n", lport, fport, error);
+	if (p == NULL) {
+		syslog(LOG_ERR, "asprintf: %m");
+		exit(EX_OSERR);
+	}
+	if (lflag)
+		syslog(LOG_INFO, "auth: %.*s (user %s)",
+		    ssize - 2, p, pw ? pw->pw_name : "???");
+	send(s, p, ssize, MSG_EOF);
+	free(p);
+
 	exit(0);
 }
 

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




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