Add a -S option to ypbind that allows the following:

-S domainname,server1,server2,server3,...
           The -S flag allows the system administrator to lock ypbind to a
           particular domain and group of NIS servers. Up to ten servers can
           be specified.  There must not be any spaces between the commas in
           the domain/server specification. This option is used to insure that
           that the system binds only to one domain and only to one of the
           specified servers, which is useful for systems that are both NIS
           servers and NIS clients: it provides a way to restrict what ma-
           chines the system can bind to without the need for specifying the
           -ypset or -ypsetme options, which are often considered to be secu-
           rity holes. The specified servers must have valid entries in the
           local /etc/hosts file. IP addresses may be specified in place of
           hostnames. If ypbind can't make sense ouf of the arguments, it will
           ignore the -S flag and continue running normally.

           Note that ypbind will consider the domainname specified with the -S
           flag to be the system default domain.

(According to what Garrett showed me, OSF/1 actually only allows 4 servers
to be specified. Ten seemed to be a bit more reasonable to me.)

Suggested by: G. Wollman
Idea lifted from: OSF/1
This commit is contained in:
Bill Paul 1995-07-20 22:33:02 +00:00
parent cfb5972713
commit a974cefe6e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=9600
2 changed files with 131 additions and 7 deletions

View File

@ -29,7 +29,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: ypbind.8,v 1.1 1995/04/09 21:59:06 wpaul Exp $
.\" $Id: ypbind.8,v 1.2 1995/04/26 19:03:15 wpaul Exp $
.\"
.Dd April 9, 1995
.Dt YPBIND 8
@ -42,6 +42,7 @@
.Op Fl ypset
.Op Fl ypsetme
.Op Fl s
.Op Fl S Ar domainname,server1,server2,...
.Sh DESCRIPTION
.Nm ypbind
is the process that maintains NIS binding information. At startup,
@ -103,6 +104,35 @@ flag causes
to run in secure mode: it will refuse to bind to any NIS server
that is not running as root (i.e. that is not using privileged
TCP ports).
.It Fl S Ar domainname,server1,server2,server3,...
The
.Fl S
flag allows the system administrator to lock ypbind to a particular
domain and group of NIS servers. Up to ten servers can be specified.
There must not be any spaces between the commas in the domain/server
specification. This option is used to insure that that the system binds
only to one domain and only to one of the specified servers, which
is useful for systems that are both NIS servers and NIS
clients: it provides a way to restrict what machines the system can
bind to without the need for specifying the
.Fl ypset
or
.Fl ypsetme
options, which are often considered to be security holes. The specified
servers must have valid entries in the local
.Pa /etc/hosts
file. IP addresses may be specified in place of hostnames. If
.Nm ypbind
can't make sense ouf of the arguments, it will ignore
the
.Fl S
flag and continue running normally.
.Pp
Note that
.Nm ypbind
will consider the domainname specified with the
.Fl S
flag to be the system default domain.
.Sh NOTES
.Nm ypbind
will not make continuous attempts to keep secondary domains bound.
@ -118,6 +148,9 @@ client programs reference it ot not.
.Bl -tag -width Pa -compact
.It Pa /var/yp/binding/[domainname].[version]
The files used to hold binding information for each NIS domain.
.It Pa /etc/sysconfig
System configuration file where the system default domain and
ypbind startup options are specified.
.El
.Sh SEE ALSO
.Xr syslog 3 ,

View File

