/*
* 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
*/
/*
*/
/*
* Net DFS server side RPC service for managing DFS namespaces.
*
* For more details refer to following Microsoft specification:
* [MS-DFSNM]
* Distributed File System (DFS): Namespace Management Protocol Specification
*/
#include <unistd.h>
#include <strings.h>
#include <sys/sysmacros.h>
#include <smbsrv/libntsvcs.h>
#include <dfs.h>
/*
* Depends on the information level requested around 4000 or more links
* can be provided with this buffer size. The limitation here is due
*
* - Do NOT increase the buffer size until that problem is fixed
* - The buffer size should be increased when the problem is fixed
* so the 4000 link limitation is removed.
*/
typedef struct netdfs_enumhandle_t {
static int netdfs_s_getver(void *, ndr_xa_t *);
static int netdfs_s_add(void *, ndr_xa_t *);
static int netdfs_s_remove(void *, ndr_xa_t *);
static int netdfs_s_setinfo(void *, ndr_xa_t *);
static int netdfs_s_getinfo(void *, ndr_xa_t *);
static int netdfs_s_enum(void *, ndr_xa_t *);
static int netdfs_s_move(void *, ndr_xa_t *);
static int netdfs_s_rename(void *, ndr_xa_t *);
static int netdfs_s_addstdroot(void *, ndr_xa_t *);
static int netdfs_s_remstdroot(void *, ndr_xa_t *);
static int netdfs_s_enumex(void *, ndr_xa_t *);
const char *, const char *);
const char *, const char *);
uint32_t *);
uint32_t *);
uint32_t *);
uint32_t *);
uint32_t *);
uint32_t *);
uint32_t *);
uint32_t *);
{ netdfs_s_add, NETDFS_OPNUM_ADD },
{0}
};
"NETDFS", /* name */
"DFS", /* desc */
"\\netdfs", /* endpoint */
PIPE_NETDFS, /* sec_addr_port */
0, /* no bind_instance_size */
0, /* no bind_req() */
0, /* no unbind_and_close() */
0, /* use generic_call_stub() */
netdfs_stub_table /* stub_table */
};
/*
* Register the NETDFS RPC interface with the RPC runtime library.
* The service must be registered in order to use either the client
* side or the server side functions.
*/
void
netdfs_initialize(void)
{
(void) ndr_svc_register(&netdfs_service);
dfs_init();
}
void
netdfs_finalize(void)
{
dfs_fini();
}
/*
* Returns the version number of the DFS server in use on the server.
*
* [MS-DFSNM]: NetrDfsManagerGetVersion (Opnum 0)
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* Creates a new DFS link or adds a new target to an existing link of a
* DFS namespace.
*
* [MS-DFSNM]: NetrDfsAdd (Opnum 1)
*/
static int
{
if (!ndr_is_admin(mxa)) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
case DFS_CREATE_VOLUME:
case DFS_ADD_VOLUME:
case DFS_RESTORE_VOLUME:
case (DFS_ADD_VOLUME | DFS_RESTORE_VOLUME):
break;
default:
return (NDR_DRC_OK);
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* Removes a link or a link target from a DFS namespace. A link can be
* removed regardless of the number of targets associated with it.
*
* [MS-DFSNM]: NetrDfsRemove (Opnum 2)
*/
static int
{
if (!ndr_is_admin(mxa)) {
return (NDR_DRC_OK);
}
/* both server and share must be NULL or non-NULL */
return (NDR_DRC_OK);
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* Sets or modifies information relevant to a specific DFS root, DFS root
* target, DFS link, or DFS link target
*
* [MS-DFSNM]: NetrDfsSetInfo (Opnum 3)
*/
/*ARGSUSED*/
static int
{
/* both server and share must be NULL or non-NULL */
return (NDR_DRC_OK);
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
}
case 100:
break;
case 101:
break;
case 102:
break;
case 103:
break;
case 104:
break;
case 105:
break;
default:
break;
}
return (NDR_DRC_OK);
}
/*
* Returns information about a DFS root or a DFS link of the specified
* DFS namespace.
*
* [MS-DFSNM]: NetrDfsGetInfo (Opnum 4)
*/
static int
{
const char *fspath;
if (status != ERROR_SUCCESS)
goto getinfo_error;
goto getinfo_error;
}
} else {
}
if (status != ERROR_SUCCESS)
goto getinfo_error;
switch (level) {
case 1:
}
break;
case 2:
}
break;
case 3:
}
break;
case 4:
}
break;
case 5:
}
break;
case 6:
}
break;
case 100:
}
break;
default:
break;
}
if (status != ERROR_SUCCESS)
return (NDR_DRC_OK);
}
/*
* Enumerates the DFS root hosted on a server or the DFS links of the
* namespace hosted by a server. Depending on the information level,
* the targets of the root and links are also displayed.
*
* For level 300, only one DFS root info is returned, no DFS links info.
* ERROR_DEVICE_NOT_AVAILABLE is returned if multiple namespaces are
* hosted by a server.
*
* For unsupported levels, it should return ERROR_INVALID_LEVEL as
* Microsoft does for DFS server on Win2000 and NT.
*
* [MS-DFSNM]: NetrDfsEnum (Opnum 5)
*/
/*ARGSUSED*/
static int
{
goto enum_error;
}
if (!dfs_ns_exists(SMB_NS_DFS)) {
goto enum_error;
}
if ((nroot = dfs_ns_count()) == 0)
else if (nroot > 1)
if (status != ERROR_SUCCESS)
goto enum_error;
goto enum_error;
}
else
goto enum_error;
}
*param->resume_handle = 0;
}
switch (level) {
case 1:
entsize = sizeof (netdfs_info1_t);
goto enum_error;
}
break;
case 2:
entsize = sizeof (netdfs_info2_t);
goto enum_error;
}
break;
case 3:
entsize = sizeof (netdfs_info3_t) +
sizeof (netdfs_storage_info_t);
goto enum_error;
}
break;
case 4:
entsize = sizeof (netdfs_info4_t) +
sizeof (netdfs_storage_info_t);
goto enum_error;
}
break;
case 5:
entsize = sizeof (netdfs_info5_t);
goto enum_error;
}
break;
case 6:
entsize = sizeof (netdfs_info6_t) +
sizeof (netdfs_storage_info1_t);
goto enum_error;
}
break;
case 300:
entsize = sizeof (netdfs_info300_t);
goto enum_error;
}
break;
default:
break;
}
return (NDR_DRC_OK);
}
/*
* Renames or moves a DFS link
*
* Does not need to be supported for DFS version 1
*
* [MS-DFSNM]: NetrDfsMove (Opnum 6)
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* According to [MS-DFSNM] spec this operation (opnum 7) is not
* used over the wire.
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* Creates a new standalone DFS namespace
*
* [MS-DFSNM]: NetrDfsAddStdRoot (Opnum 12)
*/
/*ARGSUSED*/
static int
{
if (!ndr_is_admin(mxa)) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* Deletes the specified stand-alone DFS namespace. The DFS namespace can be
* removed without first removing all of the links in it.
*
* [MS-DFSNM]: NetrDfsRemoveStdRoot (Opnum 13)
*/
/*ARGSUSED*/
static int
{
if (ndr_is_admin(mxa))
else
return (NDR_DRC_OK);
}
/*
* Enumerates the DFS roots hosted on a server, or DFS links of a namespace
* hosted by the server. Depending on the information level, the targets
* associated with the roots and links are also displayed
*
* Does not need to be supported for DFS version 1
*
* [MS-DFSNM] NetrDfsEnumEx (Opnum 21)
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
*/
static uint32_t
{
else
return (status);
}
/*
*/
static uint32_t
{
} else {
}
else
return (status);
}
/*
*/
static uint32_t
{
else
return (status);
}
/*
* Sets the property flags for the root or link.
*/
static uint32_t
{
else
return (status);
}
/*
* Sets the target priority rank and class for the root target or link target
*/
static uint32_t
{
return (ERROR_INVALID_PARAMETER);
return (ERROR_INVALID_PARAMETER);
return (ERROR_INVALID_PARAMETER);
else
return (status);
}
/*
* Sets the comment, state, time-out information, and property flags for the
* namespace root or link specified in DfsInfo. Does not apply to a root target
* or link target.
*/
static uint32_t
{
if (flavor == 0)
return (ERROR_INTERNAL_ERROR);
else
return (status);
}
/*
* DFS_STORAGE_INFO: target information
*/
static uint32_t
{
int i;
if (info->i_ntargets == 0)
return (ERROR_SUCCESS);
return (ERROR_NOT_ENOUGH_MEMORY);
return (ERROR_NOT_ENOUGH_MEMORY);
}
return (ERROR_SUCCESS);
}
/*
* DFS_STORAGE_INFO_1: target information
*/
static uint32_t
{
int i;
if (info->i_ntargets == 0)
return (ERROR_SUCCESS);
return (ERROR_NOT_ENOUGH_MEMORY);
storage->p_reserved = 0;
return (ERROR_NOT_ENOUGH_MEMORY);
}
return (ERROR_SUCCESS);
}
/*
*/
static uint32_t
{
return (ERROR_NOT_ENOUGH_MEMORY);
*size = sizeof (netdfs_info1_t) +
return (ERROR_SUCCESS);
}
/*
*/
static uint32_t
{
void *entry_path;
void *comment;
return (ERROR_NOT_ENOUGH_MEMORY);
*size = sizeof (netdfs_info2_t) +
return (ERROR_SUCCESS);
}
/*
*/
static uint32_t
{
void *entry_path;
void *comment;
return (ERROR_NOT_ENOUGH_MEMORY);
*size = sizeof (netdfs_info3_t) +
}
/*
*/
static uint32_t
{
void *entry_path;
void *comment;
return (ERROR_NOT_ENOUGH_MEMORY);
return (ERROR_INVALID_DATA);
*size = sizeof (netdfs_info4_t) +
}
/*
*/
static uint32_t
{
void *entry_path;
void *comment;
return (ERROR_NOT_ENOUGH_MEMORY);
return (ERROR_INVALID_DATA);
info5->metadata_sz = 0;
*size = sizeof (netdfs_info5_t) +
return (ERROR_SUCCESS);
}
/*
*/
static uint32_t
{
void *entry_path;
void *comment;
return (ERROR_NOT_ENOUGH_MEMORY);
return (ERROR_INVALID_DATA);
info6->metadata_sz = 0;
*size = sizeof (netdfs_info6_t) +
}
/*
* Sets a DFS_INFO_100 for Get response
*/
static uint32_t
{
return (ERROR_NOT_ENOUGH_MEMORY);
*size = sizeof (netdfs_info100_t) +
return (ERROR_SUCCESS);
}
/*
* Sets a DFS_INFO_300 for Enum response
*/
static uint32_t
{
return (ERROR_NOT_ENOUGH_MEMORY);
*size = sizeof (netdfs_info300_t) +
return (ERROR_SUCCESS);
}
/*
* Common enumeration function.
* Caller must be holding namespace lock (dfs_ns_hold)
*/
static uint32_t
{
return (ERROR_SUCCESS);
do {
continue;
continue;
}
break;
if (status != ERROR_SUCCESS)
continue;
case 1:
info1++;
break;
case 2:
info2++;
break;
case 3:
info3++;
break;
case 4:
info4++;
break;
case 5:
info5++;
break;
case 6:
info6++;
break;
case 300:
&itemsz);
info300++;
break;
default:
}
if (status != ERROR_SUCCESS)
return (status);
break;
}
break;
return (ERROR_SUCCESS);
}
/*
* Converts the guid string into binary format in network byte order.
*/
static boolean_t
{
return (B_FALSE);
return (B_TRUE);
}