mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 11:43:34 +08:00
Update.
1999-06-11 Thorsten Kukuk <kukuk@suse.de> * nscd/nscd.c: Add -S options for separate caching of data for every user. So one user couldn't see the data another user has gotten with his credentials. * nscd/nscd.h: Add new prototypes. * nscd/cache.c: Compare owner of cache entry if in secure mode. * nscd/connections.c: Check on shutdown if caller really was root. In secure mode get uid of caller. * nscd/grpcache.c: Add support for new secure group mode. * nscd/hstcache.c: Add support for new secure hosts mode. * nscd/pwdcache.c: Add support for new secure passwd mode.
This commit is contained in:
parent
9be8ed9e94
commit
a1c542bfc5
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
1999-06-11 Thorsten Kukuk <kukuk@suse.de>
|
||||
|
||||
* nscd/nscd.c: Add -S options for separate caching of data for
|
||||
every user. So one user couldn't see the data another user
|
||||
has gotten with his credentials.
|
||||
* nscd/nscd.h: Add new prototypes.
|
||||
* nscd/cache.c: Compare owner of cache entry if in secure mode.
|
||||
* nscd/connections.c: Check on shutdown if caller really was root.
|
||||
In secure mode get uid of caller.
|
||||
* nscd/grpcache.c: Add support for new secure group mode.
|
||||
* nscd/hstcache.c: Add support for new secure hosts mode.
|
||||
* nscd/pwdcache.c: Add support for new secure passwd mode.
|
||||
|
||||
1999-06-11 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* resolv/nss_dns/dns-host.c (getanswer_r): Correctly track usage
|
||||
|
10
nscd/cache.c
10
nscd/cache.c
@ -38,7 +38,8 @@
|
||||
|
||||
This function must be called with the read-lock held. */
|
||||
struct hashentry *
|
||||
cache_search (int type, void *key, size_t len, struct database *table)
|
||||
cache_search (int type, void *key, size_t len, struct database *table,
|
||||
uid_t owner)
|
||||
{
|
||||
unsigned long int hash = __nis_hash (key, len) % table->module;
|
||||
struct hashentry *work;
|
||||
@ -47,8 +48,8 @@ cache_search (int type, void *key, size_t len, struct database *table)
|
||||
|
||||
while (work != NULL)
|
||||
{
|
||||
if (type == work->type
|
||||
&& len == work->len && memcmp (key, work->key, len) == 0)
|
||||
if (type == work->type && len == work->len
|
||||
&& memcmp (key, work->key, len) == 0 && work->owner == owner)
|
||||
{
|
||||
/* We found the entry. Increment the appropriate counter. */
|
||||
if (work->data == (void *) -1)
|
||||
@ -76,7 +77,7 @@ cache_search (int type, void *key, size_t len, struct database *table)
|
||||
the readlock reduces the chance of conflicts. */
|
||||
void
|
||||
cache_add (int type, void *key, size_t len, const void *packet, size_t total,
|
||||
void *data, int last, time_t t, struct database *table)
|
||||
void *data, int last, time_t t, struct database *table, uid_t owner)
|
||||
{
|
||||
unsigned long int hash = __nis_hash (key, len) % table->module;
|
||||
struct hashentry *newp;
|
||||
@ -88,6 +89,7 @@ cache_add (int type, void *key, size_t len, const void *packet, size_t total,
|
||||
newp->type = type;
|
||||
newp->len = len;
|
||||
newp->key = key;
|
||||
newp->owner = owner;
|
||||
newp->data = data;
|
||||
newp->timeout = t;
|
||||
newp->packet = packet;
|
||||
|
@ -195,7 +195,7 @@ close_sockets (void)
|
||||
|
||||
/* Handle new request. */
|
||||
static void
|
||||
handle_request (int fd, request_header *req, void *key)
|
||||
handle_request (int fd, request_header *req, void *key, uid_t uid)
|
||||
{
|
||||
if (debug_level > 0)
|
||||
dbg_log (_("handle_request: request received (Version = %d)"),
|
||||
@ -251,7 +251,7 @@ cannot handle old request version %d; current version is %d"),
|
||||
|
||||
/* See whether we can handle it from the cache. */
|
||||
cached = (struct hashentry *) cache_search (req->type, key, req->key_len,
|
||||
db);
|
||||
db, uid);
|
||||
if (cached != NULL)
|
||||
{
|
||||
/* Hurray it's in the cache. */
|
||||
@ -279,35 +279,35 @@ cannot handle old request version %d; current version is %d"),
|
||||
switch (req->type)
|
||||
{
|
||||
case GETPWBYNAME:
|
||||
addpwbyname (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addpwbyname (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETPWBYUID:
|
||||
addpwbyuid (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addpwbyuid (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETGRBYNAME:
|
||||
addgrbyname (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addgrbyname (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETGRBYGID:
|
||||
addgrbygid (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addgrbygid (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETHOSTBYNAME:
|
||||
addhstbyname (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addhstbyname (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETHOSTBYNAMEv6:
|
||||
addhstbynamev6 (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addhstbynamev6 (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETHOSTBYADDR:
|
||||
addhstbyaddr (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addhstbyaddr (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETHOSTBYADDRv6:
|
||||
addhstbyaddrv6 (&dbs[serv2db[req->type]], fd, req, key);
|
||||
addhstbyaddrv6 (&dbs[serv2db[req->type]], fd, req, key, uid);
|
||||
break;
|
||||
|
||||
case GETSTAT:
|
||||
@ -315,7 +315,24 @@ cannot handle old request version %d; current version is %d"),
|
||||
break;
|
||||
|
||||
case SHUTDOWN:
|
||||
termination_handler (0);
|
||||
/* Accept shutdown only from root */
|
||||
if (secure_in_use && uid == 0)
|
||||
termination_handler (0);
|
||||
else
|
||||
{
|
||||
struct ucred caller;
|
||||
int optlen = sizeof (caller);
|
||||
|
||||
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
dbg_log (_("error getting callers id: %s"),
|
||||
strerror_r (errno, buf, sizeof (buf)));
|
||||
}
|
||||
else if (caller.uid == 0)
|
||||
termination_handler (0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -362,6 +379,7 @@ nscd_run (void *p)
|
||||
int fd = accept (conn.fd, NULL, NULL);
|
||||
request_header req;
|
||||
char buf[256];
|
||||
uid_t uid = 0;
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
@ -380,6 +398,25 @@ nscd_run (void *p)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (secure_in_use)
|
||||
{
|
||||
struct ucred caller;
|
||||
int optlen = sizeof (caller);
|
||||
|
||||
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED,
|
||||
&caller, &optlen) < 0)
|
||||
{
|
||||
dbg_log (_("error getting callers id: %s"),
|
||||
strerror_r (errno, buf, sizeof (buf)));
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (req.type < GETPWBYNAME || req.type >= LASTREQ
|
||||
|| secure[serv2db[req.type]])
|
||||
uid = caller.uid;
|
||||
}
|
||||
|
||||
/* It should not be possible to crash the nscd with a silly
|
||||
request (i.e., a terribly large key. We limit the size
|
||||
to 1kb. */
|
||||
@ -404,7 +441,7 @@ nscd_run (void *p)
|
||||
}
|
||||
|
||||
/* Phew, we got all the data, now process it. */
|
||||
handle_request (fd, &req, keybuf);
|
||||
handle_request (fd, &req, keybuf, uid);
|
||||
|
||||
/* We are done. */
|
||||
close (fd);
|
||||
|
@ -77,7 +77,7 @@ struct groupdata
|
||||
|
||||
static void
|
||||
cache_addgr (struct database *db, int fd, request_header *req, void *key,
|
||||
struct group *grp)
|
||||
struct group *grp, uid_t owner)
|
||||
{
|
||||
ssize_t total;
|
||||
ssize_t written;
|
||||
@ -105,7 +105,7 @@ cache_addgr (struct database *db, int fd, request_header *req, void *key,
|
||||
pthread_rwlock_rdlock (&db->lock);
|
||||
|
||||
cache_add (req->type, copy, req->key_len, &iov_notfound,
|
||||
sizeof (notfound), (void *) -1, 0, t, db);
|
||||
sizeof (notfound), (void *) -1, 0, t, db, owner);
|
||||
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
}
|
||||
@ -177,9 +177,9 @@ cache_addgr (struct database *db, int fd, request_header *req, void *key,
|
||||
|
||||
/* We have to add the value for both, byname and byuid. */
|
||||
cache_add (GETGRBYNAME, gr_name, gr_name_len, data,
|
||||
total, data, 0, t, db);
|
||||
total, data, 0, t, db, owner);
|
||||
|
||||
cache_add (GETGRBYGID, cp, n, data, total, data, 1, t, db);
|
||||
cache_add (GETGRBYGID, cp, n, data, total, data, 1, t, db, owner);
|
||||
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
}
|
||||
@ -194,7 +194,8 @@ cache_addgr (struct database *db, int fd, request_header *req, void *key,
|
||||
|
||||
|
||||
void
|
||||
addgrbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
addgrbyname (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -204,10 +205,17 @@ addgrbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
char *buffer = alloca (buflen);
|
||||
struct group resultbuf;
|
||||
struct group *grp;
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
dbg_log (_("Haven't found \"%s\" in group cache!"), key);
|
||||
|
||||
if (secure[grpdb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (uid);
|
||||
}
|
||||
|
||||
while (getgrnam_r (key, &resultbuf, buffer, buflen, &grp) != 0
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
@ -216,12 +224,16 @@ addgrbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addgr (db, fd, req, key, grp);
|
||||
if (secure[grpdb])
|
||||
seteuid (oldeuid);
|
||||
|
||||
cache_addgr (db, fd, req, key, grp, uid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addgrbygid (struct database *db, int fd, request_header *req, void *key)
|
||||
addgrbygid (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -232,10 +244,17 @@ addgrbygid (struct database *db, int fd, request_header *req, void *key)
|
||||
struct group resultbuf;
|
||||
struct group *grp;
|
||||
gid_t gid = atol (key);
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
dbg_log (_("Haven't found \"%d\" in group cache!"), gid);
|
||||
|
||||
if (secure[grpdb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (uid);
|
||||
}
|
||||
|
||||
while (getgrgid_r (gid, &resultbuf, buffer, buflen, &grp) != 0
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
@ -244,5 +263,8 @@ addgrbygid (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addgr (db, fd, req, key, grp);
|
||||
if (secure[grpdb])
|
||||
seteuid (oldeuid);
|
||||
|
||||
cache_addgr (db, fd, req, key, grp, uid);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ struct hostdata
|
||||
|
||||
static void
|
||||
cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
struct hostent *hst)
|
||||
struct hostent *hst, uid_t owner)
|
||||
{
|
||||
ssize_t total;
|
||||
ssize_t written;
|
||||
@ -116,7 +116,7 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
pthread_rwlock_rdlock (&db->lock);
|
||||
|
||||
cache_add (req->type, copy, req->key_len, &iov_notfound,
|
||||
sizeof (notfound), (void *) -1, 0, t, db);
|
||||
sizeof (notfound), (void *) -1, 0, t, db, owner);
|
||||
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
}
|
||||
@ -227,10 +227,10 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
{
|
||||
if (addr_list_type == GETHOSTBYADDR)
|
||||
cache_add (GETHOSTBYNAME, aliases, h_aliases_len[cnt], data, total,
|
||||
data, 0, t, db);
|
||||
data, 0, t, db, owner);
|
||||
|
||||
cache_add (GETHOSTBYNAMEv6, aliases, h_aliases_len[cnt], data, total,
|
||||
data, 0, t, db);
|
||||
data, 0, t, db, owner);
|
||||
|
||||
aliases += h_aliases_len[cnt];
|
||||
}
|
||||
@ -239,7 +239,7 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
for (cnt = 0; cnt < h_addr_list_cnt; ++cnt)
|
||||
{
|
||||
cache_add (addr_list_type, addresses, hst->h_length, data, total,
|
||||
data, 0, t, db);
|
||||
data, 0, t, db, owner);
|
||||
addresses += hst->h_length;
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
for (cnt = 0; cnt < h_addr_list_cnt; ++cnt)
|
||||
{
|
||||
cache_add (GETHOSTBYADDRv6, addresses, IN6ADDRSZ, data, total,
|
||||
data, 0, t, db);
|
||||
data, 0, t, db, owner);
|
||||
addresses += IN6ADDRSZ;
|
||||
}
|
||||
|
||||
@ -257,17 +257,17 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
{
|
||||
if (addr_list_type == GETHOSTBYADDR)
|
||||
cache_add (GETHOSTBYNAME, key_copy, req->key_len, data, total,
|
||||
data, 0, t, db);
|
||||
data, 0, t, db, owner);
|
||||
cache_add (GETHOSTBYNAMEv6, key_copy, req->key_len, data,
|
||||
total, data, 0, t, db);
|
||||
total, data, 0, t, db, owner);
|
||||
}
|
||||
|
||||
/* And finally the name. We mark this as the last entry. */
|
||||
if (addr_list_type == GETHOSTBYADDR)
|
||||
cache_add (GETHOSTBYNAME, data->strdata, h_name_len, data, total, data,
|
||||
0, t, db);
|
||||
0, t, db, owner);
|
||||
cache_add (GETHOSTBYNAMEv6, data->strdata, h_name_len, data,
|
||||
total, data, 1, t, db);
|
||||
total, data, 1, t, db, owner);
|
||||
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
}
|
||||
@ -282,7 +282,8 @@ cache_addhst (struct database *db, int fd, request_header *req, void *key,
|
||||
|
||||
|
||||
void
|
||||
addhstbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
addhstbyname (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -292,10 +293,17 @@ addhstbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
char *buffer = alloca (buflen);
|
||||
struct hostent resultbuf;
|
||||
struct hostent *hst;
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
dbg_log (_("Haven't found \"%s\" in hosts cache!"), key);
|
||||
|
||||
if (secure[hstdb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (uid);
|
||||
}
|
||||
|
||||
while (gethostbyname2_r (key, AF_INET, &resultbuf, buffer, buflen, &hst,
|
||||
&h_errno) != 0
|
||||
&& h_errno == NETDB_INTERNAL
|
||||
@ -306,12 +314,16 @@ addhstbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addhst (db, fd, req, key, hst);
|
||||
if (secure[hstdb])
|
||||
seteuid (uid);
|
||||
|
||||
cache_addhst (db, fd, req, key, hst, uid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addhstbyaddr (struct database *db, int fd, request_header *req, void *key)
|
||||
addhstbyaddr (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -321,6 +333,7 @@ addhstbyaddr (struct database *db, int fd, request_header *req, void *key)
|
||||
char *buffer = alloca (buflen);
|
||||
struct hostent resultbuf;
|
||||
struct hostent *hst;
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
{
|
||||
@ -329,6 +342,12 @@ addhstbyaddr (struct database *db, int fd, request_header *req, void *key)
|
||||
inet_ntop (AF_INET, key, buf, sizeof (buf)));
|
||||
}
|
||||
|
||||
if (secure[hstdb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (uid);
|
||||
}
|
||||
|
||||
while (gethostbyaddr_r (key, INADDRSZ, AF_INET, &resultbuf, buffer, buflen,
|
||||
&hst, &h_errno) != 0
|
||||
&& h_errno == NETDB_INTERNAL
|
||||
@ -339,12 +358,16 @@ addhstbyaddr (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addhst (db, fd, req, key, hst);
|
||||
if (secure[hstdb])
|
||||
seteuid (oldeuid);
|
||||
|
||||
cache_addhst (db, fd, req, key, hst, uid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addhstbynamev6 (struct database *db, int fd, request_header *req, void *key)
|
||||
addhstbynamev6 (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -354,6 +377,7 @@ addhstbynamev6 (struct database *db, int fd, request_header *req, void *key)
|
||||
char *buffer = alloca (buflen);
|
||||
struct hostent resultbuf;
|
||||
struct hostent *hst;
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
{
|
||||
@ -363,6 +387,12 @@ addhstbynamev6 (struct database *db, int fd, request_header *req, void *key)
|
||||
inet_ntop (AF_INET6, key, buf, sizeof (buf)));
|
||||
}
|
||||
|
||||
if (secure[hstdb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (uid);
|
||||
}
|
||||
|
||||
while (gethostbyname2_r (key, AF_INET6, &resultbuf, buffer, buflen, &hst,
|
||||
&h_errno) != 0
|
||||
&& h_errno == NETDB_INTERNAL
|
||||
@ -373,12 +403,16 @@ addhstbynamev6 (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addhst (db, fd, req, key, hst);
|
||||
if (secure[hstdb])
|
||||
seteuid (oldeuid);
|
||||
|
||||
cache_addhst (db, fd, req, key, hst, uid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addhstbyaddrv6 (struct database *db, int fd, request_header *req, void *key)
|
||||
addhstbyaddrv6 (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -388,6 +422,7 @@ addhstbyaddrv6 (struct database *db, int fd, request_header *req, void *key)
|
||||
char *buffer = alloca (buflen);
|
||||
struct hostent resultbuf;
|
||||
struct hostent *hst;
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
{
|
||||
@ -396,6 +431,12 @@ addhstbyaddrv6 (struct database *db, int fd, request_header *req, void *key)
|
||||
inet_ntop (AF_INET6, key, buf, sizeof (buf)));
|
||||
}
|
||||
|
||||
if (secure[hstdb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (uid);
|
||||
}
|
||||
|
||||
while (gethostbyaddr_r (key, IN6ADDRSZ, AF_INET6, &resultbuf, buffer, buflen,
|
||||
&hst, &h_errno) != 0
|
||||
&& h_errno == NETDB_INTERNAL
|
||||
@ -406,5 +447,8 @@ addhstbyaddrv6 (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addhst (db, fd, req, key, hst);
|
||||
if (secure[hstdb])
|
||||
seteuid (oldeuid);
|
||||
|
||||
cache_addhst (db, fd, req, key, hst, uid);
|
||||
}
|
||||
|
21
nscd/nscd.c
21
nscd/nscd.c
@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 1998, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -58,10 +58,13 @@ typedef struct
|
||||
|
||||
thread_info_t thread_info;
|
||||
|
||||
int do_shutdown = 0;
|
||||
int disabled_passwd = 0;
|
||||
int disabled_group = 0;
|
||||
int do_shutdown;
|
||||
int disabled_passwd;
|
||||
int disabled_group;
|
||||
int go_background = 1;
|
||||
|
||||
int secure[lastdb];
|
||||
int secure_in_use;
|
||||
static const char *conffile = _PATH_NSCDCONF;
|
||||
|
||||
static int check_pid (const char *file);
|
||||
@ -81,6 +84,7 @@ static const struct argp_option options[] =
|
||||
{ "nthreads", 't', N_("NUMBER"), 0, N_("Start NUMBER threads") },
|
||||
{ "shutdown", 'K', NULL, 0, N_("Shut the server down") },
|
||||
{ "statistic", 'g', NULL, 0, N_("Print current configuration statistic") },
|
||||
{ "secure", 'S', N_("TABLE,yes"), 0, N_("Use separate cache for each user")},
|
||||
{ NULL, 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
@ -208,6 +212,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
nthreads = atol (arg);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
if (strcmp (arg, "passwd,yes") == 0)
|
||||
secure_in_use = secure[pwddb] = 1;
|
||||
else if (strcmp (arg, "group,yes") == 0)
|
||||
secure_in_use = secure[grpdb] = 1;
|
||||
else if (strcmp (arg, "hosts,yes") == 0)
|
||||
secure_in_use = secure[hstdb] = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
29
nscd/nscd.h
29
nscd/nscd.h
@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
/* Copyright (c) 1998, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -46,6 +46,7 @@ struct hashentry
|
||||
request_type type; /* Which type of dataset. */
|
||||
size_t len; /* Length of key. */
|
||||
void *key; /* Pointer to key. */
|
||||
uid_t owner; /* If secure table, this is the owner. */
|
||||
struct hashentry *next; /* Next entry in this hash bucket list. */
|
||||
time_t timeout; /* Time when this entry becomes invalid. */
|
||||
ssize_t total; /* Number of bytes in PACKET. */
|
||||
@ -91,6 +92,9 @@ extern const struct iovec hst_iov_disabled;
|
||||
/* Number of threads to run. */
|
||||
extern int nthreads;
|
||||
|
||||
/* Tables for which we cache data with uid */
|
||||
extern int secure[lastdb];
|
||||
extern int secure_in_use; /* Is one of the above 1 ? */
|
||||
|
||||
/* Prototypes for global functions. */
|
||||
|
||||
@ -112,33 +116,34 @@ extern int receive_print_stats (void);
|
||||
|
||||
/* cache.c */
|
||||
extern struct hashentry *cache_search (int type, void *key, size_t len,
|
||||
struct database *table);
|
||||
struct database *table, uid_t owner);
|
||||
extern void cache_add (int type, void *key, size_t len,
|
||||
const void *packet, size_t iovtotal, void *data,
|
||||
int last, time_t t, struct database *table);
|
||||
int last, time_t t, struct database *table,
|
||||
uid_t owner);
|
||||
extern void prune_cache (struct database *table, time_t now);
|
||||
|
||||
/* pwdcache.c */
|
||||
extern void addpwbyname (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
extern void addpwbyuid (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
|
||||
/* grpcache.c */
|
||||
extern void addgrbyname (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
extern void addgrbygid (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
|
||||
/* hstcache.c */
|
||||
extern void addhstbyname (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
extern void addhstbyaddr (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
extern void addhstbynamev6 (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
extern void addhstbyaddrv6 (struct database *db, int fd, request_header *req,
|
||||
void *key);
|
||||
void *key, uid_t uid);
|
||||
|
||||
|
||||
#endif /* nscd.h */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Cache handling for passwd lookup.
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
|
||||
@ -84,7 +84,7 @@ struct passwddata
|
||||
|
||||
static void
|
||||
cache_addpw (struct database *db, int fd, request_header *req, void *key,
|
||||
struct passwd *pwd)
|
||||
struct passwd *pwd, uid_t owner)
|
||||
{
|
||||
ssize_t total;
|
||||
ssize_t written;
|
||||
@ -112,7 +112,7 @@ cache_addpw (struct database *db, int fd, request_header *req, void *key,
|
||||
pthread_rwlock_rdlock (&db->lock);
|
||||
|
||||
cache_add (req->type, copy, req->key_len, &iov_notfound,
|
||||
sizeof (notfound), (void *) -1, 0, t, db);
|
||||
sizeof (notfound), (void *) -1, 0, t, db, owner);
|
||||
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
}
|
||||
@ -175,9 +175,9 @@ cache_addpw (struct database *db, int fd, request_header *req, void *key,
|
||||
|
||||
/* We have to add the value for both, byname and byuid. */
|
||||
cache_add (GETPWBYNAME, data->strdata, pw_name_len, data,
|
||||
total, data, 0, t, db);
|
||||
total, data, 0, t, db, owner);
|
||||
|
||||
cache_add (GETPWBYUID, cp, n, data, total, data, 1, t, db);
|
||||
cache_add (GETPWBYUID, cp, n, data, total, data, 1, t, db, owner);
|
||||
|
||||
pthread_rwlock_unlock (&db->lock);
|
||||
}
|
||||
@ -192,7 +192,8 @@ cache_addpw (struct database *db, int fd, request_header *req, void *key,
|
||||
|
||||
|
||||
void
|
||||
addpwbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
addpwbyname (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t c_uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -202,10 +203,17 @@ addpwbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
char *buffer = alloca (buflen);
|
||||
struct passwd resultbuf;
|
||||
struct passwd *pwd;
|
||||
uid_t oldeuid;
|
||||
|
||||
if (debug_level > 0)
|
||||
dbg_log (_("Haven't found \"%s\" in password cache!"), key);
|
||||
|
||||
if (secure[pwddb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (c_uid);
|
||||
}
|
||||
|
||||
while (getpwnam_r (key, &resultbuf, buffer, buflen, &pwd) != 0
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
@ -214,12 +222,16 @@ addpwbyname (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addpw (db, fd, req, key, pwd);
|
||||
if (secure[pwddb])
|
||||
seteuid (c_uid);
|
||||
|
||||
cache_addpw (db, fd, req, key, pwd, c_uid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addpwbyuid (struct database *db, int fd, request_header *req, void *key)
|
||||
addpwbyuid (struct database *db, int fd, request_header *req,
|
||||
void *key, uid_t c_uid)
|
||||
{
|
||||
/* Search for the entry matching the key. Please note that we don't
|
||||
look again in the table whether the dataset is now available. We
|
||||
@ -230,10 +242,17 @@ addpwbyuid (struct database *db, int fd, request_header *req, void *key)
|
||||
struct passwd resultbuf;
|
||||
struct passwd *pwd;
|
||||
uid_t uid = atol (key);
|
||||
uid_t oldeuid = 0;
|
||||
|
||||
if (debug_level > 0)
|
||||
dbg_log (_("Haven't found \"%d\" in password cache!"), uid);
|
||||
|
||||
if (secure[pwddb])
|
||||
{
|
||||
oldeuid = geteuid ();
|
||||
seteuid (c_uid);
|
||||
}
|
||||
|
||||
while (getpwuid_r (uid, &resultbuf, buffer, buflen, &pwd) != 0
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
@ -242,5 +261,8 @@ addpwbyuid (struct database *db, int fd, request_header *req, void *key)
|
||||
buffer = alloca (buflen);
|
||||
}
|
||||
|
||||
cache_addpw (db, fd, req, key, pwd);
|
||||
if (secure[pwddb])
|
||||
seteuid (oldeuid);
|
||||
|
||||
cache_addpw (db, fd, req, key, pwd, c_uid);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user