diff options
| -rw-r--r-- | usr/src/cmd/praudit/format.c | 158 |
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); } |
