Date: Thu, 3 Dec 2009 15:48:25 +0000 (UTC) From: Ed Schouten <ed@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r200062 - in head: contrib/groff/tmac lib lib/libulog libexec libexec/ulog-helper share/mk Message-ID: <200912031548.nB3FmPp3018525@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ed Date: Thu Dec 3 15:48:24 2009 New Revision: 200062 URL: http://svn.freebsd.org/changeset/base/200062 Log: Add a new library: libulog. One of the things I really want to do, is to get rid of the limitations of our current utmp(5) mechanism: - It only allows 8 byte TTY device names. - The hostname only allows 16 bytes of storage. I'm not a big fan of <utmpx.h>, but I think we should at least try to add parts of it. Unfortunately we cannot implement <utmpx.h>, because we miss various fields, such as ut_id, ut_pid, etc. The API provided by libulog shares some similarities with <utmpx.h>, so it shouldn't be too hard to port these applications eventually. In most simple cases, it should just be a matter of removing the ulog_ prefix everywhere. As a bonus, it also implements a function called ulog_login_pseudo(), which allows unprivileged applications to write log entries, provided they have a valid file descriptor to a pseudo-terminal master device. libulog will allow a smoother transition to a new file format by adding a library interface to deal with utmp/wtmp/lastlog files. I initially thought about adding the functionality to libutil, but because I'm not planning on keeping this library around forever, we'd better keep it separated. Next items on the todo list: 1. Port applications in the base system (and ports) to libulog, instead of letting them use <utmp.h>. 2. Remove <utmp.h>, implement <utmpx.h> and reimplement this library on top. 3. Port as many applications as possible back to <utmpx.h>. Added: head/lib/libulog/ head/lib/libulog/Makefile (contents, props changed) head/lib/libulog/Symbol.map (contents, props changed) head/lib/libulog/ulog.h (contents, props changed) head/lib/libulog/ulog_getutxent.3 (contents, props changed) head/lib/libulog/ulog_getutxent.c (contents, props changed) head/lib/libulog/ulog_internal.h (contents, props changed) head/lib/libulog/ulog_login.3 (contents, props changed) head/lib/libulog/ulog_login.c (contents, props changed) head/lib/libulog/ulog_login_pseudo.c (contents, props changed) head/libexec/ulog-helper/ head/libexec/ulog-helper/Makefile (contents, props changed) head/libexec/ulog-helper/ulog-helper.c (contents, props changed) Modified: head/contrib/groff/tmac/doc-syms head/lib/Makefile head/libexec/Makefile head/share/mk/bsd.libnames.mk Modified: head/contrib/groff/tmac/doc-syms ============================================================================== --- head/contrib/groff/tmac/doc-syms Thu Dec 3 15:14:30 2009 (r200061) +++ head/contrib/groff/tmac/doc-syms Thu Dec 3 15:48:24 2009 (r200062) @@ -777,6 +777,7 @@ .ds doc-str-Lb-librt \*[Px] \*[doc-str-Lb]Real-time Library (librt, \-lrt) .ds doc-str-Lb-libtermcap Termcap Access Library (libtermcap, \-ltermcap) .ds doc-str-Lb-libusbhid USB Human Interface Devices Library (libusbhid, \-lusbhid) +.ds doc-str-Lb-libulog User Login Record Library (libulog, \-lulog) .ds doc-str-Lb-libutil System Utilities Library (libutil, \-lutil) .ds doc-str-Lb-libx86_64 x86_64 Architecture Library (libx86_64, \-lx86_64) .ds doc-str-Lb-libz Compression Library (libz, \-lz) Modified: head/lib/Makefile ============================================================================== --- head/lib/Makefile Thu Dec 3 15:14:30 2009 (r200061) +++ head/lib/Makefile Thu Dec 3 15:48:24 2009 (r200062) @@ -40,8 +40,8 @@ SUBDIR= ${_csu} libc libbsm libauditd li ${_libpmc} libproc librt ${_libsdp} ${_libsm} ${_libsmb} \ ${_libsmdb} \ ${_libsmutil} libstand ${_libtelnet} ${_libthr} libthread_db libufs \ - libugidfw ${_libusbhid} ${_libusb} ${_libvgl} libwrap liby libz \ - ${_bind} + libugidfw libulog ${_libusbhid} ${_libusb} ${_libvgl} libwrap \ + liby libz ${_bind} .if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf) _csu=csu/${MACHINE_ARCH}-elf Added: head/lib/libulog/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/Makefile Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,21 @@ +# $FreeBSD$ + +LIB= ulog +SHLIB_MAJOR= 0 +INCS= ulog.h +SRCS= ulog.h ulog_getutxent.c ulog_internal.h \ + ulog_login.c ulog_login_pseudo.c + +MAN= ulog_getutxent.3 ulog_login.3 +MLINKS+=ulog_getutxent.3 ulog_endutxent.3 \ + ulog_getutxent.3 ulog_setutxent.3 \ + ulog_login.3 ulog_login_pseudo.3 \ + ulog_login.3 ulog_logout.3 \ + ulog_login.3 ulog_logout_pseudo.3 + +WARNS?= 6 + +VERSION_DEF= ${.CURDIR}/../libc/Versions.def +SYMBOL_MAPS= ${.CURDIR}/Symbol.map + +.include <bsd.lib.mk> Added: head/lib/libulog/Symbol.map ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/Symbol.map Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,13 @@ +/* + * $FreeBSD$ + */ + +FBSD_1.2 { + ulog_endutxent; + ulog_getutxent; + ulog_login; + ulog_login_pseudo; + ulog_logout; + ulog_logout_pseudo; + ulog_setutxent; +}; Added: head/lib/libulog/ulog.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog.h Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _ULOG_H_ +#define _ULOG_H_ + +#include <sys/cdefs.h> +#include <sys/_timeval.h> + +/* + * libulog. + * + * This library is provided as a migratory tool towards <utmpx.h>. We + * cannot yet implement <utmpx.h>, because our on-disk file format lacks + * various fields. <utmpx.h> also has some shortcomings. Ideally we + * want to allow logging of user login records generated by unprivileged + * processes as well, provided that they hold a file descriptor to a + * pseudo-terminal master device. + * + * Unlike struct utmpx, the buffers containing the strings are not + * stored inside struct ulog_utmpx itself. Processes should never + * handcraft these structures anyway. + * + * This library (or at least parts of it) will hopefully deprecate over + * time, when we provide the <utmpx.h> API. + */ + +#define _UTX_USERDISPSIZE 16 +#define _UTX_LINEDISPSIZE 8 +#define _UTX_HOSTDISPSIZE 16 + +struct ulog_utmpx { + char *ut_user; +#if 0 + char *ut_id; +#endif + char *ut_line; + char *ut_host; +#if 0 + pid_t ut_pid; + short ut_type; +#endif + struct timeval ut_tv; +}; + +__BEGIN_DECLS +void ulog_endutxent(void); +struct ulog_utmpx *ulog_getutxent(void); +#if 0 +struct ulog_utmpx *ulog_getutxid(const struct ulog_utmpx *id); +struct ulog_utmpx *ulog_getutxline(const struct ulog_utmpx *line); +struct ulog_utmpx *ulog_pututxline(const struct ulog_utmpx *utmpx); +#endif +void ulog_setutxent(void); + +void ulog_login(const char *, const char *, const char *); +void ulog_login_pseudo(int, const char *); +void ulog_logout(const char *); +void ulog_logout_pseudo(int); +__END_DECLS + +#endif /* !_ULOG_H_ */ Added: head/lib/libulog/ulog_getutxent.3 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog_getutxent.3 Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,98 @@ +.\" Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 2, 2009 +.Os +.Dt ULOG_GETUTXENT 3 +.Sh NAME +.Nm ulog_getutxent , +.Nm ulog_setutxent , +.Nm ulog_endutxent +.Nd read user login records +.Sh LIBRARY +.Lb libulog +.Sh SYNOPSIS +.In ulog.h +.Ft struct ulog_utmpx * +.Fn ulog_getutxent "void" +.Ft void +.Fn ulog_setutxent "void" +.Ft void +.Fn ulog_endutxent "void" +.Sh DESCRIPTION +The +.Fn ulog_getutxent +function returns a pointer to an object, with the following structure, +containing stored information of an active user login session. +.Bd -literal +struct ulog_utmpx { + char *ut_user; /* Username. */ + char *ut_line; /* TTY device. */ + char *ut_host; /* Remote hostname. */ + struct timeval ut_tv; /* Timestamp. */ +}; +.Ed +.Pp +The fields are as follows: +.Bl -tag -width ut_user +.It Fa ut_user +The username of the logged in user. +.It Fa ut_line +The pathname of the TTY device, without the leading +.Pa /dev/ +directory. +.It Fa ut_host +An optional hostname of a remote system, if the login session is +provided through a networked login service. +.It Fa ut_tv +Timestamp indicating when the entry was last modified. +.El +.Pp +The +.Fn ulog_getutxent +function reads the next entry from the utmp file, opening the file if +necessary. +The +.Fn ulog_setutxent +opens the file, closing it first if already opened. +The +.Fn ulog_endutxent +function closes any open files. +.Pp +The +.Fn ulog_getutxent +function reads from the beginning of the file until and EOF is +encountered. +.Sh RETURN VALUES +The +.Fn ulog_getutxent +function returns a null pointer on EOF or error. +.Sh SEE ALSO +.Xr ulog_login 3 , +.Xr utmp 5 +.Sh HISTORY +These functions appeared in +.Fx 9.0 . Added: head/lib/libulog/ulog_getutxent.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog_getutxent.c Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <timeconv.h> + +#include "ulog_internal.h" + +static FILE *ufile; + +void +ulog_endutxent(void) +{ + if (ufile != NULL) + fclose(ufile); + ufile = NULL; +} + +struct ulog_utmpx * +ulog_getutxent(void) +{ + struct futmp ut; + static struct ulog_utmpx utx; + + /* Open the utmp file if not already done so. */ + if (ufile == NULL) + ulog_setutxent(); + if (ufile == NULL) + return (NULL); + + if (fread(&ut, sizeof ut, 1, ufile) != 1) + return (NULL); +#define COPY_STRING(field) do { \ + free(utx.ut_ ## field); \ + utx.ut_ ## field = strndup(ut.ut_ ## field, \ + sizeof ut.ut_ ## field); \ + if (utx.ut_ ## field == NULL) \ + utx.ut_ ## field = __DECONST(char *, ""); \ +} while (0) + COPY_STRING(user); + COPY_STRING(line); + COPY_STRING(host); + utx.ut_tv.tv_sec = _time32_to_time(ut.ut_time); + utx.ut_tv.tv_usec = 0; + + return (&utx); +} + +void +ulog_setutxent(void) +{ + + if (ufile != NULL) + fclose(ufile); + ufile = fopen(_PATH_UTMP, "r"); +} Added: head/lib/libulog/ulog_internal.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog_internal.h Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _ULOG_INTERNAL_H_ +#define _ULOG_INTERNAL_H_ + +#include <stdint.h> + +#include "ulog.h" + +/* + * On-disk format. + */ + +#define _PATH_UTMP "/var/run/utmp" +#define _PATH_WTMP "/var/log/wtmp" + +struct futmp { + char ut_line[8]; + char ut_user[16]; + char ut_host[16]; + int32_t ut_time; +}; + +#define _PATH_LASTLOG "/var/log/lastlog" + +struct flastlog { + int32_t ll_time; + char ll_line[8]; + char ll_host[16]; +}; + +#endif /* !_ULOG_INTERNAL_H_ */ Added: head/lib/libulog/ulog_login.3 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog_login.3 Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,102 @@ +.\" Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 2, 2009 +.Os +.Dt ULOG_LOGIN 3 +.Sh NAME +.Nm ulog_login , +.Nm ulog_login_pseudo , +.Nm ulog_logout , +.Nm ulog_logout_pseudo +.Nd manage user login records +.Sh LIBRARY +.Lb libulog +.Sh SYNOPSIS +.In ulog.h +.Ft void +.Fn ulog_login "const char *line" "const char *user" "const char *host" +.Ft void +.Fn ulog_login_pseudo "int fd" "const char *host" +.Ft void +.Fn ulog_logout "const char *line" +.Ft void +.Fn ulog_logout_pseudo "int fd" +.Sh DESCRIPTION +The +.Fn ulog_login +and +.Fn ulog_login_pseudo +functions register a login session on a TTY. +The +.Fn ulog_login +function adds an entry for TTY +.Fa line +and username +.Fa user . +The +.Fn ulog_login_pseudo +function uses file descriptor to a pseudo-terminal master device +.Fa fd +to determine the TTY name, while using the username belonging to the +real user ID of the calling process. +The optional +.Fa host +argument denotes a remote hostname, in case the login session is +provided by a network service. +.Pp +The +.Fn ulog_logout +and +.Fn ulog_logout_pseudo +functions mark the previously registered login session as being +terminated. +.Pp +Because the +.Fa line +and +.Fa user +arguments of +.Fn ulog_login +and +.Fn ulog_logout +cannot be trusted, these functions require administrative privileges. +The +.Fn ulog_login_pseudo +and +.Fn ulog_logout_pseudo +functions spawn a privileged process to perform the actual logging. +.Sh SEE ALSO +.Xr getuid 3 , +.Xr login 3 , +.Xr logout 3 , +.Xr posix_openpt 2 , +.Xr ptsname 3 , +.Xr ulog_getutxent 3 , +.Xr utmp 5 +.Sh HISTORY +These functions appeared in +.Fx 9.0 . Added: head/lib/libulog/ulog_login.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog_login.c Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <fcntl.h> +#include <inttypes.h> +#include <paths.h> +#include <pwd.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <timeconv.h> +#include <ttyent.h> + +#include "ulog_internal.h" + +void +ulog_login(const char *line, const char *user, const char *host) +{ + struct futmp fu; + struct flastlog fl; + int fd; + + /* Remove /dev/ component. */ + if (strncmp(line, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) + line += sizeof _PATH_DEV - 1; + + /* Prepare log entries. */ + memset(&fu, 0, sizeof fu); + strlcpy(fu.ut_line, line, sizeof fu.ut_line); + strlcpy(fu.ut_user, user, sizeof fu.ut_user); + if (host != NULL) + strlcpy(fu.ut_host, host, sizeof fu.ut_host); + fu.ut_time = _time_to_time32(time(NULL)); + + fl.ll_time = fu.ut_time; + memcpy(fl.ll_line, fu.ut_line, sizeof fl.ll_line); + memcpy(fl.ll_host, fu.ut_host, sizeof fl.ll_host); + + /* Update utmp entry. */ + if ((fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) { + struct ttyent *ty; + int idx; + + setttyent(); + for (idx = 1; (ty = getttyent()) != NULL; ++idx) { + if (strcmp(ty->ty_name, line) != 0) + continue; + lseek(fd, (off_t)(idx * sizeof fu), L_SET); + write(fd, &fu, sizeof fu); + break; + } + endttyent(); + close(fd); + } + + /* Add wtmp entry. */ + if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) { + write(fd, &fu, sizeof fu); + close(fd); + } + + /* Update lastlog entry. */ + if ((fd = open(_PATH_LASTLOG, O_WRONLY, 0)) >= 0) { + struct passwd *pw; + + pw = getpwnam(user); + if (pw != NULL) { + lseek(fd, (off_t)(pw->pw_uid * sizeof fl), L_SET); + write(fd, &fl, sizeof fl); + } + close(fd); + } +} + +void +ulog_logout(const char *line) +{ + struct futmp ut; + int fd, found; + + /* Remove /dev/ component. */ + if (strncmp(line, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) + line += sizeof _PATH_DEV - 1; + + /* Mark entry in utmp as logged out. */ + if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0) + return; + found = 0; + while (read(fd, &ut, sizeof ut) == sizeof ut) { + if (ut.ut_user[0] == '\0' || + strncmp(ut.ut_line, line, sizeof ut.ut_line) != 0) + continue; + memset(ut.ut_user, 0, sizeof ut.ut_user); + memset(ut.ut_host, 0, sizeof ut.ut_host); + ut.ut_time = _time_to_time32(time(NULL)); + lseek(fd, -(off_t)sizeof ut, L_INCR); + write(fd, &ut, sizeof ut); + found = 1; + } + close(fd); + if (!found) + return; + + /* utmp entry found. Also add logout entry to wtmp. */ + if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) { + write(fd, &ut, sizeof ut); + close(fd); + } +} Added: head/lib/libulog/ulog_login_pseudo.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libulog/ulog_login_pseudo.c Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/wait.h> + +#include <errno.h> +#include <signal.h> +#include <stdlib.h> +#include <sysexits.h> +#include <unistd.h> + +#include "ulog_internal.h" + +#define _PATH_ULOG_HELPER "/usr/libexec/ulog-helper" + +/* + * Registering login sessions. + */ + +static void +ulog_exec_helper(int fd, char const * const argv[]) +{ + sigset_t oblock, nblock; + pid_t pid, wpid; + int status; + + /* Block SIGCHLD. */ + sigemptyset(&nblock); + sigaddset(&nblock, SIGCHLD); + sigprocmask(SIG_BLOCK, &nblock, &oblock); + + switch (pid = fork()) { + case -1: + break; + case 0: + /* Execute helper program. */ + if (dup2(fd, STDIN_FILENO) == -1) + exit(EX_UNAVAILABLE); + sigprocmask(SIG_SETMASK, &oblock, NULL); + execv(_PATH_ULOG_HELPER, __DECONST(char * const *, argv)); + exit(EX_UNAVAILABLE); + default: + /* Wait for helper to finish. */ + do { + wpid = waitpid(pid, &status, 0); + } while (wpid == -1 && errno == EINTR); + break; + } + + sigprocmask(SIG_SETMASK, &oblock, NULL); +} + +void +ulog_login_pseudo(int fd, const char *host) +{ + char const * const args[4] = { "ulog-helper", "login", host, NULL }; + + ulog_exec_helper(fd, args); +} + +void +ulog_logout_pseudo(int fd) +{ + char const * const args[3] = { "ulog-helper", "logout", NULL }; + + ulog_exec_helper(fd, args); +} Modified: head/libexec/Makefile ============================================================================== --- head/libexec/Makefile Thu Dec 3 15:14:30 2009 (r200061) +++ head/libexec/Makefile Thu Dec 3 15:48:24 2009 (r200062) @@ -29,6 +29,7 @@ SUBDIR= ${_atrun} \ ${_telnetd} \ tftpd \ ${_tftp-proxy} \ + ulog-helper \ ${_ypxfr} .if ${MK_AT} != "no" Added: head/libexec/ulog-helper/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/libexec/ulog-helper/Makefile Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,13 @@ +# $FreeBSD$ + +PROG= ulog-helper +BINOWN= root +BINMODE=4555 +NO_MAN= + +DPADD= ${LIBULOG} +LDADD= -lulog + +WARNS?= 6 + +.include <bsd.prog.mk> Added: head/libexec/ulog-helper/ulog-helper.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/libexec/ulog-helper/ulog-helper.c Thu Dec 3 15:48:24 2009 (r200062) @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <pwd.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <ulog.h> + +/* + * This setuid helper utility writes user login records to disk. + * Unprivileged processes are not capable of writing records to utmp, + * wtmp and lastlog, but we do want to allow this for pseudo-terminals. + * Because a file descriptor to a pseudo-terminal master device can only + * be obtained by processes using the pseudo-terminal, we expect such a + * descriptor on stdin. + * + * It uses the real user ID of the calling process to determine the + * username. It does allow users to log arbitrary hostnames. + */ + +int +main(int argc, char *argv[]) +{ + const char *line; + + /* Device line name. */ + if ((line = ptsname(STDIN_FILENO)) == NULL) + return (EX_USAGE); + + if ((argc == 2 || argc == 3) && strcmp(argv[1], "login") == 0) { + struct passwd *pwd; + const char *host = NULL; + + /* Username. */ + pwd = getpwuid(getuid()); + if (pwd == NULL) + return (EX_OSERR); + + /* Hostname. */ + if (argc == 3) + host = argv[2]; + + if (ulog_login(line, pwd->pw_name, host) != 0) + return (EX_OSFILE); + return (EX_OK); + } else if (argc == 2 && strcmp(argv[1], "logout") == 0) { + if (ulog_logout(line) != 0) + return (EX_OSFILE); + return (EX_OK); + } + + return (EX_USAGE); +} Modified: head/share/mk/bsd.libnames.mk ============================================================================== --- head/share/mk/bsd.libnames.mk Thu Dec 3 15:14:30 2009 (r200061) +++ head/share/mk/bsd.libnames.mk Thu Dec 3 15:48:24 2009 (r200062) @@ -151,6 +151,7 @@ LIBUGIDFW?= ${DESTDIR}${LIBDIR}/libugidf LIBUMEM?= ${DESTDIR}${LIBDIR}/libumem.a LIBUSBHID?= ${DESTDIR}${LIBDIR}/libusbhid.a LIBUSB20?= ${DESTDIR}${LIBDIR}/libusb20.a +LIBULOG?= ${DESTDIR}${LIBDIR}/libulog.a LIBUTIL?= ${DESTDIR}${LIBDIR}/libutil.a LIBUUTIL?= ${DESTDIR}${LIBDIR}/libuutil.a LIBVGL?= ${DESTDIR}${LIBDIR}/libvgl.a
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912031548.nB3FmPp3018525>