/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* This has the fall-back logic for IP6, IP4, NBT
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <libintl.h>
#include <xti.h>
#include <assert.h>
#include <sys/byteorder.h>
#include "smbfs_lib.h"
#include "smbfs_nb_lib.h"
#include "smbfs_charsets.h"
#include "smbfs_private.h"
/*
* SMB messages are up to 64K.
* Let's leave room for two.
*/
/*
* Internal set sockopt for int-sized options.
*/
static int
{
struct {
int ival;
} opts;
/* opt header */
return (errno);
return (EPROTO);
}
DPRINT("flags 0x%x, status 0x%x",
return (EPROTO);
}
return (0);
}
static int
{
int err;
/*
* Failures here are not fatal -
* just log a complaint.
*
* We don't need these two:
* SO_RCVTIMEO, SO_SNDTIMEO
*/
if (err) {
}
if (err) {
}
if (err) {
}
if (err) {
}
/* Set the connect timeout (in milliseconds). */
smb_connect_timeout * 1000);
if (err) {
}
return (0);
}
static int
{
return (EINVAL);
}
DPRINT("tcp6: %s (%d)",
if (fd < 0) {
/* Assume t_errno = TSYSERR */
return (err);
}
goto errout;
else
goto errout;
}
goto errout;
}
return (0);
return (err);
}
/*
* This is used for both SMB over TCP (port 445)
* and NetBIOS - see conn_nbt().
*/
static int
{
return (EINVAL);
}
DPRINT("tcp4: %s (%d)",
if (fd < 0) {
/* Assume t_errno = TSYSERR */
return (err);
}
goto errout;
else
goto errout;
}
goto errout;
}
return (0);
return (err);
}
/*
* Open a NetBIOS connection (session, port 139)
*
* The optional name parameter, if passed, means
* we found the sockaddr via NetBIOS name lookup,
* and can just use that for our session request.
* Otherwise (if name is NULL), we're connecting
* by IP address, and need to come up with the
* NetBIOS name by other means.
*/
static int
{
switch (sin.sin_family) {
case AF_NETBIOS: /* our fake AF */
break;
case AF_INET:
break;
default:
return (EINVAL);
}
/*
* If we have a NetBIOS name, just use it.
* This is the path taken when we've done a
* NetBIOS name lookup on this name to get
* the IP address in the passed sa. Otherwise,
* we're connecting by IP address, and need to
* figure out what NetBIOS name to use.
*/
if (name) {
} else {
/*
*
* Try a NetBIOS node status query,
* which searches for a type=[20] name.
* If that doesn't work, just use the
* (fake) "*SMBSERVER" name.
*/
DPRINT("try node status");
server[0] = '\0';
/* Found the name. Save for reconnect. */
sizeof (ctx->ct_srvname));
} else {
}
}
/*
* Establish the TCP connection.
* Careful to close it on errors.
*/
goto out;
}
/* Connected. Do NetBIOS session request. */
if (err)
out:
if (err) {
}
}
return (err);
}
/*
* Make a new connection, or reconnect.
*/
int
{
DPRINT("sername not set!");
return (EINVAL);
}
if (smbfs_debug)
/*
* This may be a reconnect, so
* cleanup if necessary.
*/
}
/*
* Get local machine name.
* Full name - not a NetBIOS name.
*/
if (err) {
"can't get local name"), err);
return (err);
}
}
/*
* We're called with each IP address
* already copied into ct_srvaddr.
*/
case AF_INET6:
break;
case AF_INET:
/*
* If port 445 was not listening, try port 139.
* Note: Not doing NetBIOS name lookup here.
* We already have the IP address.
*/
switch (err) {
case ECONNRESET:
case ECONNREFUSED:
if (err2 == 0)
err = 0;
}
break;
case AF_NETBIOS:
/* Like AF_INET, but use NetBIOS ssn. */
break;
default:
break;
}
if (err) {
return (err);
}
/*
* SMB Negotiate Protocol and
* SMB Session Setup, one of 3 ways:
* NULL session
* Extended security,
* NTLM (v2, v1)
*
* Empty user name means an explicit request for
* NULL session setup. No fall-back logic here.
*
* For NULL session, don't offer extended security.
* That's a lot simpler than dealing with NTLMSSP.
*/
if (err)
goto out;
} else {
/*
* Do SMB Negotiate Protocol.
*/
if (err)
goto out;
/*
* Do SMB Session Setup (authenticate)
*
* If the server negotiated extended security,
* run the SPNEGO state machine.
*/
} else {
/*
* Server did NOT negotiate extended security.
* Try NTLMv2, NTLMv1 (if enabled).
*/
if ((ctx->ct_authflags &
(SMB_AT_NTLM2 | SMB_AT_NTLM1)) == 0) {
/*
* Don't return EAUTH, because a
* new password will not help.
*/
DPRINT("No NTLM authflags");
goto out;
}
else
}
}
/* Tell library code we have a session. */
out:
if (err) {
} else
return (err);
}