diff options
-rw-r--r-- | usr.sbin/ypbind/ypbind.8 | 35 | ||||
-rw-r--r-- | usr.sbin/ypbind/ypbind.c | 103 |
2 files changed, 131 insertions, 7 deletions
diff --git a/usr.sbin/ypbind/ypbind.8 b/usr.sbin/ypbind/ypbind.8 index dcd47af..4748a21 100644 --- a/usr.sbin/ypbind/ypbind.8 +++ b/usr.sbin/ypbind/ypbind.8 @@ -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 , diff --git a/usr.sbin/ypbind/ypbind.c b/usr.sbin/ypbind/ypbind.c index 0d68818..775f4c4 100644 --- a/usr.sbin/ypbind/ypbind.c +++ b/usr.sbin/ypbind/ypbind.c @@ -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; +} |