⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portmap.c

📁 当你重新编译了EM85XX的交叉编译工具以支持SUNRPC时
💻 C
📖 第 1 页 / 共 2 页
字号:
	deny_severity = LOG_WARNING;	if (debugging)		(void) fprintf(stderr, "server: about do a switch\n");	switch (rqstp->rq_proc) {	case PMAPPROC_NULL:		/*		 * Null proc call		 */		/* remote host authorization check */		check_default(svc_getcaller(xprt), rqstp->rq_proc, (u_long) 0);		if (!svc_sendreply(xprt, (xdrproc_t) xdr_void, (caddr_t)0)		    && debugging) {			abort();		}		break;	case PMAPPROC_SET:		/*		 * Set a program,version to port mapping		 */		if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))			svcerr_decode(xprt);		else {			/* reject non-local requests, protect priv. ports */			if (!CHECK_SETUNSET(xprt, ludpxprt, ltcpxprt,			    rqstp->rq_proc, reg.pm_prog, reg.pm_port)) {				ans = 0;				goto done;			} 			/*			 * check to see if already used			 * find_service returns a hit even if			 * the versions don't match, so check for it			 */			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);			if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {				if (fnd->pml_map.pm_port == reg.pm_port) {					ans = 1;					goto done;				}				else {					ans = 0;					goto done;				}			} else {				/* 				 * add to END of list				 */				fpml = (struct flagged_pml *)				    malloc((u_int)sizeof(struct flagged_pml));				pml = &fpml->pml;				fpml->priv =					(ntohs(svc_getcaller(xprt)->sin_port)					 < IPPORT_RESERVED);				pml->pml_map = reg;				pml->pml_next = 0;				if (pmaplist == 0) {					pmaplist = pml;				} else {					for (fnd= pmaplist; fnd->pml_next != 0;					    fnd = fnd->pml_next);					fnd->pml_next = pml;				}				ans = 1;				dump_table();			}		done:			if ((!svc_sendreply(xprt, (xdrproc_t)xdr_int,					    (caddr_t)&ans)) &&			    debugging) {				(void) fprintf(stderr, "svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_UNSET:		/*		 * Remove a program,version to port mapping.		 */		if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&reg))			svcerr_decode(xprt);		else {			ans = 0;			/* reject non-local requests */			if (!CHECK_SETUNSET(xprt, ludpxprt, ltcpxprt,			    rqstp->rq_proc, reg.pm_prog, (u_long) 0))				goto done;			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {				if ((pml->pml_map.pm_prog != reg.pm_prog) ||					(pml->pml_map.pm_vers != reg.pm_vers)) {					/* both pml & prevpml move forwards */					prevpml = pml;					pml = pml->pml_next;					continue;				}				/* found it; pml moves forward, prevpml stays */				/* privileged port check */				if (!check_privileged_port(svc_getcaller(xprt), 				    rqstp->rq_proc, 				    reg.pm_prog, 				    pml->pml_map.pm_port)) {					ans = 0;					break;				}				fpml = (struct flagged_pml*)pml;				if (fpml->priv &&				    (ntohs(svc_getcaller(xprt)->sin_port)				     >= IPPORT_RESERVED)) {					ans = 0;					break;				}				ans = 1;				t = (caddr_t)pml;				pml = pml->pml_next;				if (prevpml == NULL)					pmaplist = pml;				else					prevpml->pml_next = pml;				free(t);				dump_table();			}			if ((!svc_sendreply(xprt, (xdrproc_t)xdr_int,					    (caddr_t)&ans)) &&			    debugging) {				(void) fprintf(stderr, "svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_GETPORT:		/*		 * Lookup the mapping for a program,version and return its port		 */		if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&reg))			svcerr_decode(xprt);		else {			/* remote host authorization check */			if (!check_default(svc_getcaller(xprt), 			    rqstp->rq_proc, 			    reg.pm_prog)) {				ans = 0;				goto done;			}			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);			if (fnd)				port = fnd->pml_map.pm_port;			else				port = 0;			if ((!svc_sendreply(xprt, (xdrproc_t)xdr_int,					    (caddr_t)&port)) &&			    debugging) {				(void) fprintf(stderr, "svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_DUMP:		/*		 * Return the current set of mapped program,version		 */		if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL))			svcerr_decode(xprt);		else {			/* remote host authorization check */			struct pmaplist *p;			if (!check_default(svc_getcaller(xprt), 			    rqstp->rq_proc, (u_long) 0)) {				p = 0;	/* send empty list */			} else {				p = pmaplist;			}			if ((!svc_sendreply(xprt, (xdrproc_t)xdr_pmaplist,			    (caddr_t)&p)) && debugging) {				(void) fprintf(stderr, "svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_CALLIT:		/*		 * Calls a procedure on the local machine.  If the requested		 * procedure is not registered this procedure does not return		 * error information!!		 * This procedure is only supported on rpc/udp and calls via 		 * rpc/udp.  It passes null authentication parameters.		 */		callit(rqstp, xprt);		break;	default:		/* remote host authorization check */		check_default(svc_getcaller(xprt), rqstp->rq_proc, (u_long) 0);		svcerr_noproc(xprt);		break;	}}/* * Stuff for the rmtcall service */#define ARGSIZE 9000struct encap_parms {	u_int arglen;	char *args;};static bool_txdr_encap_parms(XDR *xdrs, struct encap_parms *epp){	return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));}struct rmtcallargs {	u_long	rmt_prog;	u_long	rmt_vers;	u_long	rmt_port;	u_long	rmt_proc;	struct encap_parms rmt_args;};static bool_txdr_rmtcall_args(XDR *xdrs, struct rmtcallargs *cap){	/* does not get a port number */	if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&	    xdr_u_long(xdrs, &(cap->rmt_vers)) &&	    xdr_u_long(xdrs, &(cap->rmt_proc))) {		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));	}	return (FALSE);}static bool_txdr_rmtcall_result(XDR *xdrs, struct rmtcallargs *cap){	if (xdr_u_long(xdrs, &(cap->rmt_port)))		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));	return (FALSE);}/* * only worries about the struct encap_parms part of struct rmtcallargs. * The arglen must already be set!! */static bool_txdr_opaque_parms(XDR *xdrs, struct rmtcallargs *cap){	return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));}/* * This routine finds and sets the length of incoming opaque paraters * and then calls xdr_opaque_parms. */static bool_txdr_len_opaque_parms(XDR *xdrs, struct rmtcallargs *cap){	u_int beginpos, lowpos, highpos, currpos, pos;	beginpos = lowpos = pos = xdr_getpos(xdrs);	highpos = lowpos + ARGSIZE;	while ((int)(highpos - lowpos) >= 0) {		currpos = (lowpos + highpos) / 2;		if (xdr_setpos(xdrs, currpos)) {			pos = currpos;			lowpos = currpos + 1;		} else {			highpos = currpos - 1;		}	}	xdr_setpos(xdrs, beginpos);	cap->rmt_args.arglen = pos - beginpos;	return (xdr_opaque_parms(xdrs, cap));}/* * Call a remote procedure service * This procedure is very quiet when things go wrong. * The proc is written to support broadcast rpc.  In the broadcast case, * a machine should shut-up instead of complain, less the requestor be * overrun with complaints at the expense of not hearing a valid reply ... * * This now forks so that the program & process that it calls can call  * back to the portmapper. */static void callit(struct svc_req *rqstp, SVCXPRT *xprt){	struct rmtcallargs a;	struct pmaplist *pml;	u_short port;	struct sockaddr_in me;	int pid, so = -1;	CLIENT *client;	struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;	struct timeval timeout;	char buf[ARGSIZE];	timeout.tv_sec = 5;	timeout.tv_usec = 0;	a.rmt_args.args = buf;	if (!svc_getargs(xprt, (xdrproc_t)xdr_rmtcall_args, (caddr_t)&a))		return;	/* host and service access control */	if (!check_callit(svc_getcaller(xprt), 	    rqstp->rq_proc, a.rmt_prog, a.rmt_proc))		return;	if ((pml = find_service(a.rmt_prog, a.rmt_vers,	    (u_long)IPPROTO_UDP)) == NULL)		return;	/*	 * fork a child to do the work.  Parent immediately returns.	 * Child exits upon completion.	 */	if ((pid = fork()) != 0) {		if (pid < 0)			syslog(LOG_ERR, "CALLIT (prog %lu): fork: %m",			    a.rmt_prog);		return;	}	port = pml->pml_map.pm_port;	get_myaddress(&me);	me.sin_port = htons(port);	client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &so);	if (client != (CLIENT *)NULL) {		if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {			client->cl_auth = authunix_create(au->aup_machname,			   au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);		}		a.rmt_port = (u_long)port;		if (clnt_call(client, a.rmt_proc, (xdrproc_t)xdr_opaque_parms,			      (caddr_t)&a, (xdrproc_t)xdr_len_opaque_parms,			      (caddr_t)&a, timeout) == RPC_SUCCESS) {			svc_sendreply(xprt, (xdrproc_t)xdr_rmtcall_result,				      (caddr_t)&a);		}		AUTH_DESTROY(client->cl_auth);		clnt_destroy(client);	}	(void)close(so);	exit(0);}#ifndef IGNORE_SIGCHLD			/* Lionel Cons <cons@dxcern.cern.ch> */static void reap(int ignore){	int save_errno = errno;	while (wait3((int *)NULL, WNOHANG, (struct rusage *)NULL) > 0);	errno = save_errno;}#endif/* Dump and restore mapping table so that we can survive kill/restart. * To cope with chroot, an fd is opened early and we just write to that. * If we are killed while writing the file, we lose, but that isn't * very likely... */static void dump_table(void){	FILE *f;	struct pmaplist *pml;	if (store_fd < 0)		return;	ftruncate(store_fd, 0);	lseek(store_fd, 0, 0);	f = fdopen(dup(store_fd), "w");	if (!f)		return;	for (pml = pmaplist ; pml ; pml = pml->pml_next) {		struct flagged_pml *fpml = (struct flagged_pml*)pml;		fprintf(f, "%lu %lu %lu %lu %d\n",			pml->pml_map.pm_prog,			pml->pml_map.pm_vers,			pml->pml_map.pm_prot,			pml->pml_map.pm_port,			fpml->priv);	}	fclose(f);}static void load_table(void){	FILE *f;	struct pmaplist **ep;	struct flagged_pml fpml, *fpmlp;	ep = &pmaplist;	while ((*ep)->pml_next)		ep = & (*ep)->pml_next;	if (store_fd < 0)		return;	lseek(store_fd, 0, 0);	f = fdopen(dup(store_fd), "r");	if (f == NULL)		return;	while (fscanf(f, "%lu %lu %lu %lu %d\n",		      &fpml.pml.pml_map.pm_prog,		      &fpml.pml.pml_map.pm_vers,		      &fpml.pml.pml_map.pm_prot,		      &fpml.pml.pml_map.pm_port,		      &fpml.priv) == 5) {		if (fpml.pml.pml_map.pm_port == PMAPPORT)			continue;		fpmlp = malloc(sizeof(struct flagged_pml));		if (!fpmlp)			break;		*fpmlp = fpml;		*ep = &fpmlp->pml;		ep = &fpmlp->pml.pml_next;		*ep = NULL;	}	fclose(f);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -