1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
24 */
25
26/*
27 * This module provides the interface to NDR RPC.
28 */
29
30#include <sys/stat.h>
31#include <sys/uio.h>
32#include <sys/ksynch.h>
33#include <sys/stropts.h>
34#include <sys/socket.h>
35#include <sys/filio.h>
36#include <smbsrv/smb_kproto.h>
37#include <smbsrv/smb_xdr.h>
38#include <smb/winioctl.h>
39
40/*
41 * Allocate a new opipe and return it, or NULL, in which case
42 * the caller will report "internal error".
43 */
44static smb_opipe_t *
45smb_opipe_alloc(smb_request_t *sr)
46{
47	smb_server_t	*sv = sr->sr_server;
48	smb_opipe_t	*opipe;
49	ksocket_t	sock;
50
51	if (ksocket_socket(&sock, AF_UNIX, SOCK_STREAM, 0,
52	    KSOCKET_SLEEP, sr->user_cr) != 0)
53		return (NULL);
54
55	opipe = kmem_cache_alloc(smb_cache_opipe, KM_SLEEP);
56
57	bzero(opipe, sizeof (smb_opipe_t));
58	mutex_init(&opipe->p_mutex, NULL, MUTEX_DEFAULT, NULL);
59	cv_init(&opipe->p_cv, NULL, CV_DEFAULT, NULL);
60	opipe->p_magic = SMB_OPIPE_MAGIC;
61	opipe->p_server = sv;
62	opipe->p_refcnt = 1;
63	opipe->p_socket = sock;
64
65	return (opipe);
66}
67
68/*
69 * Destroy an opipe.  This is normally called from smb_ofile_delete
70 * when the ofile has no more references and is about to be free'd.
71 * This is also called here in error handling code paths, before
72 * the opipe is installed under an ofile.
73 */
74void
75smb_opipe_dealloc(smb_opipe_t *opipe)
76{
77	smb_server_t *sv;
78
79	SMB_OPIPE_VALID(opipe);
80	sv = opipe->p_server;
81	SMB_SERVER_VALID(sv);
82
83	/*
84	 * This is called in the error path when opening,
85	 * in which case we close the socket here.
86	 */
87	if (opipe->p_socket != NULL)
88		(void) ksocket_close(opipe->p_socket, zone_kcred());
89
90	opipe->p_magic = (uint32_t)~SMB_OPIPE_MAGIC;
91	cv_destroy(&opipe->p_cv);
92	mutex_destroy(&opipe->p_mutex);
93
94	kmem_cache_free(smb_cache_opipe, opipe);
95}
96
97/*
98 * Unblock a request that might be blocked reading some
99 * pipe (AF_UNIX socket).  We don't have an easy way to
100 * interrupt just the thread servicing this request, so
101 * we shutdown(3socket) the socket, waking all readers.
102 * That's a bit heavy-handed, making the socket unusable
103 * after this, so we do this only when disconnecting a
104 * session (i.e. stopping the SMB service), and not when
105 * handling an SMB2_cancel or SMB_nt_cancel request.
106 */
107static void
108smb_opipe_cancel(smb_request_t *sr)
109{
110	ksocket_t so;
111
112	switch (sr->session->s_state) {
113	case SMB_SESSION_STATE_DISCONNECTED:
114	case SMB_SESSION_STATE_TERMINATED:
115		if ((so = sr->cancel_arg2) != NULL)
116			(void) ksocket_shutdown(so, SHUT_RDWR, sr->user_cr);
117		break;
118	}
119}
120
121/*
122 * Helper for open: build pipe name and connect.
123 */
124static int
125smb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe)
126{
127	struct sockaddr_un saddr;
128	smb_arg_open_t	*op = &sr->sr_open;
129	const char *name;
130	int rc;
131
132	name = op->fqi.fq_path.pn_path;
133	name += strspn(name, "\\");
134	if (smb_strcasecmp(name, "PIPE", 4) == 0) {
135		name += 4;
136		name += strspn(name, "\\");
137	}
138	(void) strlcpy(opipe->p_name, name, SMB_OPIPE_MAXNAME);
139	(void) smb_strlwr(opipe->p_name);
140
141	bzero(&saddr, sizeof (saddr));
142	saddr.sun_family = AF_UNIX;
143	(void) snprintf(saddr.sun_path, sizeof (saddr.sun_path),
144	    "%s/%s", SMB_PIPE_DIR, opipe->p_name);
145	rc = ksocket_connect(opipe->p_socket, (struct sockaddr *)&saddr,
146	    sizeof (saddr), sr->user_cr);
147
148	return (rc);
149}
150
151/*
152 * Helper for open: encode and send the user info.
153 *
154 * We send information about this client + user to the
155 * pipe service so it can use it for access checks.
156 * The service MAY deny the open based on this info,
157 * (i.e. anonymous session trying to open a pipe that
158 * requires authentication) in which case we will read
159 * an error status from the service and return that.
160 */
161static void
162smb_opipe_send_userinfo(smb_request_t *sr, smb_opipe_t *opipe,
163    smb_error_t *errp)
164{
165	XDR xdrs;
166	smb_netuserinfo_t nui;
167	smb_pipehdr_t phdr;
168	char *buf;
169	uint32_t buflen;
170	uint32_t status;
171	size_t iocnt = 0;
172	int rc;
173
174	/*
175	 * Any errors building the XDR message etc.
176	 */
177	errp->status = NT_STATUS_INTERNAL_ERROR;
178
179	smb_user_netinfo_init(sr->uid_user, &nui);
180	phdr.ph_magic = SMB_PIPE_HDR_MAGIC;
181	phdr.ph_uilen = xdr_sizeof(smb_netuserinfo_xdr, &nui);
182
183	buflen = sizeof (phdr) + phdr.ph_uilen;
184	buf = kmem_alloc(buflen, KM_SLEEP);
185
186	bcopy(&phdr, buf, sizeof (phdr));
187	xdrmem_create(&xdrs, buf + sizeof (phdr),
188	    buflen - (sizeof (phdr)), XDR_ENCODE);
189	if (!smb_netuserinfo_xdr(&xdrs, &nui))
190		goto out;
191
192	mutex_enter(&sr->sr_mutex);
193	if (sr->sr_state != SMB_REQ_STATE_ACTIVE) {
194		mutex_exit(&sr->sr_mutex);
195		errp->status = NT_STATUS_CANCELLED;
196		goto out;
197	}
198	sr->sr_state = SMB_REQ_STATE_WAITING_PIPE;
199	sr->cancel_method = smb_opipe_cancel;
200	sr->cancel_arg2 = opipe->p_socket;
201	mutex_exit(&sr->sr_mutex);
202
203	rc = ksocket_send(opipe->p_socket, buf, buflen, 0,
204	    &iocnt, sr->user_cr);
205	if (rc == 0 && iocnt != buflen)
206		rc = EIO;
207	if (rc == 0)
208		rc = ksocket_recv(opipe->p_socket, &status, sizeof (status),
209		    0, &iocnt, sr->user_cr);
210	if (rc == 0 && iocnt != sizeof (status))
211		rc = EIO;
212
213	mutex_enter(&sr->sr_mutex);
214	sr->cancel_method = NULL;
215	sr->cancel_arg2 = NULL;
216	switch (sr->sr_state) {
217	case SMB_REQ_STATE_WAITING_PIPE:
218		sr->sr_state = SMB_REQ_STATE_ACTIVE;
219		break;
220	case SMB_REQ_STATE_CANCEL_PENDING:
221		sr->sr_state = SMB_REQ_STATE_CANCELLED;
222		rc = EINTR;
223		break;
224	default:
225		/* keep rc from above */
226		break;
227	}
228	mutex_exit(&sr->sr_mutex);
229
230
231	/*
232	 * Return the status we read from the pipe service,
233	 * normally NT_STATUS_SUCCESS, but could be something
234	 * else like NT_STATUS_ACCESS_DENIED.
235	 */
236	switch (rc) {
237	case 0:
238		errp->status = status;
239		break;
240	case EINTR:
241		errp->status = NT_STATUS_CANCELLED;
242		break;
243	/*
244	 * If we fail sending the netuserinfo or recv'ing the
245	 * status reponse, we have probably run into the limit
246	 * on the number of open pipes.  That's this status:
247	 */
248	default:
249		errp->status = NT_STATUS_PIPE_NOT_AVAILABLE;
250		break;
251	}
252
253out:
254	xdr_destroy(&xdrs);
255	kmem_free(buf, buflen);
256	smb_user_netinfo_fini(&nui);
257}
258
259/*
260 * smb_opipe_open
261 *
262 * Open an RPC named pipe. This routine should be called if
263 * a file open is requested on a share of type STYPE_IPC.
264 * If we recognize the pipe, we setup a new ofile.
265 *
266 * Returns 0 on success, Otherwise an NT status code.
267 */
268int
269smb_opipe_open(smb_request_t *sr, smb_ofile_t *ofile)
270{
271	smb_arg_open_t	*op = &sr->sr_open;
272	smb_attr_t *ap = &op->fqi.fq_fattr;
273	smb_opipe_t *opipe;
274	smb_error_t err;
275
276	opipe = smb_opipe_alloc(sr);
277	if (opipe == NULL)
278		return (NT_STATUS_INTERNAL_ERROR);
279
280	if (smb_opipe_connect(sr, opipe) != 0) {
281		smb_opipe_dealloc(opipe);
282		return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
283	}
284
285	smb_opipe_send_userinfo(sr, opipe, &err);
286	if (err.status != 0) {
287		smb_opipe_dealloc(opipe);
288		return (err.status);
289	}
290
291	/*
292	 * We might have blocked in smb_opipe_connect long enough so
293	 * a tree disconnect might have happened.  In that case, we
294	 * would be adding an ofile to a tree that's disconnecting,
295	 * which would interfere with tear-down.
296	 */
297	if (!smb_tree_is_connected(sr->tid_tree)) {
298		smb_opipe_dealloc(opipe);
299		return (NT_STATUS_NETWORK_NAME_DELETED);
300	}
301
302	/*
303	 * Note: The new opipe is given to smb_ofile_open
304	 * via op->pipe
305	 */
306	op->pipe = opipe;
307	smb_ofile_open(sr, op, ofile);
308	op->pipe = NULL;
309
310	/* An "up" pointer, for debug. */
311	opipe->p_ofile = ofile;
312
313	/*
314	 * Caller expects attributes in op->fqi
315	 */
316	(void) smb_opipe_getattr(ofile, &op->fqi.fq_fattr);
317
318	op->dsize = 0;
319	op->dattr = ap->sa_dosattr;
320	op->fileid = ap->sa_vattr.va_nodeid;
321	op->ftype = SMB_FTYPE_MESG_PIPE;
322	op->action_taken = SMB_OACT_OPLOCK | SMB_OACT_OPENED;
323	op->devstate = SMB_PIPE_READMODE_MESSAGE
324	    | SMB_PIPE_TYPE_MESSAGE
325	    | SMB_PIPE_UNLIMITED_INSTANCES; /* 0x05ff */
326
327	sr->smb_fid = ofile->f_fid;
328	sr->fid_ofile = ofile;
329
330	return (NT_STATUS_SUCCESS);
331}
332
333/*
334 * smb_opipe_close
335 *
336 * Called by smb_ofile_close for pipes.
337 *
338 * Note: ksocket_close may block while waiting for
339 * any I/O threads with a hold to get out.
340 */
341void
342smb_opipe_close(smb_ofile_t *of)
343{
344	smb_opipe_t *opipe;
345	ksocket_t sock;
346
347	ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING);
348	ASSERT(of->f_ftype == SMB_FTYPE_MESG_PIPE);
349	opipe = of->f_pipe;
350	SMB_OPIPE_VALID(opipe);
351
352	mutex_enter(&opipe->p_mutex);
353	sock = opipe->p_socket;
354	opipe->p_socket = NULL;
355	mutex_exit(&opipe->p_mutex);
356
357	(void) ksocket_shutdown(sock, SHUT_RDWR, of->f_cr);
358	(void) ksocket_close(sock, of->f_cr);
359}
360
361/*
362 * smb_opipe_write
363 *
364 * Write RPC request data to the pipe.  The client should call smb_opipe_read
365 * to complete the exchange and obtain the RPC response.
366 *
367 * Returns 0 on success or an errno on failure.
368 */
369int
370smb_opipe_write(smb_request_t *sr, struct uio *uio)
371{
372	struct nmsghdr msghdr;
373	smb_ofile_t *ofile;
374	smb_opipe_t *opipe;
375	ksocket_t sock;
376	size_t sent = 0;
377	int rc = 0;
378
379	ofile = sr->fid_ofile;
380	ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
381	opipe = ofile->f_pipe;
382	SMB_OPIPE_VALID(opipe);
383
384	mutex_enter(&opipe->p_mutex);
385	sock = opipe->p_socket;
386	if (sock != NULL)
387		ksocket_hold(sock);
388	mutex_exit(&opipe->p_mutex);
389	if (sock == NULL)
390		return (EBADF);
391
392	bzero(&msghdr, sizeof (msghdr));
393	msghdr.msg_iov = uio->uio_iov;
394	msghdr.msg_iovlen = uio->uio_iovcnt;
395
396	/*
397	 * This should block until we've sent it all,
398	 * or given up due to errors (pipe closed).
399	 */
400	while (uio->uio_resid > 0) {
401		rc = ksocket_sendmsg(sock, &msghdr, 0, &sent, ofile->f_cr);
402		if (rc != 0)
403			break;
404		uio->uio_resid -= sent;
405	}
406
407	ksocket_rele(sock);
408
409	return (rc);
410}
411
412/*
413 * smb_opipe_read
414 *
415 * This interface may be called from smb_opipe_transact (write, read)
416 * or from smb_read / smb2_read to get the rest of an RPC response.
417 * The response data (and length) are returned via the uio.
418 */
419int
420smb_opipe_read(smb_request_t *sr, struct uio *uio)
421{
422	struct nmsghdr msghdr;
423	smb_ofile_t *ofile;
424	smb_opipe_t *opipe;
425	ksocket_t sock;
426	size_t recvcnt = 0;
427	int rc;
428
429	ofile = sr->fid_ofile;
430	ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
431	opipe = ofile->f_pipe;
432	SMB_OPIPE_VALID(opipe);
433
434	mutex_enter(&opipe->p_mutex);
435	sock = opipe->p_socket;
436	if (sock != NULL)
437		ksocket_hold(sock);
438	mutex_exit(&opipe->p_mutex);
439	if (sock == NULL)
440		return (EBADF);
441
442	mutex_enter(&sr->sr_mutex);
443	if (sr->sr_state != SMB_REQ_STATE_ACTIVE) {
444		mutex_exit(&sr->sr_mutex);
445		rc = EINTR;
446		goto out;
447	}
448	sr->sr_state = SMB_REQ_STATE_WAITING_PIPE;
449	sr->cancel_method = smb_opipe_cancel;
450	sr->cancel_arg2 = sock;
451	mutex_exit(&sr->sr_mutex);
452
453	/*
454	 * This should block only if there's no data.
455	 * A single call to recvmsg does just that.
456	 * (Intentionaly no recv loop here.)
457	 */
458	bzero(&msghdr, sizeof (msghdr));
459	msghdr.msg_iov = uio->uio_iov;
460	msghdr.msg_iovlen = uio->uio_iovcnt;
461	rc = ksocket_recvmsg(sock, &msghdr, 0,
462	    &recvcnt, ofile->f_cr);
463
464	mutex_enter(&sr->sr_mutex);
465	sr->cancel_method = NULL;
466	sr->cancel_arg2 = NULL;
467	switch (sr->sr_state) {
468	case SMB_REQ_STATE_WAITING_PIPE:
469		sr->sr_state = SMB_REQ_STATE_ACTIVE;
470		break;
471	case SMB_REQ_STATE_CANCEL_PENDING:
472		sr->sr_state = SMB_REQ_STATE_CANCELLED;
473		rc = EINTR;
474		break;
475	default:
476		/* keep rc from above */
477		break;
478	}
479	mutex_exit(&sr->sr_mutex);
480
481	if (rc != 0)
482		goto out;
483
484	if (recvcnt == 0) {
485		/* Other side closed. */
486		rc = EPIPE;
487		goto out;
488	}
489	uio->uio_resid -= recvcnt;
490
491out:
492	ksocket_rele(sock);
493
494	return (rc);
495}
496
497int
498smb_opipe_ioctl(smb_request_t *sr, int cmd, void *arg, int *rvalp)
499{
500	smb_ofile_t *ofile;
501	smb_opipe_t *opipe;
502	ksocket_t sock;
503	int rc;
504
505	ofile = sr->fid_ofile;
506	ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
507	opipe = ofile->f_pipe;
508	SMB_OPIPE_VALID(opipe);
509
510	mutex_enter(&opipe->p_mutex);
511	sock = opipe->p_socket;
512	if (sock != NULL)
513		ksocket_hold(sock);
514	mutex_exit(&opipe->p_mutex);
515	if (sock == NULL)
516		return (EBADF);
517
518	rc = ksocket_ioctl(sock, cmd, (intptr_t)arg, rvalp, ofile->f_cr);
519
520	ksocket_rele(sock);
521
522	return (rc);
523}
524
525/*
526 * Get the smb_attr_t for a named pipe.
527 * Caller has already cleared to zero.
528 */
529int
530smb_opipe_getattr(smb_ofile_t *of, smb_attr_t *ap)
531{
532
533	if (of->f_pipe == NULL)
534		return (EINVAL);
535
536	ap->sa_vattr.va_type = VFIFO;
537	ap->sa_vattr.va_nlink = 1;
538	ap->sa_vattr.va_nodeid = (uintptr_t)of->f_pipe;
539	ap->sa_dosattr = FILE_ATTRIBUTE_NORMAL;
540	ap->sa_allocsz = SMB_PIPE_MAX_MSGSIZE;
541
542	return (0);
543}
544
545int
546smb_opipe_getname(smb_ofile_t *of, char *buf, size_t buflen)
547{
548	smb_opipe_t *opipe;
549
550	if ((opipe = of->f_pipe) == NULL)
551		return (EINVAL);
552
553	(void) snprintf(buf, buflen, "\\%s", opipe->p_name);
554	return (0);
555}
556
557/*
558 * Handle device type FILE_DEVICE_NAMED_PIPE
559 * for smb2_ioctl
560 */
561/* ARGSUSED */
562uint32_t
563smb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl)
564{
565	uint32_t status;
566
567	if (!STYPE_ISIPC(sr->tid_tree->t_res_type))
568		return (NT_STATUS_INVALID_DEVICE_REQUEST);
569
570	switch (fsctl->CtlCode) {
571	case FSCTL_PIPE_TRANSCEIVE:
572		status = smb_opipe_transceive(sr, fsctl);
573		break;
574
575	case FSCTL_PIPE_PEEK:
576	case FSCTL_PIPE_WAIT:
577		/* XXX todo */
578		status = NT_STATUS_NOT_SUPPORTED;
579		break;
580
581	default:
582		ASSERT(!"CtlCode");
583		status = NT_STATUS_INTERNAL_ERROR;
584		break;
585	}
586
587	return (status);
588}
589
590uint32_t
591smb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl)
592{
593	smb_vdb_t	vdb;
594	smb_ofile_t	*ofile;
595	struct mbuf	*mb;
596	uint32_t	status;
597	int		len, rc;
598
599	/*
600	 * Caller checked that this is the IPC$ share,
601	 * and that this call has a valid open handle.
602	 * Just check the type.
603	 */
604	ofile = sr->fid_ofile;
605	if (ofile->f_ftype != SMB_FTYPE_MESG_PIPE)
606		return (NT_STATUS_INVALID_HANDLE);
607
608	rc = smb_mbc_decodef(fsctl->in_mbc, "#B",
609	    fsctl->InputCount, &vdb);
610	if (rc != 0) {
611		/* Not enough data sent. */
612		return (NT_STATUS_INVALID_PARAMETER);
613	}
614
615	rc = smb_opipe_write(sr, &vdb.vdb_uio);
616	if (rc != 0)
617		return (smb_errno2status(rc));
618
619	vdb.vdb_tag = 0;
620	vdb.vdb_uio.uio_iov = &vdb.vdb_iovec[0];
621	vdb.vdb_uio.uio_iovcnt = MAX_IOVEC;
622	vdb.vdb_uio.uio_segflg = UIO_SYSSPACE;
623	vdb.vdb_uio.uio_extflg = UIO_COPY_DEFAULT;
624	vdb.vdb_uio.uio_loffset = (offset_t)0;
625	vdb.vdb_uio.uio_resid = fsctl->MaxOutputResp;
626	mb = smb_mbuf_allocate(&vdb.vdb_uio);
627
628	rc = smb_opipe_read(sr, &vdb.vdb_uio);
629	if (rc != 0) {
630		m_freem(mb);
631		return (smb_errno2status(rc));
632	}
633
634	len = fsctl->MaxOutputResp - vdb.vdb_uio.uio_resid;
635	smb_mbuf_trim(mb, len);
636	MBC_ATTACH_MBUF(fsctl->out_mbc, mb);
637
638	/*
639	 * If the output buffer holds a partial pipe message,
640	 * we're supposed to return NT_STATUS_BUFFER_OVERFLOW.
641	 * As we don't have message boundary markers, the best
642	 * we can do is return that status when we have ALL of:
643	 *	Output buffer was < SMB_PIPE_MAX_MSGSIZE
644	 *	We filled the output buffer (resid==0)
645	 *	There's more data (ioctl FIONREAD)
646	 */
647	status = NT_STATUS_SUCCESS;
648	if (fsctl->MaxOutputResp < SMB_PIPE_MAX_MSGSIZE &&
649	    vdb.vdb_uio.uio_resid == 0) {
650		int nread = 0, trval;
651		rc = smb_opipe_ioctl(sr, FIONREAD, &nread, &trval);
652		if (rc == 0 && nread != 0)
653			status = NT_STATUS_BUFFER_OVERFLOW;
654	}
655
656	return (status);
657}
658