/*
* 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_subr.c,v 1.27.108.1 2005/06/02 00:55:39 lindak Exp $
*/
/*
*/
#include <sys/isa_defs.h>
#include <sys/u8_textprep.h>
#include <netsmb/smb_osdep.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
/*
* XXX:This conversion might not be fully MS-Compatible
* for calculating hashes. The output length may differ
* for some locales and needs to be handled from where
* the call is made.
*/
int
{
int err = 0;
/* inrem, outrem are bytes unused, remaining */
if (inrem) {
}
if (outrem) {
}
SMBSDEBUG("outlen > inlen! (%d > %d)\n",
/* Truncate to inlen here? */
}
return (err);
}
void
{
/* cr arg is optional */
cr = ddi_get_cred();
if (is_system_labeled()) {
} else {
}
}
void
{
}
}
/*
* Helper for the SMBERROR macro, etc.
* This is also a good place for a breakpoint
* or a dtrace probe, i.e. fbt:nsmb:smb_errmsg
*/
void
{
/*
* This is one of our xxxDEBUG macros.
* Don't bother to log these, but just
* fire a dtrace probe with the message.
*/
(char *), func_name,
(char *), buf);
} else {
/*
* This is one of our xxxERROR macros.
* Add a prefix to the fmt string,
* then let vcmn_err do the args.
*/
(char *), func_name,
(char *), buf,
}
}
#if 1 /* def SMB_SOCKETDATA_DEBUG */
void
{
m = m->b_cont;
}
}
#endif
#ifndef EPROTO
#endif
#ifndef ELIBACC
#endif
#ifndef ENODATA
#endif
#ifndef ENOTUNIQ
#endif
#ifndef ECOMM
#endif
#ifndef ENOMEDIUM
#endif
#ifndef ETIME
#endif
/*
* Log any un-handled NT or DOS errors we encounter.
* Make these log NOTICE in a debug build to ensure
* they get noticed during tests. In the field these
* are unimportant, so just fire a Dtrace probe.
*/
static int unknown_err_logpri =
#ifdef DEBUG
#else
#endif
typedef struct nt2errno {
unsigned int nterr;
int errno;
} nt2errno_t;
/* Alphabetical order. */
{0, 0}
};
/*
* Rows ordered by integer value of last column (NT STATUS)
*/
typedef struct nt2doserr {
unsigned short dclass;
unsigned short derr;
unsigned int nterr;
} nt2doserr_t;
{ERRHRD, ERRgeneral,
{0, 0, 0}
};
int
{
switch (NT_SC_SEVERITY(nterr)) {
return (0);
}
/* first try direct map to unix */
"No direct map for 32 bit server error (0x%x)\n", nterr);
/* ok, then try mapping to dos to unix */
return (EIO);
}
int
{
return (0);
switch (eclass) {
case ERRDOS:
switch (eno) {
case ERROR_INVALID_LEVEL:
return (ENOTSUP);
case ERRbadfunc:
case ERRbadenv:
case ERRbadformat:
case ERRremcd:
case ERRrmuns:
return (EINVAL);
case ERRbadfile:
case ERRbadpath:
case ERROR_BAD_DEV_TYPE:
case ERROR_BAD_NET_NAME:
return (ENOENT);
case ERRnofids:
return (EMFILE);
case ERRnoaccess:
/*
* XXX CSM Reported on samba-technical 12/7/2002
*
* There is a case for which server(s) return
* ERRnoaccess but should return ERRdiskfull: When
* the offset for a write is exactly the server
* file size limit then Samba (at least) thinks
* the reason for zero bytes having been written
* must have been "access denied" from the local
* filesystem. This cannot be easily worked
* around since the server behaviour is
* indistinguishable from actual access denied.
* An incomplete workaround: attempt a 2 byte write
* from "offset-1". (That may require reading at
* offset-1 first.) The flaw is that reading or
* writing at offset-1 could cause an
* unrelated error (due to a byte range lock
* for instance) and we can't presume the
* order servers check errors in.
*/
case ERRbadaccess:
return (EACCES);
case ERRbadshare:
return (EBUSY);
case ERRbadfid:
return (EBADF);
case ERRbadmcb:
return (EIO);
case ERRnomem:
return (ENOMEM); /* actually remote no mem... */
case ERRbadmem:
return (EFAULT);
case ERRbaddata:
return (E2BIG);
case ERRbaddrive:
case ERRnotready: /* nt */
return (ENXIO);
case ERRdiffdevice:
return (EXDEV);
case ERRnofiles:
return (0); /* eeof ? */
case ERRlock:
return (EAGAIN);
case ERRfilexists:
return (EEXIST);
case ERROR_INVALID_NAME:
return (ENOENT);
case ERROR_DIR_NOT_EMPTY:
return (ENOTEMPTY);
case ERROR_NOT_LOCKED:
return (0); /* we unlock on any close */
case ERROR_ALREADY_EXISTS:
return (EEXIST);
case ERRmoredata:
return (EMOREDATA);
}
break;
case ERRSRV:
switch (eno) {
case ERRerror:
return (EINVAL);
case ERRbadpw:
return (EAUTH);
case ERRaccess:
case ERRbaduid:
return (EACCES);
case ERRinvnid:
return (ENETRESET);
case ERRinvnetname:
return (ENXIO);
case ERRbadtype: /* reserved and returned */
return (EIO);
case NERR_AccountExpired: /* account exists but disabled */
return (EPERM);
}
break;
case ERRHRD:
switch (eno) {
case ERRnowrite:
return (EROFS);
case ERRbadunit:
return (ENODEV);
case ERRbadreq:
return (EBADRPC);
case ERRbadshare:
return (ETXTBSY);
case ERRlock:
return (EAGAIN);
case ERRdiskfull:
return (EFBIG);
case ERRnotready:
case ERRbadcmd:
case ERRdata:
case ERRgeneral:
return (EIO);
}
}
return (EIO);
}
#if defined(NOICONVSUPPORT) || defined(lint)
#endif
/*ARGSUSED*/
int
{
int error;
if (size <= 0)
return (0);
/*
* Handle the easy case (non-unicode).
* XXX: Technically, we should convert
* the string to OEM codeset first...
* Modern servers all use Unicode, so
* this is good enough.
*/
if (SMB_UNICODE_STRINGS(vcp) == 0) {
return (error);
}
/*
* Convert to UCS-2 (really UTF-16).
* Use stack buffer if the string is
* small enough, else allocate.
*/
if (size <= SMALL_CONV) {
cbufalloc = 0;
outlen = SMALL_CONV;
} else {
}
if (!error) {
}
if (cbufalloc)
return (error);
}
int
int caseopt)
{
/*
* Let smb_put_dmem put both the string
* and the terminating null.
*/
if (error)
return (error);
return (error);
}