Home | History | Annotate | Download | only in smbsrv
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <smbsrv/smb_kproto.h>
     27 #include <smbsrv/winioctl.h>
     28 
     29 
     30 static uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *);
     31 static uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *,
     32     smb_xa_t *);
     33 
     34 /*
     35  * This table defines the list of FSCTL values for which we'll
     36  * call a funtion to perform specific processing.
     37  */
     38 static struct {
     39 	uint32_t fcode;
     40 	uint32_t (*ioctl_func)(smb_request_t *sr, smb_xa_t *xa);
     41 } ioctl_ret_tbl[] = {
     42 	{ FSCTL_GET_OBJECT_ID, smb_nt_trans_ioctl_invalid_parm },
     43 	{ FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_invalid_parm },
     44 	{ FSCTL_SRV_ENUMERATE_SNAPSHOTS, smb_vss_ioctl_enumerate_snaps },
     45 	{ FSCTL_SET_SPARSE, smb_nt_trans_ioctl_noop }
     46 };
     47 
     48 /*
     49  * smb_nt_transact_ioctl
     50  *
     51  * This command allows device and file system control functions to be
     52  * transferred transparently from client to server.
     53  *
     54  * Setup Words Encoding        Description
     55  * =========================== =========================================
     56  * ULONG FunctionCode;         NT device or file system control code
     57  * USHORT Fid;                 Handle for io or fs control. Unless BIT0
     58  *                             of ISFLAGS is set.
     59  * BOOLEAN IsFsctl;            Indicates whether the command is a device
     60  *                             control (FALSE) or a file system control
     61  *                             (TRUE).
     62  * UCHAR   IsFlags;            BIT0 - command is to be applied to share
     63  *                             root handle. Share must be a DFS share.
     64  *
     65  * Data Block Encoding         Description
     66  * =========================== =========================================
     67  * Data[ TotalDataCount ]      Passed to the Fsctl or Ioctl
     68  *
     69  * Server Response             Description
     70  * =========================== ==================================
     71  * SetupCount                  1
     72  * Setup[0]                    Length of information returned by
     73  *                             io or fs control.
     74  * DataCount                   Length of information returned by
     75  *                             io or fs control.
     76  * Data[ DataCount ]           The results of the io or fs control.
     77  */
     78 smb_sdrc_t
     79 smb_nt_transact_ioctl(smb_request_t *sr, smb_xa_t *xa)
     80 {
     81 	uint32_t status = NT_STATUS_NOT_SUPPORTED;
     82 	uint32_t fcode;
     83 	unsigned short fid;
     84 	unsigned char is_fsctl;
     85 	unsigned char is_flags;
     86 	int i;
     87 
     88 	if (smb_mbc_decodef(&xa->req_setup_mb, "lwbb",
     89 	    &fcode, &fid, &is_fsctl, &is_flags) != 0) {
     90 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
     91 		return (SDRC_ERROR);
     92 	}
     93 
     94 	/*
     95 	 * Invoke handler if specified, otherwise the default
     96 	 * behavior is to return NT_STATUS_NOT_SUPPORTED
     97 	 */
     98 	for (i = 0; i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
     99 	    i++) {
    100 		if (ioctl_ret_tbl[i].fcode == fcode) {
    101 			status = ioctl_ret_tbl[i].ioctl_func(sr, xa);
    102 			break;
    103 		}
    104 	}
    105 
    106 	if (status != NT_STATUS_SUCCESS) {
    107 		smbsr_error(sr, status, 0, 0);
    108 		return (SDRC_ERROR);
    109 	}
    110 
    111 	(void) smb_mbc_encodef(&xa->rep_param_mb, "l", 0);
    112 	return (SDRC_SUCCESS);
    113 }
    114 
    115 /* ARGSUSED */
    116 static uint32_t
    117 smb_nt_trans_ioctl_noop(smb_request_t *sr, smb_xa_t *xa)
    118 {
    119 	return (NT_STATUS_SUCCESS);
    120 }
    121 
    122 /* ARGSUSED */
    123 static uint32_t
    124 smb_nt_trans_ioctl_invalid_parm(smb_request_t *sr, smb_xa_t *xa)
    125 {
    126 	return (NT_STATUS_INVALID_PARAMETER);
    127 }
    128