diff options
author | ed <ed@FreeBSD.org> | 2009-12-03 15:48:24 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-12-03 15:48:24 +0000 |
commit | 879c7d27302e0fb0654529de4b88f210ee11b022 (patch) | |
tree | c0f0fe174257910e3a7d7dcda57958d8ade8bfa9 /lib | |
parent | b6cdcc994062fb93affd9d473219a5f06d4029ff (diff) | |
download | FreeBSD-src-879c7d27302e0fb0654529de4b88f210ee11b022.zip FreeBSD-src-879c7d27302e0fb0654529de4b88f210ee11b022.tar.gz |
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>.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 4 | ||||
-rw-r--r-- | lib/libulog/Makefile | 21 | ||||
-rw-r--r-- | lib/libulog/Symbol.map | 13 | ||||
-rw-r--r-- | lib/libulog/ulog.h | 87 | ||||
-rw-r--r-- | lib/libulog/ulog_getutxent.3 | 98 | ||||
-rw-r--r-- | lib/libulog/ulog_getutxent.c | 84 | ||||
-rw-r--r-- | lib/libulog/ulog_internal.h | 58 | ||||
-rw-r--r-- | lib/libulog/ulog_login.3 | 102 | ||||
-rw-r--r-- | lib/libulog/ulog_login.c | 135 | ||||
-rw-r--r-- | lib/libulog/ulog_login_pseudo.c | 93 |
10 files changed, 693 insertions, 2 deletions
diff --git a/lib/Makefile b/lib/Makefile index 00b1c60..a6b0039 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -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 diff --git a/lib/libulog/Makefile b/lib/libulog/Makefile new file mode 100644 index 0000000..f8cd91b --- /dev/null +++ b/lib/libulog/Makefile @@ -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> diff --git a/lib/libulog/Symbol.map b/lib/libulog/Symbol.map new file mode 100644 index 0000000..cd6dd00 --- /dev/null +++ b/lib/libulog/Symbol.map @@ -0,0 +1,13 @@ +/* + * $FreeBSD$ + */ + +FBSD_1.2 { + ulog_endutxent; + ulog_getutxent; + ulog_login; + ulog_login_pseudo; + ulog_logout; + ulog_logout_pseudo; + ulog_setutxent; +}; diff --git a/lib/libulog/ulog.h b/lib/libulog/ulog.h new file mode 100644 index 0000000..2a613dd --- /dev/null +++ b/lib/libulog/ulog.h @@ -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_ */ diff --git a/lib/libulog/ulog_getutxent.3 b/lib/libulog/ulog_getutxent.3 new file mode 100644 index 0000000..da71596 --- /dev/null +++ b/lib/libulog/ulog_getutxent.3 @@ -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 . diff --git a/lib/libulog/ulog_getutxent.c b/lib/libulog/ulog_getutxent.c new file mode 100644 index 0000000..f13001c --- /dev/null +++ b/lib/libulog/ulog_getutxent.c @@ -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"); +} diff --git a/lib/libulog/ulog_internal.h b/lib/libulog/ulog_internal.h new file mode 100644 index 0000000..20c5330 --- /dev/null +++ b/lib/libulog/ulog_internal.h @@ -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_ */ diff --git a/lib/libulog/ulog_login.3 b/lib/libulog/ulog_login.3 new file mode 100644 index 0000000..ca896fe --- /dev/null +++ b/lib/libulog/ulog_login.3 @@ -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 . diff --git a/lib/libulog/ulog_login.c b/lib/libulog/ulog_login.c new file mode 100644 index 0000000..22de619 --- /dev/null +++ b/lib/libulog/ulog_login.c @@ -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); + } +} diff --git a/lib/libulog/ulog_login_pseudo.c b/lib/libulog/ulog_login_pseudo.c new file mode 100644 index 0000000..841a2db --- /dev/null +++ b/lib/libulog/ulog_login_pseudo.c @@ -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); +} |