2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * Currently, only ONE standalone namespace is supported. 2N/A * ns_name The name of the exported namespace. This will be the only 2N/A * exported namespace until hosting multiple namespaces 2N/A * ns_path The filesystem path of the root share. 2N/A * ns_exported B_TRUE if a standalone namespace is exported 2N/A * ns_cache Caches links' UNC and filesystem path where 2N/A * the key is the UNC path. 2N/A * Namespace cache node operations 2N/A * System's NetBIOS name 2N/A * Lock for accessing root information (extended attribute) 2N/A * Namespace functions 2N/A * DFS module initialization: 2N/A * - gets system's NetBIOS name 2N/A * - installs interposition ops 2N/A * DFS module cleanup: 2N/A * - destroys the namespace cache 2N/A * To successfully handle some of link/root requests, some 2N/A * file system operations need to be performed. These operations 2N/A * should take place on behalf of the connected user (typically 2N/A * Administrator) and to do so we need to have an infrastructure 2N/A * in place so that smbd can act as a client and sends request to 2N/A * the kernel. Right now, we lack this infrastructure, so we make 2N/A * a compromise by temporarily enabling some privileges for smbd 2N/A * ======================== 2N/A * Namespace API (public) 2N/A * ======================== 2N/A * Sets up a dfs_ns_t structure for the specified namespace 2N/A * (root share) if a namespace hasn't already been exported. 2N/A " Only one standalone namespace is supported." 2N/A " A namespace is already exported for %s:%s.",
2N/A * If the specified namespace is exported, the cache 2N/A * will be destroyed and the namespace is marked as 2N/A * If no name is specified then the active namespace 2N/A * will be unexported if there is one. 2N/A * Returns the file system path for the given namespace. 2N/A * Returns the number of DFS root shares i.e. the number 2N/A * of standalone namespaces. 2N/A * The caller must be holding the namespace lock (dfsns.ns_lock) 2N/A * for at least reading. 2N/A * If this call fails, let's assume there's at least one root 2N/A * namespace already configured. The interposer library cannot 2N/A * confirm or deny the presence of a namespace, so let's take 2N/A * the safe approach and assume one exists. 2N/A "assuming one namespace exists",
rc);
2N/A * Creates a DFS root with the given name and comment. 2N/A * This function does not create the root share, it 2N/A * should already exist. 2N/A /* Windows has a special case here! */ 2N/A /* For now only allow a single standalone namespace */ 2N/A "dfs: trying to create %s:%s namespace." 2N/A " Only one standalone namespace is supported." 2N/A " A namespace is already exported for %s:%s",
2N/A /* This DFS root is already exported */ 2N/A " Only one standalone namespace is supported." 2N/A " A namespace is already exported for %s:%s.",
2N/A * Removes the namespace and all the links in it. 2N/A * do not remove links for fedfs namespaces 2N/A * When fedfs namespaces are destroyed, the 2N/A * entire dataset will be destroyed. 2N/A * Determines the DFS namespace flavor. 2N/A /* get flavor info from state info (info level 2) */ 2N/A * Adds the given target to the link in the specified namespace. 2N/A * It will update the cache if this is a new link 2N/A * Removes the given target from the link in the specified namespace. 2N/A * If the link is removed as a result the cache will be updated. 2N/A /* relpath may contain '/' */ 2N/A * if link is removed then try to remove its 2N/A * empty parent directories if any 2N/A * Returns the number of links + 1 (for root) in the 2N/A * specified namespace if this is the exported one 2N/A * The caller must be holding the namespace lock 2N/A * (dfsns.ns_lock) for writing. 2N/A * Returns B_TRUE if a namespace of the specified 2N/A * type exists in namespace cache. 2N/A * The caller must be holding the namespace lock 2N/A * (dfsns.ns_lock) for at least reading. 2N/A * Locks the namespace for writing. 2N/A * Used during iteration. 2N/A * Unlocks the namespace 2N/A * Returns the first node in the namespace cache. 2N/A * The first node in the cache is the root of the 2N/A * The caller must be holding the namespace lock 2N/A * (dfsns.ns_lock) for at least reading. 2N/A * Returns the next node in the namespace cache after 2N/A * The caller must be holding the namespace lock 2N/A * (dfsns.ns_lock) for at least reading. 2N/A * ================== 2N/A * ================== 2N/A * Retrieves the information of the root specified by its path. 2N/A * Info level (1) only needs the UNC path which is not stored, 2N/A * it is constructed so the function will return without 2N/A * accessing the backend storage. 2N/A * The dfs root in backend storage must be of the same namespace 2N/A * type as requested. 2N/A * Sets the provided information for the specified root or root target. 2N/A * Root is specified by 'rootdir' and the target is specified by 2N/A * (t_server, t_share) pair. Only information items needed for given 2N/A * information level (infolvl) is valid in the passed DFS info structure 2N/A * ================== 2N/A * ================== 2N/A * Gets the status of the given path as a link 2N/A * Creates a new DFS link or adds a new target to an existing link 2N/A * Optional verification of link target existence is not implemented. 2N/A * If DFS_RESTORE_VOLUME is not specified on the Flags parameter, 2N/A * the server MAY choose to verify whether the link target exists. 2N/A * If DFS_RESTORE_VOLUME is specified, the server MUST NOT perform 2N/A * this test. If it performs the test and the link target does not 2N/A * exist, the server MUST fail the call with NERR_NetNameNotFound. 2N/A /* Create a new DFS link */ 2N/A * A reparse point can not contain both DFS and 2N/A * Add a target to an existing link only 2N/A * if DFS_ADD_VOLUME flag is not specified. 2N/A * The comment MUST be ignored when 2N/A * adding a target to an existing link. 2N/A /* specified path points to a non-reparse object */ 2N/A /* checks to see if the target already exists */ 2N/A /* add the new target */ 2N/A * Removes a link or a link target from a DFS namespace. A link can be 2N/A * removed regardless of the number of targets associated with it. 2N/A * 'server' and 'share' parameters specify a target, so if they are NULL 2N/A * it means the link should be removed, otherwise the specified target 2N/A * is removed if found. 2N/A /* remove the link */ 2N/A /* remove the specified target in the link */ 2N/A /* checks to see if the target exists */ 2N/A /* if last target, then remove the link */ 2N/A * Sets the provided information for the specified link or link target. 2N/A * Link is specified by 'path' and the target is specified by 2N/A * (t_server, t_share) pair. Only information items needed for given 2N/A * information level (infolvl) is valid in the passed DFS info structure 2N/A * Gets the DFS link info. 2N/A * If path is NULL, it just does some initialization. 2N/A * Info level (1) only needs the UNC path which is not 2N/A * stored, it is constructed so the function will return 2N/A * without accessing the backend storage. 2N/A * ================== 2N/A * ================== 2N/A * Takes a DFS path in UNC format (dfs_path) and parse it into a dfs_path_t 2N/A * dfs_path_free() MUST be called to free the allocated memory in this 2N/A * ERROR_INVALID_PARAMETER path is not a valid UNC or not valid for the 2N/A * specified object type 2N/A * ERROR_NOT_ENOUGH_MEMORY not enough memory to peform the parse 2N/A * ERROR_NOT_FOUND namespace specified does not exist 2N/A * Frees the allocated memory for p_unc field of the passed path 2N/A * Free the allocated memory for targets in the given info 2N/A * Trace the given DFS info structure 2N/A * Removes DFS links and empty directories. 2N/A * Deletes the specified root information 2N/A * Opens DFS root directory's extended attribute with the given mode. 2N/A * Closes given extended attribute file descriptor 2N/A * Writes the given DFS data in the DFS root directory's 2N/A * extended attribute specified with xfd file descriptor. 2N/A * Reads DFS root information from its directory extended attribute 2N/A * and parse it into given dfs_info_t structure 2N/A * Encodes (packs) DFS information in 'info' into a flat 2N/A * buffer in a name-value format. This function allocates a 2N/A * buffer with appropriate size to contain all the information 2N/A * so the caller MUST free the allocated memory by calling free(). 2N/A * Decodes (unpack) provided buffer which contains a list of name-value 2N/A * pairs into given dfs_info_t structure 2N/A * If not defined, use SMB-DFS 2N/A /* need target information */ 2N/A /* need target and priority information */ 2N/A * Determines if the passed state is valid for a DFS root 2N/A * This is based on test results against Win2003 and in some cases 2N/A * does not match [MS-DFSNM] spec. 2N/A * Stores given information for the specified link 2N/A * Determines if the passed state is valid for a link 2N/A * Initializes the given target structure (t) with provided information. 2N/A * Lookup the specified target (server, share) in the given 2N/A * target list (targets). If there is a match its index is 2N/A * returned, otherwise -1 will be returned. 2N/A * Determines if the passed state is valid for a link/root target 2N/A * Compare function used by smb_avl_t 2N/A * starting from DFS root directory, scans the tree for DFS links 2N/A * and adds them to the cache. 2N/A * The caller must be holding the namespace lock (dfsns.ns_lock) for writing. 2N/A * Creates a cache for the given namespace, traverse 2N/A * the file system starting from the given path looking 2N/A * for all the links and load their information into the 2N/A * The caller must be holding the namespace lock (dfsns.ns_lock) for writing. 2N/A * only cache referrals for DFS namespaces 2N/A * If this namespace hasn't been cached then return 2N/A * without flushing the cache; otherwise flush and 2N/A * destroy the cache. 2N/A * The caller must be holding the namespace lock 2N/A * (dfsns.ns_lock) for writing. 2N/A * Determines whether the given path is a directory. 2N/A * Creates intermediate directories of a link from the root share path. 2N/A * TODO: directories should be created by smbsrv to get Windows compatible 2N/A /* drop the link itself from the path */ 2N/A * Removes empty directories 2N/A /* drop the link itself from the path */ 2N/A * Validates the given state based on the object type (root/link), info 2N/A * level, and whether it is the object's state or its target's state 2N/A * Validates the given property flag mask based on the object 2N/A * Based on the specified information level (infolvl) copy parts of the 2N/A * information provided through newinfo into the existing information 2N/A * (info) for the given object. 2N/A * states specified by this mask should not be stored 2N/A * return service type string from namespace type 2N/A * return namespace type from service type string 2N/A /* default to SMB-DFS */