smb_trans2_dfs.c revision b819cea2f73f98c5662230cc9affc8cc84f77fcf
/*
* 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
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_door.h>
/*
* Get Referral response header flags
* For exact meaning refer to MS-DFSC spec.
*
* R: ReferralServers
* S: StorageServers
* T: TargetFailback
*/
#define DFS_HDRFLG_R 0x00000001
#define DFS_HDRFLG_S 0x00000002
#define DFS_HDRFLG_T 0x00000004
/*
* Entry flags
*/
#define DFS_ENTFLG_T 0x0004
/*
*/
#define DFS_REFERRAL_V1 0x0001
#define DFS_REFERRAL_V2 0x0002
#define DFS_REFERRAL_V3 0x0003
#define DFS_REFERRAL_V4 0x0004
/*
* Valid values for ServerType field in referral entries
*/
#define DFS_SRVTYPE_NONROOT 0x0000
#define DFS_SRVTYPE_ROOT 0x0001
/*
* Size of the fix part for each referral entry type
*/
#define DFS_REFV1_ENTSZ 8
#define DFS_REFV2_ENTSZ 22
#define DFS_REFV3_ENTSZ 34
#define DFS_REFV4_ENTSZ 34
static dfs_reftype_t smb_dfs_get_reftype(const char *);
dfs_info_t *, uint16_t);
static void smb_dfs_referrals_free(dfs_referral_response_t *);
/*
* [MS-CIFS]
*
* 2.2.6.17 TRANS2_REPORT_DFS_INCONSISTENCY (0x0011)
*
* This Transaction2 subcommand was introduced in the NT LAN Manager dialect.
* This subcommand is reserved but not implemented.
*
* Clients SHOULD NOT send requests using this command code. Servers receiving
* requests with this command code SHOULD return STATUS_NOT_IMPLEMENTED
* (ERRDOS/ERRbadfunc).
*/
smb_sdrc_t /*ARGSUSED*/
{
return (SDRC_NOT_IMPLEMENTED);
}
/*
* See [MS-DFSC] for details about this command
*/
{
char *path;
/* This request is only valid over IPC connections */
return (SDRC_ERROR);
}
!= 0) {
return (SDRC_ERROR);
}
switch (reftype) {
case DFS_REFERRAL_INVALID:
/* Need to check the error for this case */
return (SDRC_ERROR);
case DFS_REFERRAL_DOMAIN:
case DFS_REFERRAL_DC:
/* MS-DFSC: this error is returned by non-DC root */
return (SDRC_ERROR);
case DFS_REFERRAL_SYSVOL:
/* MS-DFSC: this error is returned by non-DC root */
return (SDRC_ERROR);
default:
break;
}
if (status != NT_STATUS_SUCCESS)
return (SDRC_ERROR);
/*
* Server can respond with a referral version which is not
* bigger than but could be less than the maximum specified
* in the request.
*/
switch (maxreflvl) {
case DFS_REFERRAL_V1:
break;
case DFS_REFERRAL_V2:
break;
case DFS_REFERRAL_V3:
break;
default:
break;
}
}
/*
* [MS-DFSC]: REQ_GET_DFS_REFERRAL
*
* Determines the referral type based on the specified path:
*
* Domain referral:
* ""
*
* DC referral:
* \<domain>
*
* Sysvol referral:
* \<domain>\SYSVOL
* \<domain>\NETLOGON
*
* Root referral:
* \<domain>\<dfsname>
* \<server>\<dfsname>
*
* Link referral:
* \<domain>\<dfsname>\<linkpath>
* \<server>\<dfsname>\<linkpath>
*/
static dfs_reftype_t
smb_dfs_get_reftype(const char *path)
{
dfs_reftype_t reftype = 0;
if (*path == '\0')
return (DFS_REFERRAL_DOMAIN);
return (DFS_REFERRAL_INVALID);
} else {
}
}
smb_unc_free(&unc);
return (reftype);
}
static void
{
flags |= DFS_HDRFLG_R;
}
static uint32_t
{
uint16_t r;
char *target;
for (r = 0; r < referrals->i_ntargets; r++) {
if (entsize > rep_bufsize)
break;
rep_bufsize -= entsize;
}
/*
* Need room for at least one entry.
* Windows will silently drop targets that do not fit in
* the response buffer.
*/
if (r == 0) {
return (NT_STATUS_BUFFER_OVERFLOW);
}
return (NT_STATUS_SUCCESS);
}
/*
* Prepare a response with V2 referral format.
*
* Here is the response packet format.
* All the strings come after all the fixed size entry headers.
* These headers contain offsets to the strings at the end. Note
* that the two "dfs_path" after the last entry is shared between
* all the entries.
*
* ent1-hdr
* ent2-hdr
* ...
* entN-hdr
* dfs_path
* dfs_path
* target1
* target2
* ...
* targetN
*
* MS-DFSC mentions that strings can come after each entry header or all after
* the last entry header. Windows responses are in the format above.
*/
static uint32_t
{
uint16_t r;
if (entsize > rep_bufsize) {
/* need room for at least one referral */
return (NT_STATUS_BUFFER_OVERFLOW);
}
rep_bufsize -= entsize;
for (r = 0; r < referrals->i_ntargets; r++) {
if (r != 0) {
if (entsize > rep_bufsize)
/* silently drop targets that do not fit */
break;
rep_bufsize -= entsize;
}
}
return (NT_STATUS_SUCCESS);
}
/*
*
* For more details, see comments for smb_dfs_encode_refv2() or see
* MS-DFSC specification.
*/
static uint32_t
{
uint16_t r;
if (entsize > rep_bufsize) {
/* need room for at least one referral */
return (NT_STATUS_BUFFER_OVERFLOW);
}
rep_bufsize -= entsize;
for (r = 0; r < referrals->i_ntargets; r++) {
if (r != 0) {
if (entsize > rep_bufsize)
/* silently drop targets that do not fit */
break;
rep_bufsize -= entsize;
flags = 0;
} else if (ver == DFS_REFERRAL_V4) {
}
}
return (NT_STATUS_SUCCESS);
}
/*
* Encodes DFS path, and target strings which come after fixed header
* entries.
*
* Windows 2000 and earlier set the DFSAlternatePathOffset to point to
* an 8.3 string representation of the string pointed to by
* DFSPathOffset if it is not a legal 8.3 string. Otherwise, if
* DFSPathOffset points to a legal 8.3 string, DFSAlternatePathOffset
* points to a separate copy of the same string. Windows Server 2003,
* Windows Server 2008 and Windows Server 2008 R2 set the
* DFSPathOffset and DFSAlternatePathOffset fields to point to separate
* copies of the identical string.
*
* Following Windows 2003 and later here.
*/
static void
{
char *target;
int r;
for (r = 0; r < referrals->i_ntargets; r++) {
}
}
/*
* Get referral information for the specified path from user space
* using a door call.
*/
static uint32_t
{
int rc;
return (NT_STATUS_NO_SUCH_DEVICE);
}
return (NT_STATUS_SUCCESS);
}
static void
{
}
/*
* Returns the Unicode string length for the target UNC of
* the specified entry by 'refno'
*
* Note that the UNC path should be encoded with ONE leading
* slash not two as is common to user-visible UNC paths.
*/
static uint16_t
{
return (0);
/* Encoded target UNC \server\share */
return (len);
}