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>.
This commit is contained in:
ed 2009-12-03 15:48:24 +00:00
parent b6cdcc9940
commit 879c7d2730
15 changed files with 790 additions and 2 deletions

View File

@ -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)

View File

@ -40,8 +40,8 @@ SUBDIR= ${_csu} libc libbsm libauditd libcom_err libcrypt libelf libkvm msun \
${_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

21
lib/libulog/Makefile Normal file
View File

@ -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>

13
lib/libulog/Symbol.map Normal file
View File

@ -0,0 +1,13 @@
/*
* $FreeBSD$
*/
FBSD_1.2 {
ulog_endutxent;
ulog_getutxent;
ulog_login;
ulog_login_pseudo;
ulog_logout;
ulog_logout_pseudo;
ulog_setutxent;
};

87
lib/libulog/ulog.h Normal file
View File

@ -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_ */

View File

@ -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 .

View File

@ -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");
}

View File

@ -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_ */

102
lib/libulog/ulog_login.3 Normal file
View File

@ -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 .

135
lib/libulog/ulog_login.c Normal file
View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -29,6 +29,7 @@ SUBDIR= ${_atrun} \
${_telnetd} \
tftpd \
${_tftp-proxy} \
ulog-helper \
${_ypxfr}
.if ${MK_AT} != "no"

View File

@ -0,0 +1,13 @@
# $FreeBSD$
PROG= ulog-helper
BINOWN= root
BINMODE=4555
NO_MAN=
DPADD= ${LIBULOG}
LDADD= -lulog
WARNS?= 6
.include <bsd.prog.mk>

View File

@ -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);
}

View File

@ -151,6 +151,7 @@ LIBUGIDFW?= ${DESTDIR}${LIBDIR}/libugidfw.a
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