smb_conn.c revision 67dbe2be0c0f1e2eb428b89088bb5667e8f0b9f6
/*
* 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.
*
* $Id: smb_conn.c,v 1.27.166.1 2005/05/27 02:35:29 lindak Exp $
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Connection engine.
*/
#include <sys/socketvar.h>
#include <sys/u8_textprep.h>
#ifdef APPLE
#include <sys/smb_apple.h>
#include <sys/smb_iconv.h>
#else
#include <netsmb/smb_osdep.h>
#endif
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
#include <netsmb/smb_tran.h>
#include <netsmb/smb_pass.h>
static struct smb_connobj smb_vclist;
int
smb_sm_init(void)
{
return (0);
}
int
smb_sm_idle(void)
{
int error = 0;
SMBSDEBUG("%d connections still active\n",
}
return (error);
}
void
smb_sm_done(void)
{
/*
* XXX Q4BP why are we not iterating on smb_vclist here?
* Because the caller has just called smb_sm_idle() to
* make sure we have no VCs before calling this.
*/
}
/*
* Common code for connection object
*/
/*ARGSUSED*/
void
{
}
/*
* Called just before free of an object
* of which smb_connobj is a part, i.e.
* _vc_free, _share_free, also sm_done.
*/
void
{
}
static void
struct smb_connobj *parent,
struct smb_connobj *child)
{
/*
* Set the child's pointer to the parent.
* No references yet, so no need to lock.
*/
/*
* Add the child to the parent's list of
* children, and in-line smb_co_hold
*/
parent->co_usecount++;
}
void
{
cp->co_usecount++;
}
/*
* Called via smb_vc_rele, smb_share_rele
*/
void
{
struct smb_connobj *parent;
int old_flags;
co->co_usecount--;
return;
}
co->co_usecount = 0;
/*
* This list of children should be empty now.
* Check this while we're still linked, so
* we have a better chance of debugging.
*/
/*
* OK, this element is going away.
*
* We need to drop the lock on this CO so we can take the
* parent CO lock. The _GONE flag prevents this CO from
* getting new references before we can unlink it from the
* parent list.
*
* The _GONE flag is also used to ensure that the co_gone
* function is called only once. Note that smb_co_kill may
* do this before we get here. If we find that the _GONE
* flag was not already set, then call the co_gone hook
* (smb_share_gone, smb_vc_gone) which will disconnect
* the share or the VC, respectively.
*
* Note the old: smb_co_gone(co, scred);
* is now in-line here.
*/
/*
* If we have a parent (only smb_vclist does not)
* then unlink from parent's list of children.
* We have the only reference to the child.
*/
if (parent) {
}
}
/*
* Now it's safe to free the CO
*/
}
/*
* Finally, if the CO had a parent, decrement
* the parent's hold count for the lost child.
*/
if (parent) {
/*
* Recursive call here (easier for debugging).
* Can only go two levels.
*/
}
}
/*
* Do just the first part of what co_gone does,
* i.e. tree disconnect, or disconnect a VC.
* This is used to forcibly close things.
*/
void
{
int old_flags;
/*
* Do the same "call only once" logic here as in
* smb_co_rele, though it's probably not possible
* for this to be called after smb_co_rele.
*/
/* XXX: Walk list of children and kill those too? */
}
/*
* Session objects, which are referred to as "VC" for
* "virtual cirtuit". This has nothing to do with the
* CIFS notion of a "virtual cirtuit". See smb_conn.h
*/
void
{
}
void
{
}
void
{
}
/*
* Normally called via smb_vc_rele()
* after co_usecount drops to zero.
* Also called via: smb_vc_kill()
*
* Shutdown the VC to this server,
* invalidate shares linked with it.
*/
/*ARGSUSED*/
static void
{
/*
* Was smb_vc_disconnect(vcp);
*/
}
/*
* The VC has no more references. Free it.
* No locks needed here.
*/
static void
{
/*
* The _gone call should have emptied the request list,
* but let's make sure, as requests may have references
* to this VC without taking a hold. (The hold is the
* responsibility of threads placing requests.)
*/
/*
* We are not using the iconv routines here. So commenting them for now.
* REVISIT.
*/
#ifdef NOTYETDEFINED
if (vcp->vc_tolower)
if (vcp->vc_toupper)
if (vcp->vc_tolocal)
if (vcp->vc_toserver)
#endif
}
/*ARGSUSED*/
int
{
static char objtype[] = "smb_vc";
int error = 0;
/* Expanded TAILQ_HEAD_INITIALIZER */
/*
* These identify the connection.
*/
/* This fills in vcp->vc_tdata */
goto errout;
/* Success! */
return (0);
/*
* This will destroy the new vc.
* See: smb_vc_free
*/
return (error);
}
/*
* Find or create a VC identified by the info in ossn
* and return it with a "hold", but not locked.
*/
/*ARGSUSED*/
int
{
struct smb_connobj *co;
int error;
/* var, head, next_field */
/*
* Some things we can check without
* holding the lock (those that are
* set at creation and never change).
*/
/* VCs in other zones are invisibile. */
continue;
/* Also segregate by Unix owner. */
continue;
/*
* Compare identifying info:
* server address, user, domain
* names are case-insensitive
*/
sizeof (vc_id->id_srvaddr)))
continue;
continue;
continue;
/*
* We have a match, but still have to check
* the _GONE flag, and do that with a lock.
* No new references when _GONE is set.
*
* Also clear SMBVOPT_CREATE which the caller
* may check to find out if we did create.
*/
/*
* Return it held, unlocked.
* In-line smb_vc_hold here.
*/
co->co_usecount++;
error = 0;
goto out;
}
/* keep looking. */
}
/* Note: smb_vclist is still locked. */
/*
* Create a new VC. It starts out with
* hold count = 1, so don't incr. here.
*/
if (error == 0)
} else
out:
return (error);
}
/*
* Helper functions that operate on VCs
*/
/*
* Get a pointer to the IP address suitable for passing to Trusted
* Extensions find_tpc() routine. Used by smbfs_mount_label_policy().
* Compare this code to nfs_mount_label_policy() if problems arise.
*/
void *
{
void *ret;
case AF_INET:
*ipvers = IPV4_VERSION;
break;
case AF_INET6:
*ipvers = IPV6_VERSION;
break;
default:
SMBSDEBUG("invalid address family %d\n",
*ipvers = 0;
break;
}
return (ret);
}
void
{
/*
* Walk the share list calling func(ssp, arg)
*/
}
}
/*
* Share implementation
*/
void
{
}
void
{
}
void
{
}
/*
* Normally called via smb_share_rele()
* after co_usecount drops to zero.
* Also called via: smb_share_kill()
*/
static void
{
}
/*
* Normally called via smb_share_rele()
* after co_usecount drops to zero.
*/
static void
{
}
/*
* Allocate share structure and attach it to the given VC
* Connection expected to be locked on entry. Share will be returned
* in locked state.
*/
/*ARGSUSED*/
int
{
static char objtype[] = "smb_ss";
sizeof (smbioc_oshare_t));
return (0);
}
/*
* Find or create a share under the given VC
* and return it with a "hold", but not locked.
*/
int
{
struct smb_connobj *co;
int error = 0;
/* var, head, next_field */
/* Share name */
continue;
/*
* We have a match, but still have to check
* the _GONE flag, and do that with a lock.
* No new references when _GONE is set.
*
* Also clear SMBSOPT_CREATE which the caller
* may check to find out if we did create.
*/
/*
* Return it held, unlocked.
* In-line smb_share_hold here.
*/
co->co_usecount++;
error = 0;
goto out;
}
/* keep looking. */
}
/* Note: vcp (list of shares) is still locked. */
/*
* Create a new share. It starts out with
* hold count = 1, so don't incr. here.
*/
if (error == 0)
} else
out:
return (error);
}
/*
* Helper functions that operate on shares
*/
/*
* Mark this share as invalid, so consumers will know
* their file handles have become invalid.
*
* Most share consumers store a copy of ss_vcgenid when
* opening a file handle and compare that with what's in
* the share before using a file handle. If the genid
* doesn't match, the file handle has become "stale"
* due to disconnect. Therefore, zap ss_vcgenid here.
*/
void
{
ssp->ss_vcgenid = 0;
}
/*
* Connect (or reconnect) a share object.
*
* Called by smb_usr_get_tree() for new connections,
* and called by smb_rq_enqueue() for reconnect.
*/
int
{
int error;
SMBIODEBUG("alread connected?");
error = 0;
goto out;
}
/*
* Wait for completion of any state changes
* that might be underway.
*/
ssp->ss_conn_waiters++;
ssp->ss_conn_waiters--;
if (tmo == 0) {
/* Interrupt! */
goto out;
}
}
/* Did someone else do it for us? */
error = 0;
goto out;
}
/*
* OK, we'll do the work.
*/
/*
* Drop the lock while doing the TCON.
* On success, sets ss_tid, ss_vcgenid,
* and ss_flags |= SMBS_CONNECTED;
*/
/* They can all go ahead! */
if (ssp->ss_conn_waiters)
out:
return (error);
}
/*
* Solaris zones support
*/
/*ARGSUSED*/
void
{
/* good place for a breakpoint */
DEBUG_ENTER("lingering VC");
}
/*
* On zone shutdown, kill any IOD threads still running in this zone.
*/
/* ARGSUSED */
void
{
struct smb_connobj *co;
continue;
/*
* This will close the connection, and
* cause the IOD thread to terminate.
*/
}
}
/*
* On zone destroy, kill any IOD threads and free all resources they used.
*/
/* ARGSUSED */
void
{
struct smb_connobj *co;
/*
* We will repeat what should have already happened
* in zone_shutdown to make things go away.
*
* There should have been an smb_vc_rele call
* by now for all VCs in the zone. If not,
* there's probably more we needed to do in
* the shutdown call.
*/
SMBERROR("%d connections still active\n",
}
/* var, head, next_field */
continue;
/* Debugging */
}
}