Skip site navigation (1)Skip section navigation (2)
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>