summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/praudit/format.c158
1 files changed, 124 insertions, 34 deletions
diff --git a/usr/src/cmd/praudit/format.c b/usr/src/cmd/praudit/format.c
index 3acd370513..c2ea6c0ef6 100644
--- a/usr/src/cmd/praudit/format.c
+++ b/usr/src/cmd/praudit/format.c
@@ -64,6 +64,116 @@ static int do_mtime64(pr_context_t *context, int status, int flag,
uint64_t scale);
/*
+ * for uid/gid caches
+ */
+static uid_t lastuid = (uid_t)-1;
+static gid_t lastgid = (gid_t)-1;
+static char *lastuname = NULL;
+static char *lastgname = NULL;
+static char *getname(uid_t);
+static char *getgroup(gid_t);
+static struct cachenode *findincache(struct cachenode **, long);
+#include <utmpx.h>
+
+struct utmpx utmp;
+
+#define NMAX (sizeof (utmp.ut_name))
+#define SCPYN(a, b) (void) strncpy(a, b, NMAX)
+
+struct cachenode { /* this struct must be zeroed before using */
+ struct cachenode *lesschild; /* subtree whose entries < val */
+ struct cachenode *grtrchild; /* subtree whose entries > val */
+ long val; /* the uid or gid of this entry */
+ int initted; /* name has been filled in */
+ char name[NMAX+1]; /* the string that val maps to */
+};
+static struct cachenode *names, *groups;
+
+static struct cachenode *
+findincache(struct cachenode **head, long val)
+{
+ struct cachenode **parent = head;
+ struct cachenode *c = *parent;
+
+ while (c != NULL) {
+ if (val == c->val) {
+ /* found it */
+ return (c);
+ } else if (val < c->val) {
+ parent = &c->lesschild;
+ c = c->lesschild;
+ } else {
+ parent = &c->grtrchild;
+ c = c->grtrchild;
+ }
+ }
+
+ /* not in the cache, make a new entry for it */
+ c = calloc(1, sizeof (struct cachenode));
+ if (c == NULL) {
+ perror("praudit");
+ exit(2);
+ }
+ *parent = c;
+ c->val = val;
+ return (c);
+}
+
+/*
+ * get name from cache, or passwd file for a given uid;
+ * lastuid is set to uid.
+ */
+static char *
+getname(uid_t uid)
+{
+ struct passwd *pwent;
+ struct cachenode *c;
+
+ if ((uid == lastuid) && lastuname)
+ return (lastuname);
+
+ c = findincache(&names, uid);
+ if (c->initted == 0) {
+ if ((pwent = getpwuid(uid)) != NULL) {
+ SCPYN(&c->name[0], pwent->pw_name);
+ } else {
+ (void) sprintf(&c->name[0], "%u", (int)uid);
+ }
+ c->initted = 1;
+ }
+ lastuid = uid;
+ lastuname = &c->name[0];
+ return (lastuname);
+}
+
+/*
+ * get name from cache, or group file for a given gid;
+ * lastgid is set to gid.
+ */
+static char *
+getgroup(gid_t gid)
+{
+ struct group *grent;
+ struct cachenode *c;
+
+ if ((gid == lastgid) && lastgname)
+ return (lastgname);
+
+ c = findincache(&groups, gid);
+ if (c->initted == 0) {
+ if ((grent = getgrgid(gid)) != NULL) {
+ SCPYN(&c->name[0], grent->gr_name);
+ } else {
+ (void) sprintf(&c->name[0], "%u", (int)gid);
+ }
+ c->initted = 1;
+ }
+ lastgid = gid;
+ lastgname = &c->name[0];
+ return (lastgname);
+}
+
+/*
* ------------------------------------------------------
* field widths for arbitrary data token type
* ------------------------------------------------------
@@ -1862,9 +1972,6 @@ done:
if (wstat == 0)
wstat = do_newline(context, flag);
- if (wstat == 0 && context->data_mode == FILEMODE)
- (void) fflush(stdout);
-
return ((rstat != 0 || wstat != 0) ? -1 : 0);
}
@@ -2014,28 +2121,21 @@ static int
pa_print_uid(pr_context_t *context, uid_t uid, int status, int flag)
{
int returnstat;
- struct passwd *pw;
uval_t uval;
if (status < 0)
return (status);
- if (!(context->format & PRF_RAWM)) {
- /* get password file entry */
- if ((pw = getpwuid(uid)) == NULL) {
- returnstat = 1;
- } else {
- /* print in ASCII form */
- uval.uvaltype = PRA_STRING;
- uval.string_val = pw->pw_name;
- returnstat = pa_print(context, &uval, flag);
- }
- }
- /* print in integer form */
- if ((context->format & PRF_RAWM) || (returnstat == 1)) {
+ if (context->format & PRF_RAWM) {
+ /* print in integer form */
uval.uvaltype = PRA_INT32;
uval.int32_val = uid;
returnstat = pa_print(context, &uval, flag);
+ } else {
+ /* print in ASCII form */
+ uval.uvaltype = PRA_STRING;
+ uval.string_val = getname(uid);
+ returnstat = pa_print(context, &uval, flag);
}
return (returnstat);
}
@@ -2070,28 +2170,21 @@ static int
pa_print_gid(pr_context_t *context, gid_t gid, int status, int flag)
{
int returnstat;
- struct group *gr;
uval_t uval;
if (status < 0)
return (status);
- if (!(context->format & PRF_RAWM)) {
- /* get group file entry */
- if ((gr = getgrgid(gid)) == NULL) {
- returnstat = 1;
- } else {
- /* print in ASCII form */
- uval.uvaltype = PRA_STRING;
- uval.string_val = gr->gr_name;
- returnstat = pa_print(context, &uval, flag);
- }
- }
- /* print in integer form */
- if ((context->format & PRF_RAWM) || (returnstat == 1)) {
+ if (context->format & PRF_RAWM) {
+ /* print in integer form */
uval.uvaltype = PRA_INT32;
uval.int32_val = gid;
returnstat = pa_print(context, &uval, flag);
+ } else {
+ /* print in ASCII form */
+ uval.uvaltype = PRA_STRING;
+ uval.string_val = getgroup(gid);
+ returnstat = pa_print(context, &uval, flag);
}
return (returnstat);
}
@@ -2835,9 +2928,6 @@ pa_print(pr_context_t *context, uval_t *uval, int flag)
returnstat = pr_putchar(context, '\n');
}
}
- if ((returnstat == 0) && (context->data_mode == FILEMODE))
- (void) fflush(stdout);
-
return (returnstat);
}