Several refinements to libulog's API.

- Only set the fields in the ulog_utmpx structure that are valid for the
  command in question. This means that strings like "shutdown" or "~"
  are not visible to the user anymore.
- Rename UTXF_* to UTXI_*, indicating the indexation, instead of using
  the `antique' filename. If we ever get rid of utmp, it makes little
  sense calling it by its old name.
This commit is contained in:
Ed Schouten 2009-12-26 22:36:05 +00:00
parent 76e42b3a0c
commit 444999a314
6 changed files with 53 additions and 38 deletions

View File

@ -91,7 +91,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags,
} }
if ((flags & PAM_SILENT) == 0) { if ((flags & PAM_SILENT) == 0) {
if (ulog_setutxfile(UTXF_LASTLOG, NULL) != 0) { if (ulog_setutxfile(UTXI_USER, NULL) != 0) {
PAM_LOG("Failed to open lastlog database"); PAM_LOG("Failed to open lastlog database");
} else { } else {
utx = ulog_getutxuser(user); utx = ulog_getutxuser(user);

View File

@ -85,9 +85,9 @@ void ulog_setutxent(void);
/* Extensions. */ /* Extensions. */
struct ulog_utmpx *ulog_getutxuser(const char *); struct ulog_utmpx *ulog_getutxuser(const char *);
int ulog_setutxfile(int, const char *); int ulog_setutxfile(int, const char *);
#define UTXF_UTMP 0 #define UTXI_TTY 0
#define UTXF_WTMP 1 #define UTXI_TIME 1
#define UTXF_LASTLOG 2 #define UTXI_USER 2
/* Login/logout utility functions. */ /* Login/logout utility functions. */
void ulog_login(const char *, const char *, const char *); void ulog_login(const char *, const char *, const char *);

View File

@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$");
#include "ulog_internal.h" #include "ulog_internal.h"
static FILE *ufile; static FILE *ufile;
static int ufiletype = -1; static int ufileindex = -1;
void void
ulog_endutxent(void) ulog_endutxent(void)
@ -61,11 +61,8 @@ ulog_futmp_to_utmpx(const struct futmp *ut, struct ulog_utmpx *utx)
strncpy(utx->ut_ ## field, ut->ut_ ## field, \ strncpy(utx->ut_ ## field, ut->ut_ ## field, \
MIN(sizeof utx->ut_ ## field - 1, sizeof ut->ut_ ## field));\ MIN(sizeof utx->ut_ ## field - 1, sizeof ut->ut_ ## field));\
} while (0) } while (0)
COPY_STRING(user); #define MATCH(field, value) (strncmp(ut->ut_ ## field, (value), \
COPY_STRING(line); sizeof(ut->ut_ ## field)) == 0)
COPY_STRING(host);
#undef COPY_STRING
#define MATCH(field, value) (strcmp(utx->ut_ ## field, (value)) == 0)
if (MATCH(user, "reboot") && MATCH(line, "~")) if (MATCH(user, "reboot") && MATCH(line, "~"))
utx->ut_type = BOOT_TIME; utx->ut_type = BOOT_TIME;
else if (MATCH(user, "date") && MATCH(line, "|")) else if (MATCH(user, "date") && MATCH(line, "|"))
@ -74,12 +71,23 @@ ulog_futmp_to_utmpx(const struct futmp *ut, struct ulog_utmpx *utx)
utx->ut_type = NEW_TIME; utx->ut_type = NEW_TIME;
else if (MATCH(user, "shutdown") && MATCH(line, "~")) else if (MATCH(user, "shutdown") && MATCH(line, "~"))
utx->ut_type = SHUTDOWN_TIME; utx->ut_type = SHUTDOWN_TIME;
else if (MATCH(user, "") && MATCH(host, "")) else if (MATCH(user, "") && MATCH(host, "")) {
utx->ut_type = DEAD_PROCESS; utx->ut_type = DEAD_PROCESS;
else if (!MATCH(user, "") && !MATCH(line, "") && ut->ut_time != 0) /* XXX: ut_id and ut_pid missing. ut_line not needed. */
COPY_STRING(line);
} else if (!MATCH(user, "") && !MATCH(line, "") && ut->ut_time != 0) {
utx->ut_type = USER_PROCESS; utx->ut_type = USER_PROCESS;
else /* XXX: ut_id and ut_pid missing. */
COPY_STRING(user);
COPY_STRING(line);
COPY_STRING(host);
} else {
/* Only set ut_type for EMPTY. */
utx->ut_type = EMPTY; utx->ut_type = EMPTY;
return;
}
#undef COPY_STRING
#undef MATCH
utx->ut_tv.tv_sec = _time32_to_time(ut->ut_time); utx->ut_tv.tv_sec = _time32_to_time(ut->ut_time);
utx->ut_tv.tv_usec = 0; utx->ut_tv.tv_usec = 0;
} }
@ -93,13 +101,20 @@ ulog_flastlog_to_utmpx(const struct flastlog *ll, struct ulog_utmpx *utx)
strncpy(utx->ut_ ## field, ll->ll_ ## field, \ strncpy(utx->ut_ ## field, ll->ll_ ## field, \
MIN(sizeof utx->ut_ ## field - 1, sizeof ll->ll_ ## field));\ MIN(sizeof utx->ut_ ## field - 1, sizeof ll->ll_ ## field));\
} while (0) } while (0)
COPY_STRING(line); #define MATCH(field, value) (strncmp(ll->ll_ ## field, (value), \
COPY_STRING(host); sizeof(ll->ll_ ## field)) == 0)
#undef COPY_STRING if (!MATCH(line, "") && ll->ll_time != 0) {
if (!MATCH(line, "") && ll->ll_time != 0)
utx->ut_type = USER_PROCESS; utx->ut_type = USER_PROCESS;
else /* XXX: ut_id and ut_pid missing. */
COPY_STRING(line);
COPY_STRING(host);
} else {
/* Only set ut_type for EMPTY. */
utx->ut_type = EMPTY; utx->ut_type = EMPTY;
return;
}
#undef COPY_STRING
#undef MATCH
utx->ut_tv.tv_sec = _time32_to_time(ll->ll_time); utx->ut_tv.tv_sec = _time32_to_time(ll->ll_time);
utx->ut_tv.tv_usec = 0; utx->ut_tv.tv_usec = 0;
} }
@ -112,7 +127,7 @@ static inline off_t
ulog_tell(void) ulog_tell(void)
{ {
if (ufiletype == UTXF_LASTLOG) if (ufileindex == UTXI_USER)
return (ftello(ufile) / sizeof(struct flastlog)); return (ftello(ufile) / sizeof(struct flastlog));
else else
return (ftello(ufile) / sizeof(struct futmp)); return (ftello(ufile) / sizeof(struct futmp));
@ -132,7 +147,7 @@ ulog_read(off_t off, int whence, int resolve_user)
if (whence == SEEK_SET && ulog_tell() > off) if (whence == SEEK_SET && ulog_tell() > off)
return (NULL); return (NULL);
if (ufiletype == UTXF_LASTLOG) { if (ufileindex == UTXI_USER) {
struct flastlog ll; struct flastlog ll;
struct passwd *pw = NULL; struct passwd *pw = NULL;
uid_t uid; uid_t uid;
@ -192,7 +207,7 @@ ulog_getutxline(const struct ulog_utmpx *line)
if (ufile == NULL) if (ufile == NULL)
return (NULL); return (NULL);
if (ufiletype == UTXF_UTMP) { if (ufileindex == UTXI_TTY) {
unsigned int slot; unsigned int slot;
slot = ulog_ttyslot(line->ut_line); slot = ulog_ttyslot(line->ut_line);
@ -228,7 +243,7 @@ ulog_getutxuser(const char *user)
{ {
struct ulog_utmpx *utx; struct ulog_utmpx *utx;
if (ufiletype == UTXF_LASTLOG) { if (ufileindex == UTXI_USER) {
struct passwd *pw; struct passwd *pw;
pw = getpwnam(user); pw = getpwnam(user);
@ -258,20 +273,20 @@ ulog_getutxuser(const char *user)
*/ */
int int
ulog_setutxfile(int type, const char *file) ulog_setutxfile(int uidx, const char *file)
{ {
/* Supply default files. */ /* Supply default files. */
switch (type) { switch (uidx) {
case UTXF_UTMP: case UTXI_TTY:
if (file == NULL) if (file == NULL)
file = _PATH_UTMP; file = _PATH_UTMP;
break; break;
case UTXF_WTMP: case UTXI_TIME:
if (file == NULL) if (file == NULL)
file = _PATH_WTMP; file = _PATH_WTMP;
break; break;
case UTXF_LASTLOG: case UTXI_USER:
if (file == NULL) if (file == NULL)
file = _PATH_LASTLOG; file = _PATH_LASTLOG;
break; break;
@ -282,7 +297,7 @@ ulog_setutxfile(int type, const char *file)
if (ufile != NULL) if (ufile != NULL)
fclose(ufile); fclose(ufile);
ufile = fopen(file, "r"); ufile = fopen(file, "r");
ufiletype = type; ufileindex = uidx;
if (ufile == NULL) if (ufile == NULL)
return (-1); return (-1);
return (0); return (0);
@ -298,5 +313,5 @@ void
ulog_setutxent(void) ulog_setutxent(void)
{ {
ulog_setutxfile(UTXF_UTMP, NULL); ulog_setutxfile(UTXI_TTY, NULL);
} }

View File

@ -36,7 +36,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.In ulog.h .In ulog.h
.Ft int .Ft int
.Fn ulog_setutxfile "int type" "const char *file" .Fn ulog_setutxfile "int index" "const char *file"
.Ft struct ulog_utmpx * .Ft struct ulog_utmpx *
.Fn ulog_getutxuser "const char *user" .Fn ulog_getutxuser "const char *user"
.Sh DESCRIPTION .Sh DESCRIPTION
@ -54,17 +54,17 @@ function is similar to
.Fn ulog_setutxent , .Fn ulog_setutxent ,
but is capable of returning an error code and also gives access to other but is capable of returning an error code and also gives access to other
login record files by using one of the following values for login record files by using one of the following values for
.Fa type : .Fa index :
.Bl -tag -width UTXF_LASTLOG .Bl -tag -width UTXI_TIME
.It Dv UTXF_UTMP .It Dv UTXI_TTY
Open the default Open the default
.Nm utmp .Nm utmp
file, which is indexed by TTY device. file, which is indexed by TTY device.
.It Dv UTXF_WTMP .It Dv UTXI_TIME
Open the Open the
.Nm wtmp .Nm wtmp
file, which is indexed by time. file, which is indexed by time.
.It Dv UTXF_LASTLOG .It Dv UTXI_USER
Open the Open the
.Nm lastlog .Nm lastlog
file, which is indexed by user ID. file, which is indexed by user ID.
@ -73,7 +73,7 @@ file, which is indexed by user ID.
The The
.Fa file .Fa file
argument determines the file to be opened. argument determines the file to be opened.
If left null, implementation-defined default file is opened. If left null, an implementation-defined default file is opened.
.Pp .Pp
The The
.Fn ulog_getutxuser .Fn ulog_getutxuser

View File

@ -109,7 +109,7 @@ main(int argc, char *argv[])
usage(); usage();
if (*argv != NULL) { if (*argv != NULL) {
if (ulog_setutxfile(UTXF_UTMP, *argv) != 0) if (ulog_setutxfile(UTXI_TTY, *argv) != 0)
err(1, "%s", *argv); err(1, "%s", *argv);
} }

View File

@ -60,7 +60,7 @@ main(argc, argv)
usage(); usage();
} }
if (ulog_setutxfile(UTXF_LASTLOG, NULL) != 0) if (ulog_setutxfile(UTXI_USER, NULL) != 0)
errx(1, "failed to open lastlog database"); errx(1, "failed to open lastlog database");
setpassent(1); /* Keep passwd file pointers open */ setpassent(1); /* Keep passwd file pointers open */