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.
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.
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]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
43 #include <smbsrv/smb_door.h>
44 #include <smbsrv/smb_xdr.h>
45 #include <smbsrv/smb_token.h>
46 #include <smbsrv/libmlsvc.h>
47 #include <smbsrv/libsmbns.h>
52 * Special version of smb_door_dispatch() for the
53 * "fake" smbsrv (running in user space).
55 * This is called via function pointer from
56 * smbsrv: smb_kdoor_upcall()
58 * The args and response go RPC encoded, just so we can
59 * borrow some of the common doorsvc code, even though
60 * there's no need for RPC encoding in this scenario.
63 fksmbd_door_dispatch(smb_doorarg_t
*da
)
69 char *argp
= da
->da_arg
.data_ptr
;
70 size_t arg_size
= da
->da_arg
.data_size
;
71 size_t hdr_size
, rsize
;
76 * da->da_arg.data_ptr = (arg data, xdr encoded)
77 * da->da_arg.data_size = (arg data len)
80 bzero(&dop_arg
, sizeof (smbd_arg_t
));
82 hdr_size
= xdr_sizeof(smb_doorhdr_xdr
, hdr
);
84 if ((argp
== NULL
) || (arg_size
< hdr_size
)) {
85 syslog(LOG_DEBUG
, "fksmbd_door_dispatch: bad args");
89 if (smb_doorhdr_decode(hdr
, (uint8_t *)argp
, hdr_size
) == -1) {
90 syslog(LOG_DEBUG
, "smbd_door_dispatch: header decode failed");
94 if ((hdr
->dh_magic
!= SMB_DOOR_HDR_MAGIC
) ||
95 (hdr
->dh_flags
!= SMB_DF_FAKE_KERNEL
)) {
96 syslog(LOG_DEBUG
, "fksmbd_door_dispatch: invalid header");
100 dop_arg
.opname
= smb_doorhdr_opname(hdr
->dh_op
);
101 dop_arg
.data
= argp
+ hdr_size
;
102 dop_arg
.datalen
= hdr
->dh_datalen
;
104 if (hdr
->dh_op
== SMB_DR_ASYNC_RESPONSE
) {
106 * ASYNC_RESPONSE is not used here.
108 syslog(LOG_DEBUG
, "fksmbd_door_dispatch: ASYNC?");
115 * Call the common smbd_doorsvc.c code.
117 (void) smbd_door_dispatch_op(&dop_arg
);
122 * da->da_arg.rbuf = (return data buf)
123 * da->da_arg.rsize = (return data size)
125 * Note that the return data buffer initially
126 * points to the same buffer as the args.
127 * If that's not large enough, umem_alloc.
130 rsize
= dop_arg
.rsize
+ hdr_size
;
131 rbuf
= umem_alloc(rsize
, UMEM_DEFAULT
);
133 syslog(LOG_DEBUG
, "fksmbd_door_dispatch[%s]: alloc %m",
138 /* Copy caller's return data after the header. */
139 if (dop_arg
.rbuf
!= NULL
) {
140 (void) memcpy(rbuf
+ hdr_size
, dop_arg
.rbuf
, dop_arg
.rsize
);
144 hdr
->dh_datalen
= dop_arg
.rsize
;
145 (void) smb_doorhdr_encode(hdr
, (uint8_t *)rbuf
, hdr_size
);
147 /* Let's update da->da_hdr too. */
152 * NB: The "fake kernel" smbsrv code will umem_free rbuf.
154 da
->da_arg
.rbuf
= rbuf
;
155 da
->da_arg
.rsize
= rsize
;