@ -28,7 +28,7 @@
*/
#ifndef LINT
static char rcsid[] = "$Id: ypbind.c,v 1.15 1995/05/30 03:55:13 rgrimes Exp $";
static char rcsid[] = "$Id: ypbind.c,v 1.16 1995/07/15 23:27:27 wpaul Exp $";
#endif
#include <sys/param.h>
@ -99,6 +99,8 @@ int tell_parent __P((char *, struct sockaddr_in *));
void handle_children __P(( struct _dom_binding * ));
void reaper __P((int));
void terminate __P((int));
void yp_restricted_mode __P((char *));
int verify __P((struct in_addr));
char *domainname;
struct _dom_binding *ypbindlist;
@ -110,6 +112,15 @@ static struct _dom_binding *broad_domain;
int ypsetmode = YPSET_NO;
int ypsecuremode = 0;
/*
* Special restricted mode variables: when in restricted mode, only the
* specified restricted_domain will be bound, and only the servers listed
* in restricted_addrs will be used for binding.
*/
#define RESTRICTED_SERVERS 10
int yp_restricted = 0;
struct in_addr restricted_addrs[RESTRICTED_SERVERS];
/* No more than MAX_CHILDREN child broadcasters at a time. */
#ifndef MAX_CHILDREN
#define MAX_CHILDREN 5
@ -123,6 +134,12 @@ int ypsecuremode = 0;
#define FAIL_THRESHOLD 10
#endif
/* Number of times to fish for a response froma particular set of hosts */
#ifndef MAX_RETRIES
#define MAX_RETRIES 30
#endif
int retries = 0;
int children = 0;
int domains = 0;
int yplockfd;
@ -162,6 +179,11 @@ CLIENT *clnt;
}
if(ypdb==NULL) {
if (yp_restricted) {
syslog(LOG_NOTICE, "Running in restricted mode -- request to bind domain \"%s\" rejected.\n", argp);
return &res;
}
if (domains >= MAX_DOMAINS) {
syslog(LOG_WARNING, "domain limit (%d) exceeded",
MAX_DOMAINS);
@ -363,6 +385,7 @@ char **argv;
exit(1);
}
/* XXX domainname will be overriden if we use restricted mode */
yp_get_default_domain(&domainname);
if( domainname[0] == '\0') {
fprintf(stderr, "domainname not set. Aborting.\n");
@ -376,6 +399,8 @@ char **argv;
ypsetmode = YPSET_LOCAL;
else if (strcmp("-s", argv[i]) == 0)
ypsecuremode++;
else if (strcmp("-S", argv[i]) == 0 && argc > i)
yp_restricted_mode(argv[i+1]);
}
/* blow away everything in BINDINGDIR (if it exists) */
@ -555,9 +580,22 @@ bool_t broadcast_result(out, addr)
bool_t *out;
struct sockaddr_in *addr;
{
if (tell_parent(broad_domain->dom_domain, addr))
syslog(LOG_WARNING, "lost connection to parent");
return TRUE;
if (retries >= MAX_RETRIES) {
bzero((char *)addr, sizeof(struct sockaddr_in));
if (tell_parent(broad_domain->dom_domain, addr))
syslog(LOG_WARNING, "lost connection to parent");
return TRUE;
}
if (yp_restricted && verify(addr->sin_addr)) {
retries++;
syslog(LOG_NOTICE, "NIS server at %s not in restricted mode access list -- rejecting.\n",inet_ntoa(addr->sin_addr));
return FALSE;
} else {
if (tell_parent(broad_domain->dom_domain, addr))
syslog(LOG_WARNING, "lost connection to parent");
return TRUE;
}
}
/*
@ -615,6 +653,8 @@ struct _dom_binding *ypdb;
}
close(yplockfd);
retries = 0;
stat = clnt_broadcast(YPPROG, YPVERS, YPPROC_DOMAIN_NONACK,
xdr_domainname, (char *)ypdb->dom_domain, xdr_bool, (char *)&out,
broadcast_result);
@ -717,8 +757,8 @@ int force;
}
}
/* if in securemode, check originating port number */
if (ypsecuremode && (ntohs(raddrp->sin_port) >= IPPORT_RESERVED)) {
/* if in secure mode, check originating port number */
if ((ypsecuremode && (ntohs(raddrp->sin_port) >= IPPORT_RESERVED))) {
syslog(LOG_WARNING, "Rejected NIS server on [%s/%d] for domain %s.",
inet_ntoa(raddrp->sin_addr), ntohs(raddrp->sin_port),
dom);
@ -824,3 +864,54 @@ int force;
return;
}
}
/*
* Check address against list of allowed servers. Return 0 if okay,
* 1 if not matched.
*/
int
verify(addr)
struct in_addr addr;
{
int i;
for (i = 0; i < RESTRICTED_SERVERS; i++)
if (!bcmp((char *)&addr, (char *)&restricted_addrs[i],
sizeof(struct in_addr)))
return(0);
return(1);
}
/*
* Try to set restricted mode. We default to normal mode if we can't
* resolve the specified hostnames.
*/
void
yp_restricted_mode(args)
char *args;
{
struct hostent *h;
int i = 0;
char *s;
/* Find the restricted domain. */
if ((s = strsep(&args, ",")) == NULL)
return;
domainname = s;
/* Get the addresses of the servers. */
while ((s = strsep(&args, ",")) != NULL && i < RESTRICTED_SERVERS) {
if ((h = gethostbyname(s)) == NULL)
return;
bcopy ((char *)h->h_addr_list[0], (char *)&restricted_addrs[i],
sizeof(struct in_addr));
i++;
}
/* ypset and ypsetme not allowed with restricted mode */
ypsetmode = YPSET_NO;
yp_restricted = 1;
return;
}