aboutsummaryrefslogtreecommitdiff
path: root/gnu/usr.sbin/ypserv/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.sbin/ypserv/server.c')
-rw-r--r--gnu/usr.sbin/ypserv/server.c1384
1 files changed, 0 insertions, 1384 deletions
diff --git a/gnu/usr.sbin/ypserv/server.c b/gnu/usr.sbin/ypserv/server.c
deleted file mode 100644
index 205a8467ed1f..000000000000
--- a/gnu/usr.sbin/ypserv/server.c
+++ /dev/null
@@ -1,1384 +0,0 @@
-/*
-** server.c YP server routines.
-**
-** Copyright (c) 1993 Signum Support AB, Sweden
-**
-** This file is part of the NYS YP Server.
-**
-** The NYS YP Server is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of the
-** License, or (at your option) any later version.
-**
-** The NYS YP Server is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-**
-** You should have received a copy of the GNU General Public
-** License along with the NYS YP Server; see the file COPYING. If
-** not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-** Cambridge, MA 02139, USA.
-**
-** Author: Peter Eriksson <pen@signum.se>
-** Ported to FreeBSD and hacked all to pieces
-** by Bill Paul <wpaul@ctr.columbia.edu>
-**
-** $Id: server.c,v 1.11 1995/07/15 23:27:47 wpaul Exp $
-**
-*/
-
-#include "system.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <string.h>
-#include <limits.h>
-#include <db.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <rpc/rpc.h>
-#include "yp.h"
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <syslog.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#define PERM_SECURE (S_IRUSR|S_IWUSR)
-HASHINFO openinfo = {
- 4096, /* bsize */
- 32, /* ffactor */
- 256, /* nelem */
- 2048 * 1024, /* cachesize */
- NULL, /* hash */
- 0, /* lorder */
-};
-
-#if TCP_WRAPPER
-#include "tcpd.h"
-int allow_severity=LOG_INFO;
-int deny_severity=LOG_WARNING;
-#endif
-
-void verr __P((const char *, _BSD_VA_LIST_));
-void Perror __P((const char *, ...));
-
-extern char *dnsname();
-extern char *dnsaddr();
-extern char *_gethostbydnsaddr();
-
-extern char *progname;
-extern int errno;
-
-int debug_flag = 0;
-int dns_flag = 0;
-int children = 0;
-int forked = 0;
-
-void verr(fmt, ap)
- const char *fmt;
- _BSD_VA_LIST_ ap;
-
-{
- if (debug_flag)
- vfprintf(stderr, fmt, ap);
- else
- vsyslog(LOG_NOTICE, fmt, ap);
-}
-
-void
-#ifdef __STDC__
-Perror(const char *fmt, ...)
-#else
-Perror(fmt, va_list)
- const char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- verr(fmt,ap);
- va_end(ap);
-}
-
-
-/*
-** Return 1 if request comes from an authorized host
-**
-** XXX This function should implement the "securenets" functionality
-*/
-static int is_valid_host(struct sockaddr_in *sin)
-{
-#if TCP_WRAPPER
- extern int hosts_ctl(char *, char *, char *, char *);
- int status;
- static long oldaddr=0; /* so we dont log multiple times */
- static int oldstatus=-1;
- char *h=NULL;
-
-#ifdef TRYRESOLVE
- struct hostent *hp;
-
- hp = _gethostbydnsaddr((char *) &sin->sin_addr.s_addr,
- sizeof (sin->sin_addr.s_addr), AF_INET);
-
- h = (hp && hp->h_name) ? hp->h_name : NULL;
-#endif
-
-#ifndef FROM_UNKNOWN
-#define FROM_UNKNOWN STRING_UNKNOWN
-#endif
-
- status = hosts_ctl(progname,
- h?h:FROM_UNKNOWN,
- inet_ntoa(sin->sin_addr),
- "");
-
- if (!status && (sin->sin_addr.s_addr != oldaddr || status != oldstatus)) {
- syslog(status?allow_severity:deny_severity,
- "%sconnect from %s\n",status?"":"refused ",
- h?h:inet_ntoa(sin->sin_addr));
- oldaddr=sin->sin_addr.s_addr;
- oldstatus=status;
- }
- return status;
-#else
- return 1;
-#endif
-}
-
-
-void *ypproc_null_2_svc(void *dummy,
- struct svc_req *rqstp)
-{
- static int foo;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
- if (!is_valid_host(rqhost))
- return NULL;
-
- if (debug_flag)
- Perror("ypproc_null() [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- return (void *) &foo;
-}
-
-
-/*
-** Return 1 if the name is a valid domain name served by us, else 0.
-*/
-static int is_valid_domain(const char *domain)
-{
- struct stat sbuf;
-
-
- if (domain == NULL ||
- strcmp(domain, "binding") == 0 ||
- strcmp(domain, "..") == 0 ||
- strcmp(domain, ".") == 0 ||
- strchr(domain, '/'))
- return 0;
-
- if (stat(domain, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
- return 0;
-
- return 1;
-}
-
-
-
-bool_t *ypproc_domain_2_svc(domainname *name,
- struct svc_req *rqstp)
-{
- static bool_t result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- Perror("ypproc_domain(\"%s\") [From: %s:%d]\n",
- *name,
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- if (is_valid_domain(*name))
- result = TRUE;
- else
- result = FALSE;
-
- if (debug_flag)
- Perror("\t-> %s.\n",
- (result == TRUE ? "Ok" : "Not served by us"));
-
- return &result;
-}
-
-
-bool_t *ypproc_domain_nonack_2_svc(domainname *name,
- struct svc_req *rqstp)
-{
- static bool_t result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- Perror("ypproc_domain_nonack(\"%s\") [From: %s:%d]\n",
- *name,
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- if (!is_valid_domain(*name))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid domain)\n");
-
- /* Bail out and don't return any RPC value */
- return NULL;
- }
-
- if (debug_flag)
- Perror("\t-> OK.\n");
-
- result = TRUE;
- return &result;
-}
-
-
-/*
-** Open a DB database
-*/
-static DB *open_database(const char *domain,
- const char *map)
-{
- DB *dbp;
- char buf[1025];
-
-
- if (map[0] == '.' || strchr(map, '/'))
- return 0;
-
- sprintf (buf, "%s/%s", domain, map);
-
- dbp = dbopen(buf,O_RDONLY|O_EXCL, PERM_SECURE, DB_HASH, &openinfo);
-
- if (debug_flag > 1 && dbp == NULL)
- Perror("dbopen(%s): %s", map, strerror(errno));
-
- return dbp;
-}
-
-
-#define F_ALL 0x01
-#define F_NEXT 0x02
-#define F_YPALL 0x08
-
-/*
-** Get a record from a DB database.
-** This looks ugly because it emulates the behavior of the original
-** GDBM-based routines. Blech.
-*/
-int read_database(DB *dbp,
- const DBT *ikey,
- DBT *okey,
- DBT *dval,
- int flags)
-{
- int first_flag = 0;
- DBT nkey, ckey, dummyval;
-
-
- if (ikey == NULL || ikey->data == NULL)
- {
- (dbp->seq)(dbp,&ckey,&dummyval,R_FIRST);
- first_flag = 1;
- }
- else
- {
- if ((flags & F_NEXT))
- {
- /*
- ** This crap would be unnecessary if R_CURSOR actually worked.
- */
- if (flags < F_YPALL)
- {
- (dbp->seq)(dbp,&ckey,&dummyval,R_FIRST);
- while(strncmp((char *)ikey->data,ckey.data,(int)ikey->size) ||
- ikey->size != ckey.size)
- (dbp->seq)(dbp,&ckey,&dummyval,R_NEXT);
- }
- if ((dbp->seq)(dbp,&ckey,&dummyval,R_NEXT))
- ckey.data = NULL;
-#ifdef GNU_YPSERV_ARTIFACT
- free(dummyval.data);
-#endif
- }
- else
- ckey = *ikey;
- }
-
- if (ckey.data == NULL)
- {
- return (flags & F_NEXT) ? YP_NOMORE : YP_NOKEY;
- }
-
- while (1)
- {
- if ((dbp->get)(dbp,&ckey,dval,0))
- {
-#ifdef GNU_YPSERV_ARTIFACT
- /* Free key, unless it comes from the caller! */
- if (ikey == NULL || ckey.data != ikey->data)
- free(ckey.data);
-#endif
- if (ikey && ikey->data != NULL)
- {
- return YP_NOKEY;
- }
- else
- if (first_flag)
- return YP_BADDB;
- else
- return YP_FALSE;
- }
-
- if ((flags & F_ALL) || strncmp(ckey.data, "YP_", 3) != 0)
- {
- if (okey)
- *okey = ckey;
-#ifdef GNU_YPSERV_ARTIFACT
- else if (ikey == NULL || ikey->data != ckey.data)
- free(ckey.data);
-#endif
- return YP_TRUE;
- }
-
- /* Free old value */
-#ifdef GNU_YPSERV_ARTIFACT
- free(dval->data);
-#endif
- if ((dbp->seq)(dbp,&nkey,&dummyval,R_NEXT))
- nkey.data = NULL;
-#ifdef GNU_YPSERV_ARTIFACT
- free(dummyval.data);
-
- /* Free old key, unless it comes from the caller! */
- if (ikey == NULL || ckey.data != ikey->data)
- free(ckey.data);
-#endif
- if (ckey.data == NULL || nkey.data == NULL)
- return YP_NOMORE;
-
- ckey = nkey;
- }
-}
-
-
-/*
-** Get the DateTimeModified value for a certain map database
-*/
-static unsigned long get_dtm(const char *domain,
- const char *map)
-{
- struct stat sbuf;
- char buf[1025];
-
-
- strcpy(buf, domain);
- strcat(buf, "/");
- strcat(buf, map);
-
- if (stat(buf, &sbuf) < 0)
- return 0;
- else
- return (unsigned long) sbuf.st_mtime;
-}
-
-
-/*
-** YP function "MATCH" implementation
-*/
-ypresp_val *ypproc_match_2_svc(ypreq_key *key,
- struct svc_req *rqstp)
-{
- static ypresp_val result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_match(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\t\tdomainname = \"%s\"\n",
- key->domain);
- Perror("\t\tmapname = \"%s\"\n",
- key->map);
- Perror("\t\tkeydat = \"%.*s\"\n",
- (int) key->key.keydat_len,
- key->key.keydat_val);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- /*
- ** If this request deals with master.passwd.* and it didn't
- ** originate on a privileged port (< 1024), return a YP_YPERR.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (strstr(key->map, "master.passwd") != NULL &&
- ntohs(rqhost->sin_port) > 1023)
- {
- result.stat = YP_YPERR;
- return &result;
- }
-
- result.val.valdat_len = 0;
- if (result.val.valdat_val)
- {
-#ifdef GNU_YPSERV_ARTIFACT
- /*
- * In general, if you malloc() data in an RPC service
- * routine, you have to free() it the next time that
- * routine is called since the XDR routines won't free
- * it for you. However, in this case, we don't have to
- * do that because the DB routines do garbage collection
- * for us.
- */
- free(result.val.valdat_val);
-#endif
- result.val.valdat_val = NULL;
- }
-
- if (key->domain[0] == '\0' || key->map[0] == '\0')
- result.stat = YP_BADARGS;
- else if (!is_valid_domain(key->domain))
- result.stat = YP_NODOM;
- else
- {
- DBT rdat, qdat;
-
- DB *dbp = open_database(key->domain, key->map);
- if (dbp == NULL)
- result.stat = YP_NOMAP;
- else
- {
- qdat.size = key->key.keydat_len;
- qdat.data = key->key.keydat_val;
-
- result.stat = read_database(dbp, &qdat, NULL, &rdat, F_ALL);
-
- if (result.stat == YP_TRUE)
- {
- result.val.valdat_len = rdat.size;
- result.val.valdat_val = rdat.data;
- }
-
- (void)(dbp->close)(dbp);
- }
- }
-
- if (debug_flag)
- {
- if (result.stat == YP_TRUE)
- Perror("\t-> Value = \"%.*s\"\n",
- (int) result.val.valdat_len,
- result.val.valdat_val);
- else
- Perror("\t-> Error #%d\n", result.stat);
- }
-
-
- /*
- ** Do the jive thing if we didn't find the host in the YP map
- ** and we have enabled the magic DNS lookup stuff.
- **
- ** DNS lookups are handled in a subprocess so that the server
- ** doesn't block while waiting for requests to complete.
- */
- if (result.stat != YP_TRUE && strstr(key->map, "hosts") && dns_flag)
- {
- char *cp = NULL;
-
- if (children < MAX_CHILDREN && fork())
- {
- children++;
- return NULL;
- }
- else
- forked++;
-
- key->key.keydat_val[key->key.keydat_len] = '\0';
-
- if (debug_flag)
- Perror("Doing DNS lookup of %s\n", key->key.keydat_val);
-
- if (strcmp(key->map, "hosts.byname") == 0)
- cp = dnsname(key->key.keydat_val);
- else if (strcmp(key->map, "hosts.byaddr") == 0)
- cp = dnsaddr(key->key.keydat_val);
-
- if (cp)
- {
-
- if (debug_flag)
- Perror("\t-> OK (%s)\n", cp);
-
- result.val.valdat_len = strlen(cp);
- result.val.valdat_val = cp;
- result.stat = YP_TRUE;
- }
- else
- {
- if (debug_flag)
- {
- Perror("\t-> Not Found\n");
- Perror("DNS lookup: %s",strerror(errno));
- }
-
- result.stat = YP_NOKEY;
- }
- }
-
- return &result;
-}
-
-
-
-ypresp_key_val *ypproc_first_2_svc(ypreq_nokey *key,
- struct svc_req *rqstp)
-{
- static ypresp_key_val result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_first(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\tdomainname = \"%s\"\n", key->domain);
- Perror("\tmapname = \"%s\"\n", key->map);
-#if 0
- Perror("\tkeydat = \"%.*s\"\n",
- (int) key->key.keydat_len,
- key->key.keydat_val);
-#endif
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- /*
- ** If this request deals with master.passwd.* and it didn't
- ** originate on a privileged port (< 1024), return a YP_YPERR.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (strstr(key->map, "master.passwd") != NULL &&
- ntohs(rqhost->sin_port) > 1023)
- {
- result.stat = YP_YPERR;
- return &result;
- }
-
- result.key.keydat_len = 0;
- if (result.key.keydat_val)
- {
-#ifdef GNU_YPSERV_ARTIFACT
- free(result.key.keydat_val);
-#endif
- result.key.keydat_val = NULL;
- }
-
- result.val.valdat_len = 0;
- if (result.val.valdat_val)
- {
-#ifdef GNU_YPSERV_ARTIFACT
- free(result.val.valdat_val);
-#endif
- result.val.valdat_val = NULL;
- }
-
- if (key->map[0] == '\0' || key->domain[0] == '\0')
- result.stat = YP_BADARGS;
- else if (!is_valid_domain(key->domain))
- result.stat = YP_NODOM;
- else
- {
- DBT dkey, dval;
-
- DB *dbp = open_database(key->domain, key->map);
- if (dbp == NULL)
- result.stat = YP_NOMAP;
- else
- {
- result.stat = read_database(dbp, NULL, &dkey, &dval, 0);
-
- if (result.stat == YP_TRUE)
- {
- result.key.keydat_len = dkey.size;
- result.key.keydat_val = dkey.data;
-
- result.val.valdat_len = dval.size;
- result.val.valdat_val = dval.data;
- }
-
- (void)(dbp->close)(dbp);
- }
- }
-
- if (debug_flag)
- {
- if (result.stat == YP_TRUE)
- Perror("\t-> Key = \"%.*s\", Value = \"%.*s\"\n",
- (int) result.key.keydat_len,
- result.key.keydat_val,
- (int) result.val.valdat_len,
- result.val.valdat_val);
-
- else
- Perror("\t-> Error #%d\n", result.stat);
- }
-
- return &result;
-}
-
-
-ypresp_key_val *ypproc_next_2_svc(ypreq_key *key,
- struct svc_req *rqstp)
-{
- static ypresp_key_val result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_next(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\tdomainname = \"%s\"\n", key->domain);
- Perror("\tmapname = \"%s\"\n", key->map);
- Perror("\tkeydat = \"%.*s\"\n",
- (int) key->key.keydat_len,
- key->key.keydat_val);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- /*
- ** If this request deals with master.passwd.* and it didn't
- ** originate on a privileged port (< 1024), return a YP_YPERR.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (strstr(key->map, "master.passwd") != NULL &&
- ntohs(rqhost->sin_port) > 1023)
- {
- result.stat = YP_YPERR;
- return &result;
- }
-
- result.key.keydat_len = 0;
- if (result.key.keydat_val)
- {
-#ifdef GNU_YPSERV_ARTIFACT
- free(result.key.keydat_val);
-#endif
- result.key.keydat_val = NULL;
- }
-
- result.val.valdat_len = 0;
- if (result.val.valdat_val)
- {
-#ifdef GNU_YPSERV_ARTIFACT
- free(result.val.valdat_val);
-#endif
- result.val.valdat_val = NULL;
- }
-
- if (key->map[0] == '\0' || key->domain[0] == '\0')
- result.stat = YP_BADARGS;
- else if (!is_valid_domain(key->domain))
- result.stat = YP_NODOM;
- else
- {
- DBT dkey, dval, okey;
-
-
- DB *dbp = open_database(key->domain, key->map);
- if (dbp == NULL)
- result.stat = YP_NOMAP;
- else
- {
- dkey.size = key->key.keydat_len;
- dkey.data = key->key.keydat_val;
-
- result.stat = read_database(dbp, &dkey, &okey, &dval, F_NEXT);
-
- if (result.stat == YP_TRUE)
- {
- result.key.keydat_len = okey.size;
- result.key.keydat_val = okey.data;
-
- result.val.valdat_len = dval.size;
- result.val.valdat_val = dval.data;
- }
- (void)(dbp->close)(dbp);
- }
- }
-
- if (debug_flag)
- {
- if (result.stat == YP_TRUE)
- Perror("\t-> Key = \"%.*s\", Value = \"%.*s\"\n",
- (int) result.key.keydat_len,
- result.key.keydat_val,
- (int) result.val.valdat_len,
- result.val.valdat_val);
- else
- Perror("\t-> Error #%d\n", result.stat);
- }
-
- return &result;
-}
-
-
-
-static void print_ypmap_parms(const struct ypmap_parms *pp)
-{
- Perror("\t\tdomain = \"%s\"\n", pp->domain);
- Perror("\t\tmap = \"%s\"\n", pp->map);
- Perror("\t\tordernum = %u\n", pp->ordernum);
- Perror("\t\tpeer = \"%s\"\n", pp->peer);
-}
-
-
-/*
-** Clean up after child processes signal their termination.
-*/
-void reapchild(sig)
-int sig;
-{
- int st;
-
- while (wait3(&st, WNOHANG, NULL) > 0)
- children--;
-}
-
-/*
-** Stole the ypxfr implementation from the yps package.
-*/
-ypresp_xfr *ypproc_xfr_2_svc(ypreq_xfr *xfr,
- struct svc_req *rqstp)
-{
- static ypresp_xfr result;
- struct sockaddr_in *rqhost;
- char ypxfr_command[MAXPATHLEN];
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_xfr_2_svc(): [From: %s:%d]\n\tmap_parms:\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- print_ypmap_parms(&xfr->map_parms);
- Perror("\t\ttransid = %u\n", xfr->transid);
- Perror("\t\tprog = %u\n", xfr->prog);
- Perror("\t\tport = %u\n", xfr->port);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- /*
- ** If this request originates on a non-privileged port (< 1024),
- ** refuse it. We really only need to guard the master.passwd.*
- ** maps, but what the hell.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (ntohs(rqhost->sin_port) > 1023)
- {
- result.xfrstat = YPXFR_REFUSED;
- return &result;
- }
-
- switch(fork())
- {
- case 0:
- {
- char g[11], t[11], p[11];
-
- sprintf (ypxfr_command, "%s/ypxfr", INSTDIR);
- sprintf (t, "%u", xfr->transid);
- sprintf (g, "%u", xfr->prog);
- sprintf (p, "%u", xfr->port);
- execl(ypxfr_command, "ypxfr", "-d", xfr->map_parms.domain, "-h",
- xfr->map_parms.peer, "-f", "-C", t, g,
- inet_ntoa(rqhost->sin_addr), p, xfr->map_parms.map, NULL);
- Perror("ypxfr execl(): %s",strerror(errno));
- exit(0);
- }
- case -1:
- Perror("fork(): %s",strerror(errno));
- result.xfrstat = YPXFR_XFRERR;
- default:
- {
- result.xfrstat = YPXFR_SUCC;
- break;
- }
- }
-
- result.transid = xfr->transid;
- return &result;
-}
-
-
-void *ypproc_clear_2_svc(void *dummy,
- struct svc_req *rqstp)
-{
- static int foo;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- Perror("ypproc_clear_2_svc() [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- return (void *) &foo;
-}
-
-
-static int ypall_close(void *data)
-{
- DB *locptr;
-
- if (debug_flag && data == NULL)
- {
- Perror("ypall_close() called with NULL pointer.\n");
- return 0;
- }
-
- locptr = (DB *)data;
- (void)(locptr->close)(locptr);
- return 0;
-}
-
-
-static int ypall_encode(ypresp_key_val *val,
- void *data)
-{
- DBT dkey, dval, okey;
-
- dkey.data = val->key.keydat_val;
- dkey.size = val->key.keydat_len;
-
- val->stat = read_database((DB *) data, &dkey, &okey, &dval, F_NEXT | F_YPALL);
-
- if (val->stat == YP_TRUE)
- {
- val->key.keydat_val = okey.data;
- val->key.keydat_len = okey.size;
-
- val->val.valdat_val = dval.data;
- val->val.valdat_len = dval.size;
- }
-
-
- return val->stat;
-}
-
-
-ypresp_all *ypproc_all_2_svc(ypreq_nokey *nokey,
- struct svc_req *rqstp)
-{
- static ypresp_all result;
- extern __xdr_ypall_cb_t __xdr_ypall_cb;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_all_2_svc(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\t\tdomain = \"%s\"\n", nokey->domain);
- Perror("\t\tmap = \"%s\"\n", nokey->map);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- if (children < MAX_CHILDREN && fork())
- {
- children++;
- return NULL;
- }
- else
- forked++;
-
- __xdr_ypall_cb.u.encode = NULL;
- __xdr_ypall_cb.u.close = NULL;
- __xdr_ypall_cb.data = NULL;
-
- result.more = TRUE;
-
- /*
- ** If this request deals with master.passwd.* and it didn't
- ** originate on a privileged port (< 1024), return a YP_YPERR.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (strstr(nokey->map, "master.passwd") != NULL &&
- ntohs(rqhost->sin_port) > 1023)
- {
- result.ypresp_all_u.val.stat = YP_YPERR;
- return &result;
- }
-
- if (nokey->map[0] == '\0' || nokey->domain[0] == '\0')
- result.ypresp_all_u.val.stat = YP_BADARGS;
- else if (!is_valid_domain(nokey->domain))
- result.ypresp_all_u.val.stat = YP_NODOM;
- else
- {
- DBT dkey, dval;
-
- DB *dbp = open_database(nokey->domain, nokey->map);
- if (dbp == NULL)
- result.ypresp_all_u.val.stat = YP_NOMAP;
- else
- {
- result.ypresp_all_u.val.stat = read_database(dbp,
- NULL,
- &dkey,
- &dval,
- 0);
-
- if (result.ypresp_all_u.val.stat == YP_TRUE)
- {
- result.ypresp_all_u.val.key.keydat_len = dkey.size;
- result.ypresp_all_u.val.key.keydat_val = dkey.data;
-
- result.ypresp_all_u.val.val.valdat_len = dval.size;
- result.ypresp_all_u.val.val.valdat_val = dval.data;
-
- __xdr_ypall_cb.u.encode = ypall_encode;
- __xdr_ypall_cb.u.close = ypall_close;
- __xdr_ypall_cb.data = (void *) dbp;
-
- return &result;
- }
-
- (void)(dbp->close)(dbp);
- }
- }
-
- return &result;
-}
-
-
-ypresp_master *ypproc_master_2_svc(ypreq_nokey *nokey,
- struct svc_req *rqstp)
-{
- static ypresp_master result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_master_2_svc(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\t\tdomain = \"%s\"\n", nokey->domain);
- Perror("\t\tmap = \"%s\"\n", nokey->map);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- /*
- ** If this request deals with master.passwd.* and it didn't
- ** originate on a privileged port (< 1024), return a YP_YPERR.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (strstr(nokey->map, "master.passwd") != NULL &&
- ntohs(rqhost->sin_port) > 1023)
- {
- result.stat = YP_YPERR;
- return &result;
- }
-
- if (result.peer)
- {
-#ifdef GNU_YPSERV_ARTIFACT
- free(result.peer);
-#endif
- result.peer = NULL;
- }
-
- if (nokey->domain[0] == '\0')
- result.stat = YP_BADARGS;
- else if (!is_valid_domain(nokey->domain))
- result.stat = YP_NODOM;
- else
- {
- DB *dbp = open_database(nokey->domain, nokey->map);
- if (dbp == NULL)
- result.stat = YP_NOMAP;
- else
- {
- DBT key, val;
-
- key.size = sizeof("YP_MASTER_NAME")-1;
- key.data = "YP_MASTER_NAME";
-
- if ((dbp->get)(dbp,&key,&val,0))
- {
- /* No YP_MASTER_NAME record in map? Assume we are Master */
- static char hostbuf[1025];
-
- gethostname((char *)&hostbuf, sizeof(hostbuf)-1);
- Perror("Hostname: [%s]",hostbuf);
- result.peer = strdup(hostbuf);
- }
- else
- {
- *(((char *)val.data)+val.size) = '\0';
- result.peer = val.data;
- }
-
- result.stat = YP_TRUE;
- (void)(dbp->close)(dbp);
- }
- }
-
- if (result.peer == NULL)
- result.peer = strdup("");
-
- if (debug_flag)
- Perror("\t-> Peer = \"%s\"\n", result.peer);
-
- return &result;
-}
-
-
-ypresp_order *ypproc_order_2_svc(ypreq_nokey *nokey,
- struct svc_req *rqstp)
-{
- static ypresp_order result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_order_2_svc(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\t\tdomain = \"%s\"\n", nokey->domain);
- Perror("\t\tmap = \"%s\"\n", nokey->map);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- /*
- ** If this request deals with master.passwd.* and it didn't
- ** originate on a privileged port (< 1024), return a YP_YPERR.
- ** This is our half-assed way of preventing non-root users
- ** on NIS clients from getting at the real password map. Bah.
- */
-
- if (strstr(nokey->map, "master.passwd") != NULL &&
- ntohs(rqhost->sin_port) > 1023)
- {
- result.stat = YP_YPERR;
- return &result;
- }
-
- result.ordernum = 0;
-
- if (nokey->domain[0] == '\0')
- result.stat = YP_BADARGS;
- else if (!is_valid_domain(nokey->domain))
- result.stat = YP_NODOM;
- else
- {
- DB *dbp = open_database(nokey->domain, nokey->map);
- if (dbp == NULL)
- result.stat = YP_NOMAP;
- else
- {
- DBT key, val;
-
- key.size = sizeof("YP_LAST_MODIFIED")-1;
- key.data = "YP_LAST_MODIFIED";
-
- if ((dbp->get)(dbp,&key,&val,0))
- {
- /* No YP_LAST_MODIFIED record in map? Use DTM timestamp.. */
- result.ordernum = get_dtm(nokey->domain, nokey->map);
- }
- else
- {
- result.ordernum = atoi(val.data);
-#ifdef GNU_YPSERV_ARTIFACT
- free(val.data);
-#endif
- }
-
- result.stat = YP_TRUE;
- (void)(dbp->close)(dbp);
- }
- }
-
- if (debug_flag)
- Perror("-> Order # %d\n", result.ordernum);
-
- return &result;
-}
-
-
-static void free_maplist(ypmaplist *mlp)
-{
- ypmaplist *next;
-
- while (mlp != NULL)
- {
- next = mlp->next;
- free(mlp->map);
- free(mlp);
- mlp = next;
- }
-}
-
-static int add_maplist(ypmaplist **mlhp,
- char *map)
-{
- ypmaplist *mlp;
-
- if (!strncmp(map, ".", strlen(map)) || !strncmp(map, "..", strlen(map)))
- return 0;
-
- mlp = malloc(sizeof(*mlp));
- if (mlp == NULL)
- return -1;
-
- mlp->map = strdup(map);
- if (mlp->map == NULL)
- {
- free(mlp);
- return -1;
- }
-
- mlp->next = *mlhp;
- *mlhp = mlp;
-
- return 0;
-}
-
-
-ypresp_maplist *ypproc_maplist_2_svc(domainname *name,
- struct svc_req *rqstp)
-{
- static ypresp_maplist result;
- struct sockaddr_in *rqhost;
-
-
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
- if (debug_flag)
- {
- Perror("ypproc_maplist_2_svc(): [From: %s:%d]\n",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
-
- Perror("\t\tdomain = \"%s\"\n", *name);
- }
-
- if (!is_valid_host(rqhost))
- {
- if (debug_flag)
- Perror("\t-> Ignored (not a valid source host)\n");
-
- return NULL;
- }
-
- if (result.maps)
- free_maplist(result.maps);
-
- result.maps = NULL;
-
- if ((*name)[0] == '\0')
- result.stat = YP_BADARGS;
- else if (!is_valid_domain(*name))
- result.stat = YP_NODOM;
- else
- {
- DIR *dp;
- char dirname[MAXPATHLEN];
-
- sprintf(dirname,"./%s",*name);
- dp = opendir(dirname);
- if (dp == NULL)
- {
- if (debug_flag)
- {
- Perror("%s: opendir: %s", progname,strerror(errno));
- }
-
- result.stat = YP_BADDB;
- }
- else
- {
- struct dirent *dep;
-
- while ((dep = readdir(dp)) != NULL)
- if (add_maplist(&result.maps, dep->d_name) < 0)
- {
- result.stat = YP_YPERR;
- break;
- }
- closedir(dp);
- result.stat = YP_TRUE;
- }
- }
-
- if (debug_flag)
- {
- if (result.stat == YP_TRUE)
- {
- ypmaplist *p;
-
- p = result.maps;
- Perror("-> ");
- while (p->next)
- {
- Perror("%s,", p->map);
- p = p->next;
- }
- putc('\n', stderr);
- }
- else
- Perror("\t-> Error #%d\n", result.stat);
- }
-
- return &result;
-}