mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-23 19:28:36 +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_NETWORKS "/etc/networks"
|
||||||
#define _PATH_PROTOCOLS "/etc/protocols"
|
#define _PATH_PROTOCOLS "/etc/protocols"
|
||||||
#define _PATH_SERVICES "/etc/services"
|
#define _PATH_SERVICES "/etc/services"
|
||||||
|
#define _PATH_SERVICES_DB "/var/db/services.db"
|
||||||
|
|
||||||
#define h_errno (*__h_errno())
|
#define h_errno (*__h_errno())
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
* currently implemented sources
|
* currently implemented sources
|
||||||
*/
|
*/
|
||||||
#define NSSRC_FILES "files" /* local files */
|
#define NSSRC_FILES "files" /* local files */
|
||||||
|
#define NSSRC_DB "db" /* database */
|
||||||
#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */
|
#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */
|
||||||
#define NSSRC_NIS "nis" /* YP/NIS */
|
#define NSSRC_NIS "nis" /* YP/NIS */
|
||||||
#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */
|
#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */
|
||||||
|
|
|
@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <db.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <nsswitch.h>
|
#include <nsswitch.h>
|
||||||
|
@ -94,6 +96,19 @@ NSS_TLS_HANDLING(files);
|
||||||
static int files_servent(void *, void *, va_list);
|
static int files_servent(void *, void *, va_list);
|
||||||
static int files_setservent(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
|
#ifdef YP
|
||||||
/* nis backend declarations */
|
/* nis backend declarations */
|
||||||
static int nis_servent(void *, void *, va_list);
|
static int nis_servent(void *, void *, va_list);
|
||||||
|
@ -263,6 +278,8 @@ files_servent(void *retval, void *mdata, va_list ap)
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
ns_dtab compat_dtab[] = {
|
ns_dtab compat_dtab[] = {
|
||||||
|
{ NSSRC_DB, db_servent,
|
||||||
|
(void *)((struct servent_mdata *)mdata)->how },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_servent,
|
{ NSSRC_NIS, nis_servent,
|
||||||
(void *)((struct servent_mdata *)mdata)->how },
|
(void *)((struct servent_mdata *)mdata)->how },
|
||||||
|
@ -452,6 +469,185 @@ files_setservent(void *retval, void *mdata, va_list ap)
|
||||||
return (NS_UNAVAIL);
|
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 */
|
/* nis backend implementation */
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
static void
|
static void
|
||||||
|
@ -638,6 +834,7 @@ compat_setservent(void *retval, void *mdata, va_list ap)
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
ns_dtab compat_dtab[] = {
|
ns_dtab compat_dtab[] = {
|
||||||
|
{ NSSRC_DB, db_setservent, mdata },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_setservent, mdata },
|
{ NSSRC_NIS, nis_setservent, mdata },
|
||||||
#endif
|
#endif
|
||||||
|
@ -924,6 +1121,7 @@ getservbyname_r(const char *name, const char *proto, struct servent *serv,
|
||||||
#endif /* NS_CACHING */
|
#endif /* NS_CACHING */
|
||||||
static const ns_dtab dtab[] = {
|
static const ns_dtab dtab[] = {
|
||||||
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
||||||
|
{ NSSRC_DB, db_servent, (void *)nss_lt_name },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_servent, (void *)nss_lt_name },
|
{ NSSRC_NIS, nis_servent, (void *)nss_lt_name },
|
||||||
#endif
|
#endif
|
||||||
|
@ -960,6 +1158,7 @@ getservbyport_r(int port, const char *proto, struct servent *serv,
|
||||||
#endif
|
#endif
|
||||||
static const ns_dtab dtab[] = {
|
static const ns_dtab dtab[] = {
|
||||||
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
||||||
|
{ NSSRC_DB, db_servent, (void *)nss_lt_id },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_servent, (void *)nss_lt_id },
|
{ NSSRC_NIS, nis_servent, (void *)nss_lt_id },
|
||||||
#endif
|
#endif
|
||||||
|
@ -995,6 +1194,7 @@ getservent_r(struct servent *serv, char *buffer, size_t bufsize,
|
||||||
#endif
|
#endif
|
||||||
static const ns_dtab dtab[] = {
|
static const ns_dtab dtab[] = {
|
||||||
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
{ NSSRC_FILES, files_servent, (void *)&mdata },
|
||||||
|
{ NSSRC_DB, db_servent, (void *)nss_lt_all },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_servent, (void *)nss_lt_all },
|
{ NSSRC_NIS, nis_servent, (void *)nss_lt_all },
|
||||||
#endif
|
#endif
|
||||||
|
@ -1027,6 +1227,7 @@ setservent(int stayopen)
|
||||||
#endif
|
#endif
|
||||||
static const ns_dtab dtab[] = {
|
static const ns_dtab dtab[] = {
|
||||||
{ NSSRC_FILES, files_setservent, (void *)SETSERVENT },
|
{ NSSRC_FILES, files_setservent, (void *)SETSERVENT },
|
||||||
|
{ NSSRC_DB, db_setservent, (void *)SETSERVENT },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
|
{ NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
|
||||||
#endif
|
#endif
|
||||||
|
@ -1051,6 +1252,7 @@ endservent()
|
||||||
#endif
|
#endif
|
||||||
static const ns_dtab dtab[] = {
|
static const ns_dtab dtab[] = {
|
||||||
{ NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
|
{ NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
|
||||||
|
{ NSSRC_DB, db_setservent, (void *)ENDSERVENT },
|
||||||
#ifdef YP
|
#ifdef YP
|
||||||
{ NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
|
{ NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd January 22, 2007
|
.Dd April 4, 2010
|
||||||
.Dt NSDISPATCH 3
|
.Dt NSDISPATCH 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -176,6 +176,7 @@ While there is support for arbitrary sources, the following
|
||||||
.Bl -column NSSRC_COMPAT compat -offset indent
|
.Bl -column NSSRC_COMPAT compat -offset indent
|
||||||
.It Sy "#define value"
|
.It Sy "#define value"
|
||||||
.It Dv NSSRC_FILES Ta """files""
|
.It Dv NSSRC_FILES Ta """files""
|
||||||
|
.It Dv NSSRC_DB Ta """db""
|
||||||
.It Dv NSSRC_DNS Ta """dns""
|
.It Dv NSSRC_DNS Ta """dns""
|
||||||
.It Dv NSSRC_NIS Ta """nis""
|
.It Dv NSSRC_NIS Ta """nis""
|
||||||
.It Dv NSSRC_COMPAT Ta """compat""
|
.It Dv NSSRC_COMPAT Ta """compat""
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd December 23, 2008
|
.Dd April 4, 2010
|
||||||
.Dt NSSWITCH.CONF 5
|
.Dt NSSWITCH.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -72,6 +72,8 @@ Local files, such as
|
||||||
.Pa /etc/hosts ,
|
.Pa /etc/hosts ,
|
||||||
and
|
and
|
||||||
.Pa /etc/passwd .
|
.Pa /etc/passwd .
|
||||||
|
.It db
|
||||||
|
Local database.
|
||||||
.It dns
|
.It dns
|
||||||
Internet Domain Name System.
|
Internet Domain Name System.
|
||||||
.Dq hosts
|
.Dq hosts
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
.\" @(#)services.5 8.1 (Berkeley) 6/5/93
|
.\" @(#)services.5 8.1 (Berkeley) 6/5/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 5, 1993
|
.Dd April 4, 2010
|
||||||
.Dt SERVICES 5
|
.Dt SERVICES 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -65,6 +65,18 @@ not interpreted by the routines which search the file.
|
||||||
Service names may contain any printable
|
Service names may contain any printable
|
||||||
character other than a field delimiter, newline,
|
character other than a field delimiter, newline,
|
||||||
or comment character.
|
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
|
.Sh NIS INTERACTION
|
||||||
Access to the NIS
|
Access to the NIS
|
||||||
.Pa services.byname
|
.Pa services.byname
|
||||||
|
@ -84,6 +96,8 @@ file resides in
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr getservent 3
|
.Xr getservent 3
|
||||||
|
.Xr nsswitch.conf 5
|
||||||
|
.Xr services_mkdb 8
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
|
Loading…
Reference in a new issue