diff options
-rw-r--r-- | libexec/identd/Makefile | 5 | ||||
-rw-r--r-- | libexec/identd/identd.8 | 251 | ||||
-rw-r--r-- | libexec/identd/identd.c | 26 | ||||
-rw-r--r-- | libexec/identd/openbsd.c | 146 | ||||
-rw-r--r-- | libexec/identd/parse.c | 18 |
5 files changed, 122 insertions, 324 deletions
diff --git a/libexec/identd/Makefile b/libexec/identd/Makefile index 9893c04d22f..cf86b4dd5a6 100644 --- a/libexec/identd/Makefile +++ b/libexec/identd/Makefile @@ -1,10 +1,9 @@ -# $Id: Makefile,v 1.3 1997/08/01 19:08:39 deraadt Exp $ +# $Id: Makefile,v 1.4 1998/06/10 03:49:38 beck Exp $ PROG= identd SRCS= identd.c openbsd.c parse.c proxy.c version.c MAN= identd.8 -LDADD= -lkvm -DPADD= ${LIBKVM} +CFLAGS+= -Wall -Werror .include <bsd.prog.mk> diff --git a/libexec/identd/identd.8 b/libexec/identd/identd.8 index 95e1425e7d8..95c80a66d29 100644 --- a/libexec/identd/identd.8 +++ b/libexec/identd/identd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: identd.8,v 1.4 1998/02/08 18:52:23 deraadt Exp $ +.\" $OpenBSD: identd.8,v 1.5 1998/06/10 03:49:39 beck Exp $ .\" .\" Copyright (c) 1997, Jason Downs. All rights reserved. .\" @@ -11,7 +11,7 @@ .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: +.\" must display the following acknowledgment: .\" This product includes software developed by Jason Downs for the .\" OpenBSD system. .\" 4. Neither the name(s) of the author(s) nor the name OpenBSD @@ -50,7 +50,6 @@ .Op Fl a Ar address .Op Fl c Ar charset .Op Fl noelVvmNd -.Op Ar kernelfile Op Ar kmemfile .Sh DESCRIPTION .Nm is a server which implements the @@ -66,219 +65,133 @@ operates by looking up specific .Tn TCP/IP connections and returning the user name of the process owning the connection. -.Sh ARGUMENTS -The -.Fl i -flag, which is the default mode, should be used when starting the -daemon from +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl i +Tells +.Nm identd +to run as a process started from .Xr inetd 8 -with the "nowait" option in the +with the "nowait" option in the .Pa /etc/inetd.conf file. Use of this mode will make .Xr inetd 8 start one .Nm -daemon for each connection request. -.Pp -The -.Fl w -flag should be used when starting the daemon from +daemon for each connection request. This is the default mode of operation. +.It Fl w +Tells +.Nm identd +to run as a process started from .Xr inetd 8 -with the "wait" option in the +with the "wait" option in the .Pa /etc/inetd.conf -file. This is the prefered mode of -operation since that will start a copy of +file. This mode of operation will start a copy of .Nm at the first connection request and then .Nm -will handle subsequent requests -without having to do the nlist lookup in the kernel file for -every request as in the -.Fl i -mode above. The -.Nm -daemon will run either forever, until a bug -makes it crash or a timeout, as specified by the -.Fl t -flag, occurs. -.Pp -The -.Fl b -flag can be used to make the daemon run in standalone mode without -the assistance from -.Xr inetd 8 . -This mode is the least prefered mode since -a bug or any other fatal condition in the server will make it terminate -and it will then have to be restarted manually. Other than that is has the -same advantage as the -.Fl w -mode in that it parses the nlist only once. -.Pp -The -.Fl t Ar seconds -option is used to specify the timeout limit. This is the number -of seconds a server started with the -.Fl w -flag will wait for new connections before terminating. The server is -automatically restarted by -.Xr inetd 8 -whenever a new connection is requested -if it has terminated. A suitable value for this is 120 (2 minutes), if -used. It defaults to no timeout (ie, will wait forever, or until a -fatal condition occurs in the server). -.Pp -The -.Fl u Ar uid -option is used to specify a user id number which the -.Nm +will handle subsequent requests. +Previous versions listed this as the preferred mode of +operation due to the initial overhead of parsing the kernel nlist. +This version does not use kmem or nlist parsing, so this reasoning +is no longer valid. +.It Fl b +Specify operation as a stand alone daemon. +.It Fl t Ar seconds +Specifies an idle timeout in seconds where a daemon running in +"wait" mode will timeout and exit. The default is no timeout. +.It Fl u Ar uid +Specify a user id number or user name which the +.Nm identd server should switch to after binding itself to the .Tn TCP/IP -port if using the -.Fl b -mode of operation. -.Pp -The -.Fl g Ar gid -option is used to specify a group id number which the +port if running as a stand alone daemon. +.It Fl g Ar gid +Specify a group id number or group name which the .Nm server should switch to after binding itself to the .Tn TCP/IP -port if using the -.Fl b -mode of operation. -.Pp -The -.Fl p Ar port -option is used to specify an alternative port number to bind to if using -the -.Fl b -mode of operation. It can be specified by name or by number. Defaults to the -.Tn IDENT -port (113). -.Pp -The -.Fl a Ar address -option is used to specify the local address to bind the socket to if using -the -.Fl b -mode of operation. Can only be specified by IP address and not by domain -name. Defaults to the -.Li INADDR_ANY -address which normally means all local addresses. -.Pp -The -.Fl V -flag makes -.Nm -display the version number and the exit. -.Pp -The -.Fl l -flag tells -.Nm -to use the system logging daemon +port if running as a stand alone daemon +.It Fl p Ar port +Specify an alternative port number or service name +on which to listen when running as a stand alone daemon +Default is "auth" (113). +.It Fl a Ar address +Specify a local IP address in dotted quad format +to bind the listen socket to if +running as a standalone daemon. by default the daemon +listens on all local IP addresses. +.It Fl V +Print the version number and the exit. +.It Fl l +Use .Xr syslogd 8 for logging purposes. -.Pp -The -.Fl v -flag causes -.Nm -to log every request made, if the use of -.Xr syslogd 8 -is enabled. -.Pp -The -.Fl o -flag tells -.Nm -not to reveal the operating system type it is run on and to instead +.It Fl v +Log every request to syslog if +Fl l +above is specified. +.It Fl o +Do the operating system type, instead always return .Dq OTHER . -.Pp -The -.Fl e -flag tells -.Nm -to always return +.It Fl e +always return .Dq UNKNOWN-ERROR instead of the .Dq NO-USER or .Dq INVALID-PORT errors. -.Pp -The -.Fl c Ar charset -flags tells -.Nm -to add the optional (according to the -.Tn IDENT -protocol) character set designator to the reply generated. +.It Fl c Ar charset +Specify an optional character set designator to be included in replies. .Ar charset should be a valid character set as described in the .Tn MIME RFC in upper case characters. -.Pp -The -.Fl n -flags tells -.Nm -to always return user numbers instead of user names if you wish to -keep the user names a secret. -.Pp -The -.Fl N -flag makes -.Nm +.It Fl n +always return uid numbers instead of user names +.It Fl N +When replying with a user name or id, first check for a file .Pa .noident -in each homedirectory for a user which the daemon is about to return the user -name for. It that file exists then the daemon will give the error -.Dq HIDDEN-USER -instead of the normal USERID response. -.Pp -.Fl m -flag makes -.Nm -use a mode of operation that will allow multiple requests to be +in the user's home directory. If this file is accessible, return +.Dq HIDDEN-USER +instead of the normal USERID response. +.It Fl m +allow multiple requests to be processed per session. Each request is specified one per line and the responses will be returned one per line. The connection will not -be closed until the connecting part closes it's end of the line. +be closed until the client closes it's end of the connection. PLEASE NOTE THAT THIS MODE VIOLATES THE PROTOCOL SPECIFICATION AS IT CURRENTLY STANDS. -.Pp -The -.Fl d +.ItFl d flag enables some debugging code that normally should NOT be enabled since that breaks the protocol and may reveal information that should not be available to outsiders. .Pp -.Ar kernelfile -defaults to the normally running kernel file. -.Pp -.Ar kmemfile -defaults to the memory space of the normally running kernel. .Sh SEE ALSO .Xr inetd.conf 5 . .Sh NOTES .Nm uses the .Li LOG_DAEMON -syslogd(8) facility to log messages. This is the correct thing to do -since -.Li LOG_AUTH -is supposed to be used by authorization related programs, not authentication -related ones such as -.Nm . +syslogd(8) facility to log messages. +.Pp +Unlike previous versions of +.Nm identd, +this version uses +.Xr sysctl 3 +to obtain information from the kernel instead of parsing kmem. This +version does not require privilege beyond what is needed to bind +the listen port if running as a standalone daemon. .Sh BUGS -The handling of fatal errors could be better. -.Pp -If the -.Fl N -flag is specified and a user's +Since +.Nm identd +should typically not be run as a privileged user or group, .Pa .noident -file is not accessible, then ident information regarding that user will be -returned if requested. +files for use when running with the +.Fl N +flag will need to be world accessible. diff --git a/libexec/identd/identd.c b/libexec/identd/identd.c index 708888db449..95357a06482 100644 --- a/libexec/identd/identd.c +++ b/libexec/identd/identd.c @@ -37,9 +37,6 @@ extern int errno; extern char *version; -char *path_unix = NULL; -char *path_kmem = NULL; - int verbose_flag = 0; int debug_flag = 0; int syslog_flag = 0; @@ -105,7 +102,7 @@ main(argc, argv) struct group *grp; int background_flag = 0; int timeout = 0; - char *portno = "113"; + char *portno = "auth"; char *bind_address = NULL; int set_uid = 0; int set_gid = 0; @@ -145,7 +142,8 @@ main(argc, argv) ERROR1("no such user (%s) for -u option", argv[i] + 2); else { set_uid = pwd->pw_uid; - set_gid = pwd->pw_gid; + if (setgid == 0) + set_gid = pwd->pw_gid; } break; case 'g': @@ -197,24 +195,6 @@ main(argc, argv) } /* - * Path to kernel namelist file specified on command line - */ - if (i < argc) - path_unix = argv[i++]; - - /* - * Path to kernel memory device specified on command line - */ - if (i < argc) - path_kmem = argv[i++]; - - /* - * Open the kernel memory device and read the nlist table - */ - if (k_open() < 0) - ERROR("main: k_open"); - - /* * Do the special handling needed for the "-b" flag */ if (background_flag == 1) { diff --git a/libexec/identd/openbsd.c b/libexec/identd/openbsd.c index 72c3da45dff..ba5d5f04973 100644 --- a/libexec/identd/openbsd.c +++ b/libexec/identd/openbsd.c @@ -3,38 +3,22 @@ * who wants to. * * Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se> + * + * $Id: openbsd.c,v 1.10 1998/06/10 03:49:42 beck Exp $ + * This version elminates the kmem search in favour of a kernel sysctl to + * get the user id associated with a connection - Bob Beck <beck@obtuse.com> */ -#include <sys/types.h> -#include <sys/stat.h> #include <sys/param.h> -#include <sys/ioctl.h> #include <sys/socket.h> #include <sys/socketvar.h> -#include <sys/user.h> -#include <sys/wait.h> -#define _KERNEL -#include <sys/file.h> -#undef _KERNEL #include <sys/sysctl.h> #include <stdio.h> #include <errno.h> -#include <ctype.h> -#include <limits.h> -#include <nlist.h> -#include <pwd.h> -#include <signal.h> -#include <syslog.h> -#include <kvm.h> -#include <fcntl.h> -#include <net/if.h> -#include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> #include <netinet/tcp.h> #include <netinet/ip_var.h> #include <netinet/tcp_timer.h> @@ -45,86 +29,6 @@ #include "identd.h" #include "error.h" -struct nlist nl[] = { -#define N_TCBTABLE 0 - {"_tcbtable"}, - {""} -}; - -static kvm_t *kd; -static struct inpcbtable tcbtable; - -int -k_open() -{ - char errbuf[_POSIX2_LINE_MAX]; - - /* - ** Open the kernel memory device - */ - if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, errbuf)) == - NULL) - ERROR1("main: kvm_open: %s", errbuf); - - /* - ** Extract offsets to the needed variables in the kernel - */ - if (kvm_nlist(kd, nl) < 0) - ERROR("main: kvm_nlist"); - - return 0; -} - -/* - * Get a piece of kernel memory with error handling. - * Returns 1 if call succeeded, else 0 (zero). - */ -static int -getbuf(addr, buf, len, what) - long addr; - char *buf; - int len; - char *what; -{ - if (kvm_read(kd, addr, buf, len) < 0) { - if (syslog_flag) - syslog(LOG_ERR, "getbuf: kvm_read(%08lx, %d) - %s : %m", - addr, len, what); - - return 0; - } - return 1; -} - -/* - * Traverse the inpcb list until a match is found. - * Returns NULL if no match. - */ -static struct socket * -getlist(tcbtablep, ktcbtablep, faddr, fport, laddr, lport) - struct inpcbtable *tcbtablep, *ktcbtablep; - struct in_addr *faddr; - int fport; - struct in_addr *laddr; - int lport; -{ - struct inpcb *kpcbp, pcb; - - if (!tcbtablep) - return (NULL); - - for (kpcbp = tcbtablep->inpt_queue.cqh_first; - kpcbp != (struct inpcb *) ktcbtablep; - kpcbp = pcb.inp_queue.cqe_next) { - if (!getbuf((long) kpcbp, &pcb, sizeof(struct inpcb), "tcb")) - break; - if (pcb.inp_faddr.s_addr == faddr->s_addr && - pcb.inp_laddr.s_addr == laddr->s_addr && - pcb.inp_fport == fport && pcb.inp_lport == lport) - return (pcb.inp_socket); - } - return (NULL); -} /* * Return the user number for the connection owner @@ -137,20 +41,32 @@ k_getuid(faddr, fport, laddr, lport, uid) int lport; int *uid; { - struct socket *sockp, sock; - - if (!getbuf(nl[N_TCBTABLE].n_value, &tcbtable, sizeof(tcbtable), "tcbtable")) - return -1; - - sockp = getlist(&tcbtable, nl[N_TCBTABLE].n_value, faddr, fport, laddr, - lport); - if (!sockp) - return -1; + struct tcp_ident_mapping tir; + struct sockaddr_in *fin, *lin; + int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_IDENT }; + int error = 0; + int i; + + memset (&tir, 0, sizeof (tir)); + tir.faddr.sa_len = sizeof (struct sockaddr); + tir.laddr.sa_len = sizeof (struct sockaddr); + tir.faddr.sa_family = AF_INET; + tir.laddr.sa_family = AF_INET; + fin = (struct sockaddr_in *) &tir.faddr; + lin = (struct sockaddr_in *) &tir.laddr; + + memcpy (&fin->sin_addr, faddr, sizeof (struct in_addr)); + memcpy (&lin->sin_addr, laddr, sizeof (struct in_addr)); + fin->sin_port = fport; + lin->sin_port = lport; + i = sizeof (tir); + error = sysctl (mib, sizeof (mib) / sizeof (int), &tir, &i, NULL, 0); + if (!error && tir.ruid != -1) { + *uid = tir.ruid; + return (0); + } + if (error == -1) + syslog (LOG_DEBUG, "sysctl failed (%m)"); - if (!getbuf(sockp, &sock, sizeof sock, "socket")) - return -1; - if ((sock.so_state & SS_CONNECTOUT) == 0) - return -1; - *uid = sock.so_ruid; - return (0); + return (-1); } diff --git a/libexec/identd/parse.c b/libexec/identd/parse.c index 4deefd4bac8..81e1a031dd0 100644 --- a/libexec/identd/parse.c +++ b/libexec/identd/parse.c @@ -128,7 +128,7 @@ parse(fd, laddr, faddr) char buf[BUFSIZ], *p; struct in_addr laddr2, faddr2; struct passwd *pw; - int try, n; + int n; uid_t uid; if (debug_flag && syslog_flag) @@ -188,18 +188,11 @@ parse(fd, laddr, faddr) * Next - get the specific TCP connection and return the * uid - user number. * - * Try to fetch the information 5 times incase the - * kernel changed beneath us and we missed or took - * a fault. */ - for (try = 0; try < 5; try++) - if (k_getuid(&faddr2, htons(fport), laddr, - htons(lport), &uid) != -1) - break; - - if (try >= 5) { + if (k_getuid(&faddr2, htons(fport), laddr, + htons(lport), &uid) == -1) { if (syslog_flag) - syslog(LOG_DEBUG, "Returned: %d , %d : NO-USER", + syslog(LOG_DEBUG, "Returning: %d , %d : NO-USER", lport, fport); n = snprintf(buf, sizeof(buf), "%d , %d : ERROR : %s\r\n", lport, fport, unknown_flag ? "UNKNOWN-ERROR" : "NO-USER"); @@ -209,9 +202,6 @@ parse(fd, laddr, faddr) } return 0; } - if (try > 0 && syslog_flag) - syslog(LOG_NOTICE, "k_getuid retries: %d", try); - if (debug_flag && syslog_flag) syslog(LOG_DEBUG, " After k_getuid(), before getpwuid()"); |