/*
* 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
*/
/*
*/
/*
* Functions supporting Solaris Extended Attributes,
* used to provide access to CIFS "named streams".
*/
#include <sys/sysmacros.h>
#include <sys/u8_textprep.h>
#include <netsmb/smb_osdep.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
#include <smbfs/smbfs_node.h>
#include <smbfs/smbfs_subr.h>
/*
* Solaris wants there to be a directory node to contain
* all the extended attributes. The SMB protocol does not
* really support a directory here, and uses very different
* operations to list attributes, etc. so we "fake up" an
* smbnode here to represent the attributes directory.
*
* We need to give this (fake) directory a unique identity,
* and since we're using the full remote pathname as the
* unique identity of all nodes, the easiest thing to do
* here is append a colon (:) to the given pathname.
*
* There are several places where smbfs_fullpath and its
* callers must decide what separator to use when building
* a remote path name, and the rule is now as follows:
* 1: When no XATTR involved, use "\\" as the separator.
* 2: Traversal into the (fake) XATTR dir adds one ":"
* 3: Children of the XATTR dir add nothing (sep=0)
* The result should be _one_ colon before the attr name.
*/
/* ARGSUSED */
int
{
/*
* We don't allow recursive extended attributes
* (xattr under xattr dir.) so the "parent" node
* (pnp) must NOT be an XATTR directory or file.
*/
return (EINVAL);
&smbfs_fattr0); /* force create */
/* Note: xvp has a VN_HOLD, which our caller expects. */
/* If it's a new node, initialize. */
}
/* Success! */
return (0);
}
/*
* Find the parent of an XATTR directory or file,
* by trimming off the ":attrname" part of rpath.
* Called on XATTR files to get the XATTR dir, and
* called on the XATTR dir to get the real object
* under which the (faked up) XATTR dir lives.
*/
int
{
int rplen;
return (EINVAL);
/*
* Want the parent of the XATTR directory.
* That's easy: just remove trailing ":"
*/
if (rplen < 1) {
SMBVDEBUG("rplen < 1?");
return (ENOENT);
}
SMBVDEBUG("last is not colon");
return (ENOENT);
}
} else {
/*
* Want the XATTR directory given
* one of its XATTR files (children).
* Find the ":" and trim after it.
*/
break;
/* Should have found ":stream_name" */
SMBVDEBUG("colon not found");
return (ENOENT);
}
rplen++; /* keep the ":" */
SMBVDEBUG("no stream name");
return (ENOENT);
}
}
&smbfs_fattr0); /* force create */
/* Note: have VN_HOLD from smbfs_node_findcreate */
return (0);
}
/*
* This is called by smbfs_pathconf to find out
* if some file has any extended attributes.
* There's no short-cut way to find out, so we
* just list the attributes the usual way and
* check for an empty result.
*
* Returns 1: (exists) or 0: (none found)
*/
int
{
/* Get the xattr dir */
if (error)
return (0);
/* NB: have VN_HOLD on xpv */
if (error)
goto out;
if (error)
goto out;
/* Have at least one named stream. */
rc = 1;
out:
/* NB: Always call findclose, error or not. */
(void) smbfs_xa_findclose(&ctx);
return (rc);
}
/*
* This is called to get attributes (size, etc.) of either
* the "faked up" XATTR directory or a named stream.
*/
int
{
/*
* Simulate smbfs_smb_getfattr() for a named stream.
* OK to leave a,c,m times zero (expected w/ XATTR).
* The XATTR directory is easy (all fake).
*/
return (0);
}
/*
* Do a lookup in the XATTR directory,
* using the stream name (last part)
* from the xattr node.
*/
if (error)
return (error);
/* Note: pvp has a VN_HOLD */
/* Get stream name (ptr and length) */
/* Note: this can allocate a new "name" */
return (error);
}
/*
* Fetch the entire attribute list here in findopen.
* Will parse the results in findnext.
*
* This is called on the XATTR directory, so we
* have to get the (real) parent object first.
*/
/* ARGSUSED */
int
{
int error;
if (error)
return (error);
/* Note: pvp has a VN_HOLD */
}
if (error)
goto out;
(void) mb_put_uint32le(mbp, 0);
if (error)
goto out;
if (error) {
}
/*
* No returned parameters to parse.
* Returned data are in t2_rdata,
* which we'll parse in _findnext.
* However, save the wildcard.
*/
out:
return (error);
}
/*
* Get the next name in an XATTR directory into f_name
*/
/* ARGSUSED */
int
{
}
return (ENOENT);
/* Parse FILE_STREAM_INFORMATION */
return (ENOENT);
return (ENOENT);
/*
* Copy the string, but skip the first char (":")
* Watch out for zero-length strings here.
*/
if (size >= 2) {
}
} else {
if (size >= 1) {
}
}
if (error)
return (error);
/*
* Convert UCS-2 to UTF-8
*/
if (nmlen)
else
SMBVDEBUG("null name!\n");
/*
* Skip padding until next offset
*/
}
if (next == 0)
/*
* Chop off the trailing ":$DATA"
* The 6 here is strlen(":$DATA")
*/
*p = '\0'; /* Chop! */
}
}
/*
* The Chop above will typically leave
* an empty name in the first slot,
* which we will skip here.
*/
goto again;
/*
* If this is a lookup of a specific name,
* skip past any non-matching names.
*/
goto again;
goto again;
}
return (0);
}
/*
* NB: also used by smbfs_smb_lookup
*/
int
{
return (0);
}