Localize rpcgen
[platform/upstream/glibc.git] / sunrpc / clnt_unix.c
1 /*
2  * clnt_unix.c, Implements a TCP/IP based, client side RPC.
3  *
4  * Copyright (c) 2010, Oracle America, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  *       copyright notice, this list of conditions and the following
14  *       disclaimer in the documentation and/or other materials
15  *       provided with the distribution.
16  *     * Neither the name of the "Oracle America, Inc." nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * TCP based RPC supports 'batched calls'.
34  * A sequence of calls may be batched-up in a send buffer.  The rpc call
35  * return immediately to the client even though the call was not necessarily
36  * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
37  * the rpc timeout value is zero (see clnt.h, rpc).
38  *
39  * Clients should NOT casually batch calls that in fact return results; that is,
40  * the server side should be aware that a call is batched and not produce any
41  * return message.  Batched calls that produce many result messages can
42  * deadlock (netlock) the client and the server....
43  *
44  * Now go hang yourself.
45  */
46
47 #include <netdb.h>
48 #include <errno.h>
49 #include <stdio.h>
50 #include <unistd.h>
51 #include <libintl.h>
52 #include <rpc/rpc.h>
53 #include <sys/uio.h>
54 #include <sys/poll.h>
55 #include <sys/socket.h>
56 #include <rpc/pmap_clnt.h>
57 #include <wchar.h>
58
59 extern u_long _create_xid (void);
60
61 #define MCALL_MSG_SIZE 24
62
63 struct ct_data
64   {
65     int ct_sock;
66     bool_t ct_closeit;
67     struct timeval ct_wait;
68     bool_t ct_waitset;          /* wait set by clnt_control? */
69     struct sockaddr_un ct_addr;
70     struct rpc_err ct_error;
71     char ct_mcall[MCALL_MSG_SIZE];      /* marshalled callmsg */
72     u_int ct_mpos;              /* pos after marshal */
73     XDR ct_xdrs;
74   };
75
76 static int readunix (char *, char *, int);
77 static int writeunix (char *, char *, int);
78
79 static enum clnt_stat clntunix_call (CLIENT *, u_long, xdrproc_t, caddr_t,
80                                     xdrproc_t, caddr_t, struct timeval);
81 static void clntunix_abort (void);
82 static void clntunix_geterr (CLIENT *, struct rpc_err *);
83 static bool_t clntunix_freeres (CLIENT *, xdrproc_t, caddr_t);
84 static bool_t clntunix_control (CLIENT *, int, char *);
85 static void clntunix_destroy (CLIENT *);
86
87 static const struct clnt_ops unix_ops =
88 {
89   clntunix_call,
90   clntunix_abort,
91   clntunix_geterr,
92   clntunix_freeres,
93   clntunix_destroy,
94   clntunix_control
95 };
96
97 /*
98  * Create a client handle for a tcp/ip connection.
99  * If *sockp<0, *sockp is set to a newly created TCP socket and it is
100  * connected to raddr.  If *sockp non-negative then
101  * raddr is ignored.  The rpc/tcp package does buffering
102  * similar to stdio, so the client must pick send and receive buffer sizes,];
103  * 0 => use the default.
104  * If raddr->sin_port is 0, then a binder on the remote machine is
105  * consulted for the right port number.
106  * NB: *sockp is copied into a private area.
107  * NB: It is the clients responsibility to close *sockp.
108  * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
109  * something more useful.
110  */
111 CLIENT *
112 clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
113                  int *sockp, u_int sendsz, u_int recvsz)
114 {
115   CLIENT *h;
116   struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct));
117   struct rpc_msg call_msg;
118   int len;
119
120   h = (CLIENT *) mem_alloc (sizeof (*h));
121   if (h == NULL || ct == NULL)
122     {
123       struct rpc_createerr *ce = &get_rpc_createerr ();
124       (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
125       ce->cf_stat = RPC_SYSTEMERROR;
126       ce->cf_error.re_errno = ENOMEM;
127       goto fooy;
128     }
129
130   /*
131    * If no socket given, open one
132    */
133   if (*sockp < 0)
134     {
135       *sockp = __socket (AF_UNIX, SOCK_STREAM, 0);
136       len = strlen (raddr->sun_path) + sizeof (raddr->sun_family) + 1;
137       if (*sockp < 0
138           || __connect (*sockp, (struct sockaddr *) raddr, len) < 0)
139         {
140           struct rpc_createerr *ce = &get_rpc_createerr ();
141           ce->cf_stat = RPC_SYSTEMERROR;
142           ce->cf_error.re_errno = errno;
143           if (*sockp != -1)
144             __close (*sockp);
145           goto fooy;
146         }
147       ct->ct_closeit = TRUE;
148     }
149   else
150     {
151       ct->ct_closeit = FALSE;
152     }
153
154   /*
155    * Set up private data struct
156    */
157   ct->ct_sock = *sockp;
158   ct->ct_wait.tv_usec = 0;
159   ct->ct_waitset = FALSE;
160   ct->ct_addr = *raddr;
161
162   /*
163    * Initialize call message
164    */
165   call_msg.rm_xid = _create_xid ();
166   call_msg.rm_direction = CALL;
167   call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
168   call_msg.rm_call.cb_prog = prog;
169   call_msg.rm_call.cb_vers = vers;
170
171   /*
172    * pre-serialize the static part of the call msg and stash it away
173    */
174   xdrmem_create (&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, XDR_ENCODE);
175   if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg))
176     {
177       if (ct->ct_closeit)
178         __close (*sockp);
179       goto fooy;
180     }
181   ct->ct_mpos = XDR_GETPOS (&(ct->ct_xdrs));
182   XDR_DESTROY (&(ct->ct_xdrs));
183
184   /*
185    * Create a client handle which uses xdrrec for serialization
186    * and authnone for authentication.
187    */
188   xdrrec_create (&(ct->ct_xdrs), sendsz, recvsz,
189                  (caddr_t) ct, readunix, writeunix);
190   h->cl_ops = (struct clnt_ops *) &unix_ops;
191   h->cl_private = (caddr_t) ct;
192   h->cl_auth = authnone_create ();
193   return h;
194
195 fooy:
196   /*
197    * Something goofed, free stuff and barf
198    */
199   mem_free ((caddr_t) ct, sizeof (struct ct_data));
200   mem_free ((caddr_t) h, sizeof (CLIENT));
201   return (CLIENT *) NULL;
202 }
203 libc_hidden_nolink_sunrpc (clntunix_create, GLIBC_2_1)
204
205 static enum clnt_stat
206 clntunix_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
207      CLIENT *h;
208      u_long proc;
209      xdrproc_t xdr_args;
210      caddr_t args_ptr;
211      xdrproc_t xdr_results;
212      caddr_t results_ptr;
213      struct timeval timeout;
214 {
215   struct ct_data *ct = (struct ct_data *) h->cl_private;
216   XDR *xdrs = &(ct->ct_xdrs);
217   struct rpc_msg reply_msg;
218   u_long x_id;
219   u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall);   /* yuk */
220   bool_t shipnow;
221   int refreshes = 2;
222
223   if (!ct->ct_waitset)
224     {
225       ct->ct_wait = timeout;
226     }
227
228   shipnow =
229     (xdr_results == (xdrproc_t) 0 && ct->ct_wait.tv_sec == 0
230      && ct->ct_wait.tv_usec == 0) ? FALSE : TRUE;
231
232 call_again:
233   xdrs->x_op = XDR_ENCODE;
234   ct->ct_error.re_status = RPC_SUCCESS;
235   x_id = ntohl (--(*msg_x_id));
236   if ((!XDR_PUTBYTES (xdrs, ct->ct_mcall, ct->ct_mpos)) ||
237       (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
238       (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
239       (!(*xdr_args) (xdrs, args_ptr)))
240     {
241       if (ct->ct_error.re_status == RPC_SUCCESS)
242         ct->ct_error.re_status = RPC_CANTENCODEARGS;
243       (void) xdrrec_endofrecord (xdrs, TRUE);
244       return ct->ct_error.re_status;
245     }
246   if (!xdrrec_endofrecord (xdrs, shipnow))
247     return ct->ct_error.re_status = RPC_CANTSEND;
248   if (!shipnow)
249     return RPC_SUCCESS;
250   /*
251    * Hack to provide rpc-based message passing
252    */
253   if (ct->ct_wait.tv_sec == 0 && ct->ct_wait.tv_usec == 0)
254     return ct->ct_error.re_status = RPC_TIMEDOUT;
255
256
257   /*
258    * Keep receiving until we get a valid transaction id
259    */
260   xdrs->x_op = XDR_DECODE;
261   while (TRUE)
262     {
263       reply_msg.acpted_rply.ar_verf = _null_auth;
264       reply_msg.acpted_rply.ar_results.where = NULL;
265       reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
266       if (!xdrrec_skiprecord (xdrs))
267         return ct->ct_error.re_status;
268       /* now decode and validate the response header */
269       if (!xdr_replymsg (xdrs, &reply_msg))
270         {
271           if (ct->ct_error.re_status == RPC_SUCCESS)
272             continue;
273           return ct->ct_error.re_status;
274         }
275       if (reply_msg.rm_xid == x_id)
276         break;
277     }
278
279   /*
280    * process header
281    */
282   _seterr_reply (&reply_msg, &(ct->ct_error));
283   if (ct->ct_error.re_status == RPC_SUCCESS)
284     {
285       if (!AUTH_VALIDATE (h->cl_auth, &reply_msg.acpted_rply.ar_verf))
286         {
287           ct->ct_error.re_status = RPC_AUTHERROR;
288           ct->ct_error.re_why = AUTH_INVALIDRESP;
289         }
290       else if (!(*xdr_results) (xdrs, results_ptr))
291         {
292           if (ct->ct_error.re_status == RPC_SUCCESS)
293             ct->ct_error.re_status = RPC_CANTDECODERES;
294         }
295       /* free verifier ... */
296       if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
297         {
298           xdrs->x_op = XDR_FREE;
299           (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));
300         }
301     }                           /* end successful completion */
302   else
303     {
304       /* maybe our credentials need to be refreshed ... */
305       if (refreshes-- && AUTH_REFRESH (h->cl_auth))
306         goto call_again;
307     }                           /* end of unsuccessful completion */
308   return ct->ct_error.re_status;
309 }
310
311 static void
312 clntunix_geterr (CLIENT *h, struct rpc_err *errp)
313 {
314   struct ct_data *ct = (struct ct_data *) h->cl_private;
315
316   *errp = ct->ct_error;
317 }
318
319 static bool_t
320 clntunix_freeres (cl, xdr_res, res_ptr)
321      CLIENT *cl;
322      xdrproc_t xdr_res;
323      caddr_t res_ptr;
324 {
325   struct ct_data *ct = (struct ct_data *) cl->cl_private;
326   XDR *xdrs = &(ct->ct_xdrs);
327
328   xdrs->x_op = XDR_FREE;
329   return (*xdr_res) (xdrs, res_ptr);
330 }
331
332 static void
333 clntunix_abort ()
334 {
335 }
336
337 static bool_t
338 clntunix_control (CLIENT *cl, int request, char *info)
339 {
340   struct ct_data *ct = (struct ct_data *) cl->cl_private;
341   u_long ul;
342   u_int32_t ui32;
343
344   switch (request)
345     {
346     case CLSET_FD_CLOSE:
347       ct->ct_closeit = TRUE;
348       break;
349     case CLSET_FD_NCLOSE:
350       ct->ct_closeit = FALSE;
351       break;
352     case CLSET_TIMEOUT:
353       ct->ct_wait = *(struct timeval *) info;
354       break;
355     case CLGET_TIMEOUT:
356       *(struct timeval *) info = ct->ct_wait;
357       break;
358     case CLGET_SERVER_ADDR:
359       *(struct sockaddr_un *) info = ct->ct_addr;
360       break;
361     case CLGET_FD:
362       *(int *)info = ct->ct_sock;
363       break;
364     case CLGET_XID:
365       /*
366        * use the knowledge that xid is the
367        * first element in the call structure *.
368        * This will get the xid of the PREVIOUS call
369        */
370       memcpy (&ui32, ct->ct_mcall, sizeof (ui32));
371       ul = ntohl (ui32);
372       memcpy (info, &ul, sizeof (ul));
373       break;
374     case CLSET_XID:
375       /* This will set the xid of the NEXT call */
376       memcpy (&ul, info, sizeof (ul));
377       ui32 = htonl (ul - 1);
378       memcpy (ct->ct_mcall, &ui32, sizeof (ui32));
379       /* decrement by 1 as clntunix_call() increments once */
380       break;
381     case CLGET_VERS:
382       /*
383        * This RELIES on the information that, in the call body,
384        * the version number field is the fifth field from the
385        * begining of the RPC header. MUST be changed if the
386        * call_struct is changed
387        */
388       memcpy (&ui32, ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
389       ul = ntohl (ui32);
390       memcpy (info, &ul, sizeof (ul));
391       break;
392     case CLSET_VERS:
393       memcpy (&ul, info, sizeof (ul));
394       ui32 = htonl (ul);
395       memcpy (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
396       break;
397     case CLGET_PROG:
398       /*
399        * This RELIES on the information that, in the call body,
400        * the program number field is the  field from the
401        * begining of the RPC header. MUST be changed if the
402        * call_struct is changed
403        */
404       memcpy (&ui32, ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
405       ul = ntohl (ui32);
406       memcpy (info, &ul, sizeof (ul));
407       break;
408     case CLSET_PROG:
409       memcpy (&ul, info, sizeof (ul));
410       ui32 = htonl (ul);
411       memcpy (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
412       break;
413     /* The following are only possible with TI-RPC */
414     case CLGET_RETRY_TIMEOUT:
415     case CLSET_RETRY_TIMEOUT:
416     case CLGET_SVC_ADDR:
417     case CLSET_SVC_ADDR:
418     case CLSET_PUSH_TIMOD:
419     case CLSET_POP_TIMOD:
420     default:
421       return FALSE;
422     }
423   return TRUE;
424 }
425
426
427 static void
428 clntunix_destroy (CLIENT *h)
429 {
430   struct ct_data *ct =
431   (struct ct_data *) h->cl_private;
432
433   if (ct->ct_closeit)
434     {
435       (void) __close (ct->ct_sock);
436     }
437   XDR_DESTROY (&(ct->ct_xdrs));
438   mem_free ((caddr_t) ct, sizeof (struct ct_data));
439   mem_free ((caddr_t) h, sizeof (CLIENT));
440 }
441
442 static int
443 __msgread (int sock, void *data, size_t cnt)
444 {
445   struct iovec iov;
446   struct msghdr msg;
447 #ifdef SCM_CREDENTIALS
448   static char cm[CMSG_SPACE(sizeof (struct ucred))];
449 #endif
450   int len;
451
452   iov.iov_base = data;
453   iov.iov_len = cnt;
454
455   msg.msg_iov = &iov;
456   msg.msg_iovlen = 1;
457   msg.msg_name = NULL;
458   msg.msg_namelen = 0;
459 #ifdef SCM_CREDENTIALS
460   msg.msg_control = (caddr_t) &cm;
461   msg.msg_controllen = CMSG_SPACE(sizeof (struct ucred));
462 #endif
463   msg.msg_flags = 0;
464
465 #ifdef SO_PASSCRED
466   {
467     int on = 1;
468     if (__setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)))
469       return -1;
470   }
471 #endif
472
473  restart:
474   len = __recvmsg (sock, &msg, 0);
475   if (len >= 0)
476     {
477       if (msg.msg_flags & MSG_CTRUNC || len == 0)
478         return 0;
479       else
480         return len;
481     }
482   if (errno == EINTR)
483     goto restart;
484   return -1;
485 }
486
487 static int
488 __msgwrite (int sock, void *data, size_t cnt)
489 {
490 #ifndef SCM_CREDENTIALS
491   /* We cannot implement this reliably.  */
492   __set_errno (ENOSYS);
493   return -1;
494 #else
495   struct iovec iov;
496   struct msghdr msg;
497   struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred)));
498   struct ucred cred;
499   int len;
500
501   /* XXX I'm not sure, if gete?id() is always correct, or if we should use
502      get?id(). But since keyserv needs geteuid(), we have no other chance.
503      It would be much better, if the kernel could pass both to the server. */
504   cred.pid = __getpid ();
505   cred.uid = __geteuid ();
506   cred.gid = __getegid ();
507
508   memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred));
509   cmsg->cmsg_level = SOL_SOCKET;
510   cmsg->cmsg_type = SCM_CREDENTIALS;
511   cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred);
512
513   iov.iov_base = data;
514   iov.iov_len = cnt;
515
516   msg.msg_iov = &iov;
517   msg.msg_iovlen = 1;
518   msg.msg_name = NULL;
519   msg.msg_namelen = 0;
520   msg.msg_control = cmsg;
521   msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
522   msg.msg_flags = 0;
523
524  restart:
525   len = __sendmsg (sock, &msg, 0);
526   if (len >= 0)
527     return len;
528   if (errno == EINTR)
529     goto restart;
530   return -1;
531
532 #endif
533 }
534
535
536 /*
537  * Interface between xdr serializer and unix connection.
538  * Behaves like the system calls, read & write, but keeps some error state
539  * around for the rpc level.
540  */
541 static int
542 readunix (char *ctptr, char *buf, int len)
543 {
544   struct ct_data *ct = (struct ct_data *) ctptr;
545   struct pollfd fd;
546   int milliseconds = ((ct->ct_wait.tv_sec * 1000)
547                       + (ct->ct_wait.tv_usec / 1000));
548
549   if (len == 0)
550     return 0;
551
552   fd.fd = ct->ct_sock;
553   fd.events = POLLIN;
554   while (TRUE)
555     {
556       switch (__poll (&fd, 1, milliseconds))
557         {
558         case 0:
559           ct->ct_error.re_status = RPC_TIMEDOUT;
560           return -1;
561
562         case -1:
563           if (errno == EINTR)
564             continue;
565           ct->ct_error.re_status = RPC_CANTRECV;
566           ct->ct_error.re_errno = errno;
567           return -1;
568         }
569       break;
570     }
571   switch (len = __msgread (ct->ct_sock, buf, len))
572     {
573
574     case 0:
575       /* premature eof */
576       ct->ct_error.re_errno = ECONNRESET;
577       ct->ct_error.re_status = RPC_CANTRECV;
578       len = -1;                 /* it's really an error */
579       break;
580
581     case -1:
582       ct->ct_error.re_errno = errno;
583       ct->ct_error.re_status = RPC_CANTRECV;
584       break;
585     }
586   return len;
587 }
588
589 static int
590 writeunix (char *ctptr, char *buf, int len)
591 {
592   int i, cnt;
593   struct ct_data *ct = (struct ct_data *) ctptr;
594
595   for (cnt = len; cnt > 0; cnt -= i, buf += i)
596     {
597       if ((i = __msgwrite (ct->ct_sock, buf, cnt)) == -1)
598         {
599           ct->ct_error.re_errno = errno;
600           ct->ct_error.re_status = RPC_CANTSEND;
601           return -1;
602         }
603     }
604   return len;
605 }