smb_dev.c revision 39f633a09e54fab2b9cf8d9d3ddc2a043b3e7465
/*
* Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
#include <sys/pathname.h>
#include <netsmb/smb_osdep.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
#include <netsmb/smb_pass.h>
#define NSMB_MIN_MINOR 1
#define NSMB_MAX_MINOR L_MAXMIN32
/* for version checks */
static void *statep;
static major_t nsmb_major;
static dev_info_t *nsmb_dip;
/* Zone support */
/*
* cb_ops device operations.
*/
/* smbfs cb_ops */
static struct cb_ops nsmb_cbops = {
nsmb_open, /* open */
nsmb_close, /* close */
nodev, /* strategy */
nodev, /* print */
nodev, /* dump */
nodev, /* read */
nodev, /* write */
nsmb_ioctl, /* ioctl */
nodev, /* devmap */
nodev, /* mmap */
nodev, /* segmap */
nochpoll, /* poll */
ddi_prop_op, /* prop_op */
NULL, /* stream */
D_MP, /* cb_flag */
CB_REV, /* rev */
nodev, /* int (*cb_aread)() */
nodev /* int (*cb_awrite)() */
};
/*
* Device options
*/
DEVO_REV, /* devo_rev, */
0, /* refcnt */
nsmb_getinfo, /* info */
nulldev, /* identify */
nulldev, /* probe */
nsmb_attach, /* attach */
nsmb_detach, /* detach */
nodev, /* reset */
&nsmb_cbops, /* driver ops - devctl interfaces */
NULL, /* bus operations */
NULL, /* power */
ddi_quiesce_not_needed, /* quiesce */
};
/*
* Module linkage information.
*/
static struct modldrv nsmb_modldrv = {
&mod_driverops, /* Driver module */
"SMBFS network driver",
&nsmb_ops /* Driver ops */
};
static struct modlinkage nsmb_modlinkage = {
(void *)&nsmb_modldrv,
};
int
_init(void)
{
int error;
/* Can initialize some mutexes also. */
/* Connection data structures. */
(void) smb_sm_init();
/* Initialize password Key chain DB. */
/* Time conversion stuff. */
/* Initialize crypto mechanisms. */
/*
* Install the module. Do this after other init,
* to prevent entrances before we're ready.
*/
/* Same as 2nd half of _fini */
(void) zone_key_delete(nsmb_zone_key);
smb_sm_done();
return (error);
}
return (0);
}
int
_fini(void)
{
int status;
/*
* Prevent unload if we have active VCs
* or stored passwords
*/
if ((status = smb_sm_idle()) != 0)
return (status);
if ((status = smb_pkey_idle()) != 0)
return (status);
/*
* Remove the module. Do this before destroying things,
* to prevent new entrances while we're destorying.
*/
return (status);
}
(void) zone_key_delete(nsmb_zone_key);
/* Time conversion stuff. */
/* Destroy password Key chain DB. */
smb_sm_done();
return (status);
}
int
{
}
/*ARGSUSED*/
static int
{
int ret = DDI_SUCCESS;
switch (cmd) {
case DDI_INFO_DEVT2DEVINFO:
break;
case DDI_INFO_DEVT2INSTANCE:
break;
default:
ret = DDI_FAILURE;
}
return (ret);
}
static int
{
if (cmd != DDI_ATTACH)
return (DDI_FAILURE);
/*
* We only support only one "instance". Note that
* "instances" are different from minor units.
* We get one (unique) minor unit per open.
*/
if (ddi_get_instance(dip) > 0)
return (DDI_FAILURE);
NULL) == DDI_FAILURE) {
return (DDI_FAILURE);
}
/*
* We need the major number a couple places,
* i.e. in smb_dev2share()
*/
return (DDI_SUCCESS);
}
/*ARGSUSED*/
static int
{
if (cmd != DDI_DETACH)
return (DDI_FAILURE);
if (ddi_get_instance(dip) > 0)
return (DDI_FAILURE);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
static int
{
int err;
return (DDI_FAILURE);
}
return (EBADF);
}
/*
* Dont give access if the zone id is not as the same as we
* set in the nsmb_open or dont belong to the global zone.
* Check if the user belongs to this zone..
*/
return (EIO);
/*
* We have a zone_shutdown call back that kills all the VCs
* in a zone that's shutting down. That action will cause
* all of these ioctls to fail on such VCs, so no need to
* check the zone status here on every ioctl call.
*/
err = 0;
switch (cmd) {
case SMBIOC_GETVERS:
sizeof (nsmb_version), flags);
break;
case SMBIOC_FLAGS2:
break;
case SMBIOC_GETSSNKEY:
break;
case SMBIOC_DUP_DEV:
break;
case SMBIOC_REQUEST:
break;
case SMBIOC_T2RQ:
break;
case SMBIOC_READ:
case SMBIOC_WRITE:
break;
case SMBIOC_NTCREATE:
break;
case SMBIOC_PRINTJOB:
break;
case SMBIOC_CLOSEFH:
break;
case SMBIOC_SSN_CREATE:
case SMBIOC_SSN_FIND:
break;
case SMBIOC_SSN_KILL:
case SMBIOC_SSN_RELE:
break;
case SMBIOC_TREE_CONNECT:
case SMBIOC_TREE_FIND:
break;
case SMBIOC_TREE_KILL:
case SMBIOC_TREE_RELE:
break;
case SMBIOC_IOD_WORK:
break;
case SMBIOC_IOD_IDLE:
case SMBIOC_IOD_RCFAIL:
break;
case SMBIOC_PK_ADD:
case SMBIOC_PK_DEL:
case SMBIOC_PK_CHK:
case SMBIOC_PK_DEL_OWNER:
case SMBIOC_PK_DEL_EVERYONE:
break;
default:
break;
}
return (err);
}
/*
* This does "clone" open, meaning it automatically
* assigns an available minor unit for each open.
*/
/*ARGSUSED*/
static int
{
minor_t m;
if (m > NSMB_MAX_MINOR)
m = NSMB_MIN_MINOR;
last_minor = m;
goto found;
}
}
/* No available minor units. */
return (ENXIO);
/* NB: dev_lck still held */
return (ENXIO);
}
return (ENXIO);
}
return (0);
}
/*ARGSUSED*/
static int
{
int err;
/*
* 1. Check the validity of the minor number.
* 3. Can close the minor number.
* 4. Deallocate any resources allocated in open() call.
*/
else
/*
* Free the instance
*/
return (err);
}
static int
{
/*
* If this dev minor was opened by smbiod,
* mark this VC as "dead" because it now
* will have no IOD to service it.
*/
}
return (0);
}
/*
* Helper for SMBIOC_DUP_DEV
* Duplicate state from the FD @arg ("from") onto
* the FD for this device instance.
*/
int
{
int err;
/* Should be no VC */
return (EISCONN);
/*
* Get from_sdp (what we will duplicate)
*/
return (EFAULT);
return (EBADF);
/* rele fp below */
goto out;
}
goto out;
}
/*
* Duplicate VC and share references onto this FD.
*/
err = 0;
out:
if (fp)
return (err);
}
/*
* Helper used by smbfs_mount
*/
int
{
int err;
return (EBADF);
/* rele fp below */
goto out;
}
goto out;
}
goto out;
}
/*
* Our caller gains a ref. to this share.
*/
err = 0;
out:
if (fp)
return (err);
}