/*
* 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
* 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"
/*
* 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 *
{
/*
* Allocate space for the Item pointer, key and data.
*/
Null_Item) {
sizeof (*itemp), "itemp");
"itemp->key");
struct_size, "itemp->data");
} else {
/* Set length parameters. */
return (itemp);
}
}
/* Get the required group structure based upon the group name. */
struct group *
{
int len;
static int cache_failed;
/* Attempt to initialize the grname cache. */
if (!is_a_grnam_cache && !cache_failed) {
cache_failed = 1;
} else
is_a_grnam_cache = 1;
}
/* First look in the cache. Failing that, do it the hard way. */
/* Get the group by name. */
/* A group by that name exists on this machine. */
if (dup_gr_ent(grp))
/*
* Effectively no such group since struct
* couldn't be duplicated.
*/
/*
* If there's a grnam cache, then update it with this
* new group, otherwise, skip it.
*/
else if (is_a_grnam_cache) {
/*
* With that allocated, insert the
* group name as key and set the key
* length.
*/
/*
* Insert the data associated with
* the key and the data length.
*/
sizeof (struct group));
/* Insert the Item into the cache. */
"cgrnam()");
}
}
}
return (grp);
} else /* Found it in the cache. */
}
struct passwd *
{
int len;
static int cache_failed;
if (!is_a_pwnam_cache && !cache_failed) {
cache_failed = 1;
} else
is_a_pwnam_cache = 1;
}
/* First look in the cache. Failing that, do it the hard way. */
/* Get the passwd by name. */
/* A passwd by that name exists on this machine. */
if (dup_pw_ent(pwd))
/*
* Effectively no such passwd since struct
* couldn't be duplicated.
*/
/*
* 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.
*/
/*
* With that allocated, insert the
* group name as key and set the key
* length.
*/
/*
* Insert the data associated with
* the key and the data length.
*/
sizeof (struct passwd));
"cpwnam()");
}
}
}
return (pwd);
} else /* Found it in the cache. */
}
static int
{
#ifdef lint
int i = datalen;
datalen = i;
#endif /* lint */
}
static int
{
#ifdef lint
int i = datalen;
datalen = i;
#endif /* lint */
}
struct group *
{
int len;
static int cache_failed;
if (!is_a_grgid_cache && !cache_failed) {
cache_failed = 1;
} else
is_a_grgid_cache = 1;
}
/* First look in the cache. Failing that, do it the hard way. */
/* A group by that number exists on this machine. */
if (dup_gr_ent(grp))
/*
* Effectively no such group since struct
* couldn't be duplicated.
*/
/*
* If there's a grnam cache, then update it with this
* new group, otherwise, skip it.
*/
else if (is_a_grgid_cache) {
/*
* With that allocated, insert the
* group name as key and set the key
* length.
*/
/*
* Insert the data associated with
* the key and the data length.
*/
sizeof (struct group));
"cgrgid()");
}
}
}
return (grp);
} else /* Found it in the cache. */
}
struct passwd *
{
int len;
static int cache_failed;
if (!is_a_pwuid_cache && !cache_failed) {
cache_failed = 1;
} else
is_a_pwuid_cache = 1;
}
/* First look in the cache. Failing that, do it the hard way. */
/* Get the passwd by number. */
/* 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.
*/
/*
* If there's a pwuid cache, then update it with this
* new passwd, otherwise, skip it.
*/
else if (is_a_pwuid_cache) {
/*
* With that allocated, insert the
* group name as key and set the key
* length.
*/
/*
* Insert the data associated with
* the key and the data length.
*/
sizeof (struct passwd));
"cpwuid()");
}
}
}
return (pwd);
} else /* Found it in the cache. */
}
/*
* 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
{
if (grp) {
"unknown", "group");
return (-1);
return (-1);
}
return (-1);
return (-1);
}
/*
* Allocate space for the member list and move the members
* into it.
*/
/*
* First count the members. The nent variable will be
* the number of members + 1 for the terminator.
*/
/* Now allocate room for the pointers. */
(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.
*/
"gr_mem");
return (-1);
}
}
} else {
return (-1);
}
} else {
return (-1);
}
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
{
if (pwd) {
"unknown", "passwd");
return (-1);
return (-1);
}
return (-1);
return (-1);
}
return (-1);
return (-1);
}
return (-1);
NULL) {
return (-1);
}
return (-1);
return (-1);
}
return (-1);
return (-1);
}
return (-1);
return (-1);
}
} else {
return (-1);
}
return (0);
}
/*
*
* returns a pointer to the group structure if the group is found
* returns NULL if not found
*/
struct group *
{
}
return (NULL);
} else {
break;
}
}
}
return (gr);
} else {
return (NULL);
}
}
/*
*
* returns a pointer to the passwd structure if the passwd is found
* returns NULL if not found
*/
struct passwd *
{
return (NULL);
}
return (NULL);
} else {
break;
}
}
}
return (pw);
} else {
return (NULL);
}
}
/*
*
* returns a pointer to the group structure if the group id is found
* returns NULL if not found
*/
struct group *
{
return (NULL);
}
return (NULL);
} else {
break;
}
}
}
return (gr);
} else {
return (NULL);
}
}
/*
*
* returns a pointer to the passwd structure if the user id is found
* returns NULL if not found
*/
struct passwd *
{
return (NULL);
}
return (NULL);
} else {
break;
}
}
}
return (pw);
} else {
return (NULL);
}
}