mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-18 02:19:39 +00:00
Add capability to use a db version of services. It is enabled by
specifying `db' as source of service in /etc/nsswitch.conf. MFC after: 2 weeks
This commit is contained in:
parent
dc6ab8ddb4
commit
e622b47989
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=206155
@ -82,6 +82,7 @@ typedef __uint32_t uint32_t;
|
||||
#define _PATH_NETWORKS "/etc/networks"
|
||||
#define _PATH_PROTOCOLS "/etc/protocols"
|
||||
#define _PATH_SERVICES "/etc/services"
|
||||
#define _PATH_SERVICES_DB "/var/db/services.db"
|
||||
|
||||
#define h_errno (*__h_errno())
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
* currently implemented sources
|
||||
*/
|
||||
#define NSSRC_FILES "files" /* local files */
|
||||
#define NSSRC_DB "db" /* database */
|
||||
#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */
|
||||
#define NSSRC_NIS "nis" /* YP/NIS */
|
||||
#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */
|
||||
|
@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <db.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <nsswitch.h>
|
||||
@ -94,6 +96,19 @@ NSS_TLS_HANDLING(files);
|
||||
static int files_servent(void *, void *, va_list);
|
||||
static int files_setservent(void *, void *, va_list);
|
||||
|
||||
/* db backend declarations */
|
||||
struct db_state
|
||||
{
|
||||
DB *db;
|
||||
int stayopen;
|
||||
int keynum;
|
||||
};
|
||||
static void db_endstate(void *);
|
||||
NSS_TLS_HANDLING(db);
|
||||
|
||||
static int db_servent(void *, void *, va_list);
|
||||
static int db_setservent(void *, void *, va_list);
|
||||
|
||||
#ifdef YP
|
||||
/* nis backend declarations */
|
||||
static int nis_servent(void *, void *, va_list);
|
||||
@ -263,6 +278,8 @@ files_servent(void *retval, void *mdata, va_list ap)
|
||||
{ NULL, 0 }
|
||||
};
|
||||
ns_dtab compat_dtab[] = {
|
||||
{ NSSRC_DB, db_servent,
|
||||
(void *)((struct servent_mdata *)mdata)->how },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_servent,
|
||||
(void *)((struct servent_mdata *)mdata)->how },
|
||||
@ -452,6 +469,185 @@ files_setservent(void *retval, void *mdata, va_list ap)
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
/* db backend implementation */
|
||||
static void
|
||||
db_endstate(void *p)
|
||||
{
|
||||
DB *db;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
db = ((struct db_state *)p)->db;
|
||||
if (db != NULL)
|
||||
db->close(db);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
static int
|
||||
db_servent(void *retval, void *mdata, va_list ap)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
DBT key, data;
|
||||
DB *db;
|
||||
|
||||
char *resultbuf;
|
||||
|
||||
struct db_state *st;
|
||||
int rv;
|
||||
int stayopen;
|
||||
|
||||
enum nss_lookup_type how;
|
||||
char *name;
|
||||
char *proto;
|
||||
int port;
|
||||
|
||||
struct servent *serv;
|
||||
char *buffer;
|
||||
size_t bufsize;
|
||||
int *errnop;
|
||||
|
||||
name = NULL;
|
||||
proto = NULL;
|
||||
how = (enum nss_lookup_type)mdata;
|
||||
switch (how) {
|
||||
case nss_lt_name:
|
||||
name = va_arg(ap, char *);
|
||||
proto = va_arg(ap, char *);
|
||||
break;
|
||||
case nss_lt_id:
|
||||
port = va_arg(ap, int);
|
||||
proto = va_arg(ap, char *);
|
||||
break;
|
||||
case nss_lt_all:
|
||||
break;
|
||||
default:
|
||||
return NS_NOTFOUND;
|
||||
};
|
||||
|
||||
serv = va_arg(ap, struct servent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
bufsize = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap,int *);
|
||||
|
||||
*errnop = db_getstate(&st);
|
||||
if (*errnop != 0)
|
||||
return (NS_UNAVAIL);
|
||||
|
||||
if (how == nss_lt_all && st->keynum < 0)
|
||||
return (NS_NOTFOUND);
|
||||
|
||||
if (st->db == NULL) {
|
||||
st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL);
|
||||
if (st->db == NULL) {
|
||||
*errnop = errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
}
|
||||
|
||||
stayopen = (how == nss_lt_all) ? 1 : st->stayopen;
|
||||
db = st->db;
|
||||
|
||||
do {
|
||||
switch (how) {
|
||||
case nss_lt_name:
|
||||
key.data = buf;
|
||||
if (proto == NULL)
|
||||
key.size = snprintf(buf, sizeof(buf),
|
||||
"\376%s", name);
|
||||
else
|
||||
key.size = snprintf(buf, sizeof(buf),
|
||||
"\376%s/%s", name, proto);
|
||||
key.size++;
|
||||
if (db->get(db, &key, &data, 0) != 0 ||
|
||||
db->get(db, &data, &key, 0) != 0) {
|
||||
rv = NS_NOTFOUND;
|
||||
goto db_fin;
|
||||
}
|
||||
resultbuf = key.data;
|
||||
break;
|
||||
case nss_lt_id:
|
||||
key.data = buf;
|
||||
port = htons(port);
|
||||
if (proto == NULL)
|
||||
key.size = snprintf(buf, sizeof(buf),
|
||||
"\377%d", port);
|
||||
else
|
||||
key.size = snprintf(buf, sizeof(buf),
|
||||
"\377%d/%s", port, proto);
|
||||
key.size++;
|
||||
if (db->get(db, &key, &data, 0) != 0 ||
|
||||
db->get(db, &data, &key, 0) != 0) {
|
||||
rv = NS_NOTFOUND;
|
||||
goto db_fin;
|
||||
}
|
||||
resultbuf = key.data;
|
||||
break;
|
||||
case nss_lt_all:
|
||||
key.data = buf;
|
||||
key.size = snprintf(buf, sizeof(buf), "%d",
|
||||
st->keynum++);
|
||||
key.size++;
|
||||
if (db->get(db, &key, &data, 0) != 0) {
|
||||
st->keynum = -1;
|
||||
rv = NS_NOTFOUND;
|
||||
goto db_fin;
|
||||
}
|
||||
resultbuf = data.data;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = parse_result(serv, buffer, bufsize, resultbuf,
|
||||
strlen(resultbuf), errnop);
|
||||
|
||||
} while (!(rv & NS_TERMINATE) && how == nss_lt_all);
|
||||
|
||||
db_fin:
|
||||
if (!stayopen && st->db != NULL) {
|
||||
db->close(db);
|
||||
st->db = NULL;
|
||||
}
|
||||
|
||||
if (rv == NS_SUCCESS && retval != NULL)
|
||||
*(struct servent **)retval = serv;
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
db_setservent(void *retval, void *mdata, va_list ap)
|
||||
{
|
||||
DB *db;
|
||||
struct db_state *st;
|
||||
int rv;
|
||||
int f;
|
||||
|
||||
rv = db_getstate(&st);
|
||||
if (rv != 0)
|
||||
return (NS_UNAVAIL);
|
||||
|
||||
switch ((enum constants)mdata) {
|
||||
case SETSERVENT:
|
||||
f = va_arg(ap, int);
|
||||
st->stayopen |= f;
|
||||
st->keynum = 0;
|
||||
break;
|
||||
case ENDSERVENT:
|
||||
db = st->db;
|
||||
if (db != NULL) {
|
||||
db->close(db);
|
||||
st->db = NULL;
|
||||
}
|
||||
st->stayopen = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
/* nis backend implementation */
|
||||
#ifdef YP
|
||||
static void
|
||||
@ -638,6 +834,7 @@ compat_setservent(void *retval, void *mdata, va_list ap)
|
||||
{ NULL, 0 }
|
||||
};
|
||||
ns_dtab compat_dtab[] = {
|
||||
{ NSSRC_DB, db_setservent, mdata },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_setservent, mdata },
|
||||
#endif
|
||||
@ -924,6 +1121,7 @@ getservbyname_r(const char *name, const char *proto, struct servent *serv,
|
||||
#endif /* NS_CACHING */
|
||||
static const ns_dtab dtab[] = {
|
||||
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
||||
{ NSSRC_DB, db_servent, (void *)nss_lt_name },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_servent, (void *)nss_lt_name },
|
||||
#endif
|
||||
@ -960,6 +1158,7 @@ getservbyport_r(int port, const char *proto, struct servent *serv,
|
||||
#endif
|
||||
static const ns_dtab dtab[] = {
|
||||
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
||||
{ NSSRC_DB, db_servent, (void *)nss_lt_id },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_servent, (void *)nss_lt_id },
|
||||
#endif
|
||||
@ -995,6 +1194,7 @@ getservent_r(struct servent *serv, char *buffer, size_t bufsize,
|
||||
#endif
|
||||
static const ns_dtab dtab[] = {
|
||||
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
||||
{ NSSRC_DB, db_servent, (void *)nss_lt_all },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_servent, (void *)nss_lt_all },
|
||||
#endif
|
||||
@ -1027,6 +1227,7 @@ setservent(int stayopen)
|
||||
#endif
|
||||
static const ns_dtab dtab[] = {
|
||||
{ NSSRC_FILES, files_setservent, (void *)SETSERVENT },
|
||||
{ NSSRC_DB, db_setservent, (void *)SETSERVENT },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
|
||||
#endif
|
||||
@ -1051,6 +1252,7 @@ endservent()
|
||||
#endif
|
||||
static const ns_dtab dtab[] = {
|
||||
{ NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
|
||||
{ NSSRC_DB, db_setservent, (void *)ENDSERVENT },
|
||||
#ifdef YP
|
||||
{ NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 22, 2007
|
||||
.Dd April 4, 2010
|
||||
.Dt NSDISPATCH 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -176,6 +176,7 @@ While there is support for arbitrary sources, the following
|
||||
.Bl -column NSSRC_COMPAT compat -offset indent
|
||||
.It Sy "#define value"
|
||||
.It Dv NSSRC_FILES Ta """files""
|
||||
.It Dv NSSRC_DB Ta """db""
|
||||
.It Dv NSSRC_DNS Ta """dns""
|
||||
.It Dv NSSRC_NIS Ta """nis""
|
||||
.It Dv NSSRC_COMPAT Ta """compat""
|
||||
|
@ -33,7 +33,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 23, 2008
|
||||
.Dd April 4, 2010
|
||||
.Dt NSSWITCH.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -72,6 +72,8 @@ Local files, such as
|
||||
.Pa /etc/hosts ,
|
||||
and
|
||||
.Pa /etc/passwd .
|
||||
.It db
|
||||
Local database.
|
||||
.It dns
|
||||
Internet Domain Name System.
|
||||
.Dq hosts
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\" @(#)services.5 8.1 (Berkeley) 6/5/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 5, 1993
|
||||
.Dd April 4, 2010
|
||||
.Dt SERVICES 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -65,6 +65,18 @@ not interpreted by the routines which search the file.
|
||||
Service names may contain any printable
|
||||
character other than a field delimiter, newline,
|
||||
or comment character.
|
||||
.Pp
|
||||
If
|
||||
.Dq db
|
||||
is specified as source in the
|
||||
.Xr nsswitch.conf 5 ,
|
||||
.Pa /var/db/services.db
|
||||
is searched.
|
||||
The database in
|
||||
.Pa /var/db/services.db
|
||||
needs to be updated with
|
||||
.Xr services_mkdb 8
|
||||
after changes to the services file have been applied.
|
||||
.Sh NIS INTERACTION
|
||||
Access to the NIS
|
||||
.Pa services.byname
|
||||
@ -84,6 +96,8 @@ file resides in
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr getservent 3
|
||||
.Xr nsswitch.conf 5
|
||||
.Xr services_mkdb 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
Loading…
Reference in New Issue
Block a user