xref: /freebsd/crypto/krb5/src/lib/rpc/clnt_simple.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /* @(#)clnt_simple.c	2.2 88/08/01 4.0 RPCSRC */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert  * Copyright (c) 2010, Oracle America, Inc.
4*7f2fe78bSCy Schubert  *
5*7f2fe78bSCy Schubert  * All rights reserved.
6*7f2fe78bSCy Schubert  *
7*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions are met:
9*7f2fe78bSCy Schubert  *
10*7f2fe78bSCy Schubert  *     * Redistributions of source code must retain the above copyright
11*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer.
12*7f2fe78bSCy Schubert  *
13*7f2fe78bSCy Schubert  *     * Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer in
15*7f2fe78bSCy Schubert  *       the documentation and/or other materials provided with the
16*7f2fe78bSCy Schubert  *       distribution.
17*7f2fe78bSCy Schubert  *
18*7f2fe78bSCy Schubert  *     * Neither the name of the "Oracle America, Inc." nor the names of
19*7f2fe78bSCy Schubert  *       its contributors may be used to endorse or promote products
20*7f2fe78bSCy Schubert  *       derived from this software without specific prior written permission.
21*7f2fe78bSCy Schubert  *
22*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*7f2fe78bSCy Schubert  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*7f2fe78bSCy Schubert  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25*7f2fe78bSCy Schubert  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*7f2fe78bSCy Schubert  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*7f2fe78bSCy Schubert  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28*7f2fe78bSCy Schubert  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*7f2fe78bSCy Schubert  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert  */
34*7f2fe78bSCy Schubert #if !defined(lint) && defined(SCCSIDS)
35*7f2fe78bSCy Schubert static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
36*7f2fe78bSCy Schubert #endif
37*7f2fe78bSCy Schubert 
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert  * clnt_simple.c
40*7f2fe78bSCy Schubert  * Simplified front end to rpc.
41*7f2fe78bSCy Schubert  */
42*7f2fe78bSCy Schubert 
43*7f2fe78bSCy Schubert #include "autoconf.h"
44*7f2fe78bSCy Schubert #include <stdio.h>
45*7f2fe78bSCy Schubert /* for close() */
46*7f2fe78bSCy Schubert #include <unistd.h>
47*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
48*7f2fe78bSCy Schubert #include <sys/socket.h>
49*7f2fe78bSCy Schubert #include <netdb.h>
50*7f2fe78bSCy Schubert #include <string.h>
51*7f2fe78bSCy Schubert #include <port-sockets.h>
52*7f2fe78bSCy Schubert 
53*7f2fe78bSCy Schubert static struct callrpc_private {
54*7f2fe78bSCy Schubert 	CLIENT	*client;
55*7f2fe78bSCy Schubert         SOCKET  socket;
56*7f2fe78bSCy Schubert 	rpcprog_t oldprognum;
57*7f2fe78bSCy Schubert 	rpcvers_t oldversnum;
58*7f2fe78bSCy Schubert 	int	valid;
59*7f2fe78bSCy Schubert 	char	*oldhost;
60*7f2fe78bSCy Schubert } *callrpc_private;
61*7f2fe78bSCy Schubert 
62*7f2fe78bSCy Schubert int
callrpc(char * host,rpcprog_t prognum,rpcvers_t versnum,rpcproc_t procnum,xdrproc_t inproc,char * in,xdrproc_t outproc,char * out)63*7f2fe78bSCy Schubert callrpc(
64*7f2fe78bSCy Schubert 	char *host,
65*7f2fe78bSCy Schubert 	rpcprog_t prognum,
66*7f2fe78bSCy Schubert 	rpcvers_t versnum,
67*7f2fe78bSCy Schubert 	rpcproc_t procnum,
68*7f2fe78bSCy Schubert 	xdrproc_t inproc,
69*7f2fe78bSCy Schubert 	char *in,
70*7f2fe78bSCy Schubert 	xdrproc_t outproc,
71*7f2fe78bSCy Schubert 	char *out)
72*7f2fe78bSCy Schubert {
73*7f2fe78bSCy Schubert 	struct callrpc_private *crp = callrpc_private;
74*7f2fe78bSCy Schubert 	struct sockaddr_in server_addr;
75*7f2fe78bSCy Schubert 	enum clnt_stat clnt_stat;
76*7f2fe78bSCy Schubert 	struct hostent *hp;
77*7f2fe78bSCy Schubert 	struct timeval timeout, tottimeout;
78*7f2fe78bSCy Schubert 
79*7f2fe78bSCy Schubert 	if (crp == 0) {
80*7f2fe78bSCy Schubert 		crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
81*7f2fe78bSCy Schubert 		if (crp == 0)
82*7f2fe78bSCy Schubert 			return (0);
83*7f2fe78bSCy Schubert 		callrpc_private = crp;
84*7f2fe78bSCy Schubert 	}
85*7f2fe78bSCy Schubert 	if (crp->oldhost == NULL) {
86*7f2fe78bSCy Schubert 		crp->oldhost = mem_alloc(256);
87*7f2fe78bSCy Schubert 		if (crp->oldhost == 0)
88*7f2fe78bSCy Schubert 		    return 0;
89*7f2fe78bSCy Schubert 		crp->oldhost[0] = 0;
90*7f2fe78bSCy Schubert 		crp->socket = RPC_ANYSOCK;
91*7f2fe78bSCy Schubert 	}
92*7f2fe78bSCy Schubert 	if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
93*7f2fe78bSCy Schubert 		&& strcmp(crp->oldhost, host) == 0) {
94*7f2fe78bSCy Schubert 		/* reuse old client */
95*7f2fe78bSCy Schubert 	} else {
96*7f2fe78bSCy Schubert 		crp->valid = 0;
97*7f2fe78bSCy Schubert                 (void)closesocket(crp->socket);
98*7f2fe78bSCy Schubert 		crp->socket = RPC_ANYSOCK;
99*7f2fe78bSCy Schubert 		if (crp->client) {
100*7f2fe78bSCy Schubert 			clnt_destroy(crp->client);
101*7f2fe78bSCy Schubert 			crp->client = NULL;
102*7f2fe78bSCy Schubert 		}
103*7f2fe78bSCy Schubert 		if ((hp = gethostbyname(host)) == NULL)
104*7f2fe78bSCy Schubert 			return ((int) RPC_UNKNOWNHOST);
105*7f2fe78bSCy Schubert 		timeout.tv_usec = 0;
106*7f2fe78bSCy Schubert 		timeout.tv_sec = 5;
107*7f2fe78bSCy Schubert 		memset(&server_addr, 0, sizeof(server_addr));
108*7f2fe78bSCy Schubert 		memmove((char *)&server_addr.sin_addr, hp->h_addr,
109*7f2fe78bSCy Schubert 			sizeof(server_addr.sin_addr));
110*7f2fe78bSCy Schubert 		server_addr.sin_family = AF_INET;
111*7f2fe78bSCy Schubert 		server_addr.sin_port =  0;
112*7f2fe78bSCy Schubert 		if ((crp->client = clntudp_create(&server_addr, prognum,
113*7f2fe78bSCy Schubert 		    versnum, timeout, &crp->socket)) == NULL)
114*7f2fe78bSCy Schubert 			return ((int) rpc_createerr.cf_stat);
115*7f2fe78bSCy Schubert 		crp->valid = 1;
116*7f2fe78bSCy Schubert 		crp->oldprognum = prognum;
117*7f2fe78bSCy Schubert 		crp->oldversnum = versnum;
118*7f2fe78bSCy Schubert 		(void) strncpy(crp->oldhost, host, 255);
119*7f2fe78bSCy Schubert 		crp->oldhost[255] = '\0';
120*7f2fe78bSCy Schubert 	}
121*7f2fe78bSCy Schubert 	tottimeout.tv_sec = 25;
122*7f2fe78bSCy Schubert 	tottimeout.tv_usec = 0;
123*7f2fe78bSCy Schubert 	clnt_stat = clnt_call(crp->client, procnum, inproc, in,
124*7f2fe78bSCy Schubert 	    outproc, out, tottimeout);
125*7f2fe78bSCy Schubert 	/*
126*7f2fe78bSCy Schubert 	 * if call failed, empty cache
127*7f2fe78bSCy Schubert 	 */
128*7f2fe78bSCy Schubert 	if (clnt_stat != RPC_SUCCESS)
129*7f2fe78bSCy Schubert 		crp->valid = 0;
130*7f2fe78bSCy Schubert 	return ((int) clnt_stat);
131*7f2fe78bSCy Schubert }
132