summaryrefslogtreecommitdiff
path: root/usr/src/lib/libpkg/common/ncgrpw.c
diff options
context:
space:
mode:
authorMoriah Waterland <Moriah.Waterland@Sun.COM>2009-06-03 20:16:25 -0600
committerMoriah Waterland <Moriah.Waterland@Sun.COM>2009-06-03 20:16:25 -0600
commit5c51f1241dbbdf2656d0e10011981411ed0c9673 (patch)
tree0f30a2e38fe4e5d53a5a67264ba548577d82a86f /usr/src/lib/libpkg/common/ncgrpw.c
parent2b79d384d32b4ea1e278466cd9b0f3bb56daae22 (diff)
downloadillumos-joyent-5c51f1241dbbdf2656d0e10011981411ed0c9673.tar.gz
6739234 move SVR4 packaging to ONNV gate
Diffstat (limited to 'usr/src/lib/libpkg/common/ncgrpw.c')
-rw-r--r--usr/src/lib/libpkg/common/ncgrpw.c740
1 files changed, 740 insertions, 0 deletions
diff --git a/usr/src/lib/libpkg/common/ncgrpw.c b/usr/src/lib/libpkg/common/ncgrpw.c
new file mode 100644
index 0000000000..cf3151164e
--- /dev/null
+++ b/usr/src/lib/libpkg/common/ncgrpw.c
@@ -0,0 +1,740 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * This module fetches group and passwd structs for the caller. It
+ * uses a hash table to speed up retrieval of repeated entries. If
+ * the attempts to initialize the hash tables fail, this just
+ * continues the slow way.
+ */
+
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "pkglib.h"
+#include "pkglocale.h"
+#include "nhash.h"
+
+#define HASHSIZE 151
+#define BSZ 4
+
+#define ERR_DUPFAIL "%s: strdup(%s) failed.\n"
+#define ERR_ADDFAIL "%s: add_cache() failed.\n"
+#define ERR_BADMEMB "%s: %s in \"%s\" %s structure is invalid.\n"
+#define ERR_NOGRP "dup_gr_ent(): no group entry provided.\n"
+#define ERR_NOPWD "dup_pw_ent(): no passwd entry provided.\n"
+#define ERR_NOINIT "%s: init_cache() failed.\n"
+#define ERR_MALLOC "%s: malloc(%d) failed for %s.\n"
+
+static Cache *pwnam_cache = (Cache *) NULL;
+static Cache *grnam_cache = (Cache *) NULL;
+static Cache *pwuid_cache = (Cache *) NULL;
+static Cache *grgid_cache = (Cache *) NULL;
+
+static int dup_gr_ent(struct group *grp);
+static int dup_pw_ent(struct passwd *pwp);
+
+/*
+ * These indicate whether the hash table has been initialized for the four
+ * categories.
+ */
+static int is_a_pwnam_cache;
+static int is_a_grnam_cache;
+static int is_a_pwuid_cache;
+static int is_a_grgid_cache;
+
+extern char *get_install_root(void);
+
+/*
+ * If there's a grnam cache, then update it with this new
+ * group, otherwise, skip it.
+ */
+static Item *
+cache_alloc(char *fname, int len, size_t struct_size)
+{
+ Item *itemp;
+
+ /*
+ * Allocate space for the Item pointer, key and data.
+ */
+ if ((itemp = (Item *) malloc(sizeof (*itemp))) ==
+ Null_Item) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_MALLOC), fname,
+ sizeof (*itemp), "itemp");
+ } else if ((itemp->key = (char *)malloc(len)) == NULL) {
+ (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, len,
+ "itemp->key");
+ free(itemp);
+ } else if ((itemp->data = malloc(struct_size)) == NULL) {
+ (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname,
+ struct_size, "itemp->data");
+ free(itemp->key);
+ free(itemp);
+ } else {
+ /* Set length parameters. */
+ itemp->keyl = len;
+ itemp->datal = struct_size;
+
+ return (itemp);
+ }
+
+ return ((Item *) NULL);
+}
+
+/* Get the required group structure based upon the group name. */
+struct group *
+cgrnam(char *nam)
+{
+ struct group *grp;
+ Item *itemp;
+ int len;
+ static int cache_failed;
+
+ /* Attempt to initialize the grname cache. */
+ if (!is_a_grnam_cache && !cache_failed) {
+ if (init_cache(&grnam_cache, HASHSIZE, BSZ,
+ (int (*)())NULL, (int (*)())NULL) == -1) {
+ (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrnam()");
+ grnam_cache = (Cache *) NULL;
+ cache_failed = 1;
+ } else
+ is_a_grnam_cache = 1;
+ }
+
+ len = strlen(nam) + 1;
+
+ /* First look in the cache. Failing that, do it the hard way. */
+ if ((itemp = lookup_cache(grnam_cache, nam, len)) == Null_Item) {
+
+ /* Get the group by name. */
+ if ((grp = clgrnam(nam)) != NULL ||
+ (grp = getgrnam(nam)) != NULL) {
+ /* A group by that name exists on this machine. */
+ if (dup_gr_ent(grp))
+ /*
+ * Effectively no such group since struct
+ * couldn't be duplicated.
+ */
+ grp = (struct group *)NULL;
+ /*
+ * If there's a grnam cache, then update it with this
+ * new group, otherwise, skip it.
+ */
+ else if (is_a_grnam_cache) {
+ if ((itemp = cache_alloc("cgrnam()", len,
+ sizeof (struct group))) != Null_Item) {
+ /*
+ * With that allocated, insert the
+ * group name as key and set the key
+ * length.
+ */
+ (void) memmove(itemp->key, nam, len);
+
+ /*
+ * Insert the data associated with
+ * the key and the data length.
+ */
+ (void) memmove(itemp->data, grp,
+ sizeof (struct group));
+
+ /* Insert the Item into the cache. */
+ if (add_cache(grnam_cache, itemp) == -1)
+ (void) fprintf(stderr,
+ pkg_gt(ERR_ADDFAIL),
+ "cgrnam()");
+ }
+ }
+ }
+ return (grp);
+ } else /* Found it in the cache. */
+ return ((struct group *)itemp->data);
+}
+
+struct passwd *
+cpwnam(char *nam)
+{
+ struct passwd *pwd;
+ Item *itemp;
+ int len;
+ static int cache_failed;
+
+ if (!is_a_pwnam_cache && !cache_failed) {
+ if (init_cache(&pwnam_cache, HASHSIZE, BSZ,
+ (int (*)())NULL, (int (*)())NULL) == -1) {
+ (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cpwnam()");
+ pwnam_cache = (Cache *) NULL;
+ cache_failed = 1;
+ } else
+ is_a_pwnam_cache = 1;
+ }
+
+ len = strlen(nam) + 1;
+
+ /* First look in the cache. Failing that, do it the hard way. */
+ if ((itemp = lookup_cache(pwnam_cache, nam, len)) == Null_Item) {
+
+ /* Get the passwd by name. */
+ if ((pwd = clpwnam(nam)) != NULL ||
+ (pwd = getpwnam(nam)) != NULL) {
+ /* A passwd by that name exists on this machine. */
+ if (dup_pw_ent(pwd))
+ /*
+ * Effectively no such passwd since struct
+ * couldn't be duplicated.
+ */
+ pwd = (struct passwd *)NULL;
+ /*
+ * If there's a pwnam cache, then update it with this
+ * new passwd, otherwise, skip it.
+ */
+ else if (is_a_pwnam_cache) {
+ /*
+ * Allocate space for the Item pointer, key
+ * and data.
+ */
+ if ((itemp = cache_alloc("cpwnam()", len,
+ sizeof (struct passwd))) != Null_Item) {
+ /*
+ * With that allocated, insert the
+ * group name as key and set the key
+ * length.
+ */
+ (void) memmove(itemp->key, nam, len);
+
+ /*
+ * Insert the data associated with
+ * the key and the data length.
+ */
+ (void) memmove(itemp->data, pwd,
+ sizeof (struct passwd));
+
+ if (add_cache(pwnam_cache, itemp) == -1)
+ (void) fprintf(stderr,
+ pkg_gt(ERR_ADDFAIL),
+ "cpwnam()");
+ }
+ }
+ }
+ return (pwd);
+ } else /* Found it in the cache. */
+ return ((struct passwd *)itemp->data);
+}
+
+static int
+uid_hash(void *datap, int datalen, int hsz)
+{
+#ifdef lint
+ int i = datalen;
+ datalen = i;
+#endif /* lint */
+
+ return (*((uid_t *)datap) % hsz);
+}
+
+static int
+uid_comp(void *datap1, void *datap2, int datalen)
+{
+#ifdef lint
+ int i = datalen;
+ datalen = i;
+#endif /* lint */
+
+ return (*((uid_t *)datap1) - *((uid_t *)datap2));
+}
+
+struct group *
+cgrgid(gid_t gid)
+{
+ struct group *grp;
+ Item *itemp;
+ int len;
+ static int cache_failed;
+
+ if (!is_a_grgid_cache && !cache_failed) {
+ if (init_cache(&grgid_cache, HASHSIZE, BSZ,
+ uid_hash, uid_comp) == -1) {
+ (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrgid()");
+ grgid_cache = (Cache *) NULL;
+ cache_failed = 1;
+ } else
+ is_a_grgid_cache = 1;
+ }
+
+ len = sizeof (uid_t);
+
+ /* First look in the cache. Failing that, do it the hard way. */
+ if ((itemp = lookup_cache(grgid_cache, &gid, len)) == Null_Item) {
+ if ((grp = clgrgid(gid)) != NULL ||
+ (grp = getgrgid(gid)) != NULL) {
+ /* A group by that number exists on this machine. */
+ if (dup_gr_ent(grp))
+ /*
+ * Effectively no such group since struct
+ * couldn't be duplicated.
+ */
+ grp = (struct group *)NULL;
+ /*
+ * If there's a grnam cache, then update it with this
+ * new group, otherwise, skip it.
+ */
+ else if (is_a_grgid_cache) {
+ if ((itemp = cache_alloc("cgrgid()", len,
+ sizeof (struct group))) != Null_Item) {
+ /*
+ * With that allocated, insert the
+ * group name as key and set the key
+ * length.
+ */
+ (void) memmove(itemp->key, &gid, len);
+
+ /*
+ * Insert the data associated with
+ * the key and the data length.
+ */
+ (void) memmove(itemp->data, grp,
+ sizeof (struct group));
+
+ if (add_cache(grgid_cache, itemp) == -1)
+ (void) fprintf(stderr,
+ pkg_gt(ERR_ADDFAIL),
+ "cgrgid()");
+ }
+ }
+ }
+ return (grp);
+ } else /* Found it in the cache. */
+ return ((struct group *)itemp->data);
+}
+
+struct passwd *
+cpwuid(uid_t uid)
+{
+ struct passwd *pwd;
+ Item *itemp;
+ int len;
+ static int cache_failed;
+
+ if (!is_a_pwuid_cache && !cache_failed) {
+ if (init_cache(&pwuid_cache, HASHSIZE, BSZ,
+ uid_hash, uid_comp) == -1) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_NOINIT), "cpwuid()");
+ pwuid_cache = (Cache *) NULL;
+ cache_failed = 1;
+ } else
+ is_a_pwuid_cache = 1;
+ }
+
+ len = sizeof (uid_t);
+
+ /* First look in the cache. Failing that, do it the hard way. */
+ if ((itemp = lookup_cache(pwuid_cache, &uid, len)) == Null_Item) {
+
+ /* Get the passwd by number. */
+ if ((pwd = clpwuid(uid)) != NULL ||
+ (pwd = getpwuid(uid)) != NULL) {
+ /* A passwd by that user ID exists on this machine. */
+ if (dup_pw_ent(pwd))
+ /*
+ * Effectively no such passwd since struct
+ * couldn't be duplicated.
+ */
+ pwd = (struct passwd *)NULL;
+ /*
+ * If there's a pwuid cache, then update it with this
+ * new passwd, otherwise, skip it.
+ */
+ else if (is_a_pwuid_cache) {
+ if ((itemp = cache_alloc("cpwuid()", len,
+ sizeof (struct passwd))) != Null_Item) {
+ /*
+ * With that allocated, insert the
+ * group name as key and set the key
+ * length.
+ */
+ (void) memmove(itemp->key, &uid, len);
+
+ /*
+ * Insert the data associated with
+ * the key and the data length.
+ */
+ (void) memmove(itemp->data, pwd,
+ sizeof (struct passwd));
+
+ if (add_cache(pwuid_cache, itemp) == -1)
+ (void) fprintf(stderr,
+ pkg_gt(ERR_ADDFAIL),
+ "cpwuid()");
+ }
+ }
+ }
+ return (pwd);
+ } else /* Found it in the cache. */
+ return ((struct passwd *)itemp->data);
+}
+
+/*
+ * This function duplicates the group structure provided from kernel static
+ * memory. There is a lot of defensive coding here because there have been
+ * problems with the getgr*() functions. They will sometimes provide NULL
+ * values instead of pointers to NULL values. There has been no explanation
+ * for the reason behind this; but, this function takes a NULL to be an
+ * invalid (char *) and returns an error.
+ */
+static int
+dup_gr_ent(struct group *grp)
+{
+ char **tp = NULL;
+ char **memp = NULL;
+ int nent = 0; /* Number of entries in the member list. */
+
+ if (grp) {
+ if (grp->gr_name == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_name",
+ "unknown", "group");
+ return (-1);
+ } else if ((grp->gr_name = strdup(grp->gr_name)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_name");
+ return (-1);
+ }
+ if (grp->gr_passwd == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_passwd",
+ grp->gr_name, "group");
+ return (-1);
+ } else if ((grp->gr_passwd = strdup(grp->gr_passwd)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_passwd");
+ return (-1);
+ }
+ /*
+ * Allocate space for the member list and move the members
+ * into it.
+ */
+ if (grp->gr_mem) {
+ /*
+ * First count the members. The nent variable will be
+ * the number of members + 1 for the terminator.
+ */
+ for (tp = grp->gr_mem; *tp; nent++, tp++);
+
+ /* Now allocate room for the pointers. */
+ memp = malloc(sizeof (char **)* (nent+1));
+
+ if (memp == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_MALLOC), "dup_gr_ent()",
+ (sizeof (char **)* (nent+1)),
+ "memp");
+ return (-1);
+ }
+
+ /*
+ * Now copy over the pointers and entries. It should
+ * be noted that if the structure is messed up here,
+ * the resulting member list will be truncated at the
+ * NULL entry.
+ */
+ for (nent = 0, tp = grp->gr_mem; *tp; tp++) {
+ if ((memp[nent++] = strdup(*tp)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_gr_ent()",
+ "gr_mem");
+ return (-1);
+ }
+ }
+ } else {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_mem",
+ grp->gr_name, "group");
+ return (-1);
+ }
+ } else {
+ (void) fprintf(stderr, pkg_gt(ERR_NOGRP));
+ return (-1);
+ }
+ memp[nent++] = '\0';
+ return (0);
+}
+
+/*
+ * This function duplicates the passwd structure provided from kernel static
+ * memory. As in the above function, since there have been problems with the
+ * getpw*() functions, the structure provided is rigorously scrubbed. This
+ * function takes a NULL to be an invalid (char *) and returns an error if
+ * one is detected.
+ */
+static int
+dup_pw_ent(struct passwd *pwd)
+{
+ if (pwd) {
+ if (pwd->pw_name == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_name",
+ "unknown", "passwd");
+ return (-1);
+ } else if ((pwd->pw_name = strdup(pwd->pw_name)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_name");
+ return (-1);
+ }
+
+ if (pwd->pw_passwd == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_passwd",
+ pwd->pw_name, "passwd");
+ return (-1);
+ } else if ((pwd->pw_passwd = strdup(pwd->pw_passwd)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_passwd");
+ return (-1);
+ }
+
+ if (pwd->pw_age == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_age",
+ pwd->pw_name, "passwd");
+ return (-1);
+ } else if ((pwd->pw_age = strdup(pwd->pw_age)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_age");
+ return (-1);
+ }
+
+ if (pwd->pw_comment == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_comment",
+ pwd->pw_name, "passwd");
+ return (-1);
+ } else if ((pwd->pw_comment = strdup(pwd->pw_comment)) ==
+ NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_comment");
+ return (-1);
+ }
+
+ if (pwd->pw_gecos == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_gecos",
+ pwd->pw_name, "passwd");
+ return (-1);
+ } else if ((pwd->pw_gecos = strdup(pwd->pw_gecos)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_gecos");
+ return (-1);
+ }
+
+ if (pwd->pw_dir == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_dir",
+ pwd->pw_name, "passwd");
+ return (-1);
+ } else if ((pwd->pw_dir = strdup(pwd->pw_dir)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_dir");
+ return (-1);
+ }
+
+ if (pwd->pw_shell == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_shell",
+ pwd->pw_name, "passwd");
+ return (-1);
+ } else if ((pwd->pw_shell = strdup(pwd->pw_shell)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_shell");
+ return (-1);
+ }
+ } else {
+ (void) fprintf(stderr, pkg_gt(ERR_NOPWD));
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Check the client's etc/group file for the group name
+ *
+ * returns a pointer to the group structure if the group is found
+ * returns NULL if not found
+ */
+struct group *
+clgrnam(char *nam)
+{
+ struct group *gr;
+ char *instroot, *buf;
+ FILE *gr_ptr;
+
+ if ((instroot = get_install_root()) != NULL) {
+ if ((buf = (char *)malloc(strlen(instroot) +
+ strlen(GROUP) + 1)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_MALLOC), "clgrnam()",
+ strlen(instroot) + strlen(GROUP), "buf");
+ }
+ (void) sprintf(buf, "%s%s", instroot, GROUP);
+ if ((gr_ptr = fopen(buf, "r")) == NULL) {
+ free(buf);
+ return (NULL);
+ } else {
+ while ((gr = fgetgrent(gr_ptr)) != NULL) {
+ if (strcmp(gr->gr_name, nam) == 0) {
+ break;
+ }
+ }
+ }
+ free(buf);
+ (void) fclose(gr_ptr);
+ return (gr);
+ } else {
+ return (NULL);
+ }
+}
+
+/*
+ * Check the client's etc/passwd file for the user name
+ *
+ * returns a pointer to the passwd structure if the passwd is found
+ * returns NULL if not found
+ */
+struct passwd *
+clpwnam(char *nam)
+{
+ struct passwd *pw;
+ char *instroot, *buf;
+ FILE *pw_ptr;
+
+ if ((instroot = get_install_root()) != NULL) {
+ if ((buf = (char *)malloc(strlen(instroot) +
+ strlen(PASSWD) + 1)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_MALLOC), "clpwnam()",
+ strlen(instroot) + strlen(PASSWD), "buf");
+ }
+ (void) sprintf(buf, "%s%s", instroot, PASSWD);
+ if ((pw_ptr = fopen(buf, "r")) == NULL) {
+ free(buf);
+ return (NULL);
+ } else {
+ while ((pw = fgetpwent(pw_ptr)) != NULL) {
+ if (strcmp(pw->pw_name, nam) == 0) {
+ break;
+ }
+ }
+ }
+ free(buf);
+ (void) fclose(pw_ptr);
+ return (pw);
+ } else {
+ return (NULL);
+ }
+}
+
+/*
+ * Check the client's etc/group file for the group id
+ *
+ * returns a pointer to the group structure if the group id is found
+ * returns NULL if not found
+ */
+struct group *
+clgrgid(gid_t gid)
+{
+ struct group *gr;
+ char *instroot, *buf;
+ FILE *gr_ptr;
+
+ if ((instroot = get_install_root()) != NULL) {
+ if ((buf = (char *)malloc(strlen(instroot) +
+ strlen(GROUP) + 1)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_MALLOC), "clgrgid()",
+ strlen(instroot) + strlen(GROUP), "buf");
+ }
+ (void) sprintf(buf, "%s%s", instroot, GROUP);
+ if ((gr_ptr = fopen(buf, "r")) == NULL) {
+ free(buf);
+ return (NULL);
+ } else {
+ while ((gr = fgetgrent(gr_ptr)) != NULL) {
+ if (gr->gr_gid == gid) {
+ break;
+ }
+ }
+ }
+ free(buf);
+ (void) fclose(gr_ptr);
+ return (gr);
+ } else {
+ return (NULL);
+ }
+}
+
+/*
+ * Check the client's etc/passwd file for the user id
+ *
+ * returns a pointer to the passwd structure if the user id is found
+ * returns NULL if not found
+ */
+struct passwd *
+clpwuid(uid_t uid)
+{
+ struct passwd *pw;
+ char *instroot, *buf;
+ FILE *pw_ptr;
+
+ if ((instroot = get_install_root()) != NULL) {
+ if ((buf = (char *)malloc(strlen(instroot) +
+ strlen(PASSWD) + 1)) == NULL) {
+ (void) fprintf(stderr,
+ pkg_gt(ERR_MALLOC), "clpwuid()",
+ strlen(instroot) + strlen(PASSWD), "buf");
+ }
+ (void) sprintf(buf, "%s%s", instroot, PASSWD);
+ if ((pw_ptr = fopen(buf, "r")) == NULL) {
+ free(buf);
+ return (NULL);
+ } else {
+ while ((pw = fgetpwent(pw_ptr)) != NULL) {
+ if (pw->pw_uid == uid) {
+ break;
+ }
+ }
+ }
+ free(buf);
+ (void) fclose(pw_ptr);
+ return (pw);
+ } else {
+ return (NULL);
+ }
+}