1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22148c5f43SAlan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23c13be35aSGordon Ross * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw 26bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 27da6c28aaSamw #include <smbsrv/smb_fsops.h> 28da6c28aaSamw #include <sys/pathname.h> 29da6c28aaSamw #include <sys/sdt.h> 30da6c28aaSamw 318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static char *smb_pathname_catia_v5tov4(smb_request_t *, char *, char *, int); 328b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static char *smb_pathname_catia_v4tov5(smb_request_t *, char *, char *, int); 338b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static int smb_pathname_lookup(pathname_t *, pathname_t *, int, 349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States vnode_t **, vnode_t *, vnode_t *, smb_attr_t *attr, cred_t *); 35fe1c642dSBill Krier static char *smb_pathname_strdup(smb_request_t *, const char *); 36fe1c642dSBill Krier static char *smb_pathname_strcat(smb_request_t *, char *, const char *); 37fe1c642dSBill Krier static void smb_pathname_preprocess(smb_request_t *, smb_pathname_t *); 389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_pathname_preprocess_quota(smb_request_t *, smb_pathname_t *); 399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_pathname_dfs_preprocess(smb_request_t *, char *, size_t); 409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_pathname_preprocess_adminshare(smb_request_t *, 419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *); 429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 438b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 44da6c28aaSamw uint32_t 45da6c28aaSamw smb_is_executable(char *path) 46da6c28aaSamw { 47da6c28aaSamw char extension[5]; 48da6c28aaSamw int len = strlen(path); 49da6c28aaSamw 50da6c28aaSamw if ((len >= 4) && (path[len - 4] == '.')) { 51da6c28aaSamw (void) strcpy(extension, &path[len - 3]); 52bbf6f00cSJordan Brown (void) smb_strupr(extension); 53da6c28aaSamw 54da6c28aaSamw if (strcmp(extension, "EXE") == 0) 55da6c28aaSamw return (NODE_FLAGS_EXECUTABLE); 56da6c28aaSamw 57da6c28aaSamw if (strcmp(extension, "COM") == 0) 58da6c28aaSamw return (NODE_FLAGS_EXECUTABLE); 59da6c28aaSamw 60da6c28aaSamw if (strcmp(extension, "DLL") == 0) 61da6c28aaSamw return (NODE_FLAGS_EXECUTABLE); 62da6c28aaSamw 63da6c28aaSamw if (strcmp(extension, "SYM") == 0) 64da6c28aaSamw return (NODE_FLAGS_EXECUTABLE); 65da6c28aaSamw } 66da6c28aaSamw 67da6c28aaSamw return (0); 68da6c28aaSamw } 69da6c28aaSamw 70da6c28aaSamw /* 71da6c28aaSamw * smb_pathname_reduce 72da6c28aaSamw * 73da6c28aaSamw * smb_pathname_reduce() takes a path and returns the smb_node for the 74da6c28aaSamw * second-to-last component of the path. It also returns the name of the last 75da6c28aaSamw * component. Pointers for both of these fields must be supplied by the caller. 76da6c28aaSamw * 77da6c28aaSamw * Upon success, 0 is returned. 78da6c28aaSamw * 79da6c28aaSamw * Upon error, *dir_node will be set to 0. 80da6c28aaSamw * 81da6c28aaSamw * *sr (in) 82da6c28aaSamw * --- 83da6c28aaSamw * smb_request structure pointer 84da6c28aaSamw * 85da6c28aaSamw * *cred (in) 86da6c28aaSamw * ----- 87da6c28aaSamw * credential 88da6c28aaSamw * 89da6c28aaSamw * *path (in) 90da6c28aaSamw * ----- 91da6c28aaSamw * pathname to be looked up 92da6c28aaSamw * 93da6c28aaSamw * *share_root_node (in) 94da6c28aaSamw * ---------------- 95da6c28aaSamw * File operations which are share-relative should pass sr->tid_tree->t_snode. 96da6c28aaSamw * If the call is not for a share-relative operation, this parameter must be 0 97da6c28aaSamw * (e.g. the call from smbsr_setup_share()). (Such callers will have path 98da6c28aaSamw * operations done using root_smb_node.) This parameter is used to determine 99da6c28aaSamw * whether mount points can be crossed. 100da6c28aaSamw * 101da6c28aaSamw * share_root_node should have at least one reference on it. This reference 102da6c28aaSamw * will stay intact throughout this routine. 103da6c28aaSamw * 104da6c28aaSamw * *cur_node (in) 105da6c28aaSamw * --------- 106da6c28aaSamw * The smb_node for the current directory (for relative paths). 107da6c28aaSamw * cur_node should have at least one reference on it. 108da6c28aaSamw * This reference will stay intact throughout this routine. 109da6c28aaSamw * 110da6c28aaSamw * **dir_node (out) 111da6c28aaSamw * ---------- 112da6c28aaSamw * Directory for the penultimate component of the original path. 113da6c28aaSamw * (Note that this is not the same as the parent directory of the ultimate 114da6c28aaSamw * target in the case of a link.) 115da6c28aaSamw * 116da6c28aaSamw * The directory smb_node is returned held. The caller will need to release 117da6c28aaSamw * the hold or otherwise make sure it will get released (e.g. in a destroy 118da6c28aaSamw * routine if made part of a global structure). 119da6c28aaSamw * 120da6c28aaSamw * last_component (out) 121da6c28aaSamw * -------------- 122da6c28aaSamw * The last component of the path. (This may be different from the name of any 123da6c28aaSamw * link target to which the last component may resolve.) 124da6c28aaSamw * 125da6c28aaSamw * 126da6c28aaSamw * ____________________________ 127da6c28aaSamw * 128da6c28aaSamw * The CIFS server lookup path needs to have logic equivalent to that of 129da6c28aaSamw * smb_fsop_lookup(), smb_vop_lookup() and other smb_vop_*() routines in the 130da6c28aaSamw * following areas: 131da6c28aaSamw * 1325f1ef25cSAram Hăvărneanu * - traversal of child mounts (handled by smb_pathname_reduce) 1335f1ef25cSAram Hăvărneanu * - unmangling (handled in smb_pathname) 1345f1ef25cSAram Hăvărneanu * - "chroot" behavior of share root (handled by lookuppnvp) 135da6c28aaSamw * 136da6c28aaSamw * In addition, it needs to replace backslashes with forward slashes. It also 137da6c28aaSamw * ensures that link processing is done correctly, and that directory 138da6c28aaSamw * information requested by the caller is correctly returned (i.e. for paths 139da6c28aaSamw * with a link in the last component, the directory information of the 140da6c28aaSamw * link and not the target needs to be returned). 141da6c28aaSamw */ 142da6c28aaSamw 143da6c28aaSamw int 144da6c28aaSamw smb_pathname_reduce( 145da6c28aaSamw smb_request_t *sr, 146da6c28aaSamw cred_t *cred, 147da6c28aaSamw const char *path, 148da6c28aaSamw smb_node_t *share_root_node, 149da6c28aaSamw smb_node_t *cur_node, 150da6c28aaSamw smb_node_t **dir_node, 151da6c28aaSamw char *last_component) 152da6c28aaSamw { 153da6c28aaSamw smb_node_t *root_node; 15489dc44ceSjose borrego pathname_t ppn; 155da6c28aaSamw char *usepath; 156da6c28aaSamw int lookup_flags = FOLLOW; 157da6c28aaSamw int trailing_slash = 0; 158da6c28aaSamw int err = 0; 159da6c28aaSamw int len; 16089dc44ceSjose borrego smb_node_t *vss_cur_node; 16189dc44ceSjose borrego smb_node_t *vss_root_node; 16289dc44ceSjose borrego smb_node_t *local_cur_node; 16389dc44ceSjose borrego smb_node_t *local_root_node; 164da6c28aaSamw 165da6c28aaSamw ASSERT(dir_node); 166da6c28aaSamw ASSERT(last_component); 167da6c28aaSamw 168da6c28aaSamw *dir_node = NULL; 169da6c28aaSamw *last_component = '\0'; 17089dc44ceSjose borrego vss_cur_node = NULL; 17189dc44ceSjose borrego vss_root_node = NULL; 172da6c28aaSamw 1737b59d02dSjb if (sr && sr->tid_tree) { 174f96bd5c8SAlan Wright if (STYPE_ISIPC(sr->tid_tree->t_res_type)) 1757b59d02dSjb return (EACCES); 1767b59d02dSjb } 1777b59d02dSjb 178c8ec8eeaSjose borrego if (SMB_TREE_IS_CASEINSENSITIVE(sr)) 179da6c28aaSamw lookup_flags |= FIGNORECASE; 180da6c28aaSamw 181da6c28aaSamw if (path == NULL) 182da6c28aaSamw return (EINVAL); 183da6c28aaSamw 184da6c28aaSamw if (*path == '\0') 185da6c28aaSamw return (ENOENT); 186da6c28aaSamw 187*b24e356bSPeer Dampmann usepath = kmem_alloc(SMB_MAXPATHLEN, KM_SLEEP); 188da6c28aaSamw 189*b24e356bSPeer Dampmann len = strlcpy(usepath, path, SMB_MAXPATHLEN); 190*b24e356bSPeer Dampmann if (len >= SMB_MAXPATHLEN) { 191*b24e356bSPeer Dampmann kmem_free(usepath, SMB_MAXPATHLEN); 192da6c28aaSamw return (ENAMETOOLONG); 193da6c28aaSamw } 194da6c28aaSamw 195da6c28aaSamw (void) strsubst(usepath, '\\', '/'); 196da6c28aaSamw 197da6c28aaSamw if (share_root_node) 198da6c28aaSamw root_node = share_root_node; 199da6c28aaSamw else 200faa1795aSjb root_node = sr->sr_server->si_root_smb_node; 201da6c28aaSamw 202da6c28aaSamw if (cur_node == NULL) 203da6c28aaSamw cur_node = root_node; 204da6c28aaSamw 20589dc44ceSjose borrego local_cur_node = cur_node; 20689dc44ceSjose borrego local_root_node = root_node; 20789dc44ceSjose borrego 208148c5f43SAlan Wright if (SMB_TREE_IS_DFSROOT(sr) && (sr->smb_flg2 & SMB_FLAGS2_DFS)) { 209*b24e356bSPeer Dampmann err = smb_pathname_dfs_preprocess(sr, usepath, SMB_MAXPATHLEN); 2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (err != 0) { 211*b24e356bSPeer Dampmann kmem_free(usepath, SMB_MAXPATHLEN); 2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (err); 2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States len = strlen(usepath); 2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21789dc44ceSjose borrego if (sr && (sr->smb_flg2 & SMB_FLAGS2_REPARSE_PATH)) { 21889dc44ceSjose borrego err = smb_vss_lookup_nodes(sr, root_node, cur_node, 21989dc44ceSjose borrego usepath, &vss_cur_node, &vss_root_node); 22089dc44ceSjose borrego 22189dc44ceSjose borrego if (err != 0) { 22289dc44ceSjose borrego kmem_free(usepath, MAXPATHLEN); 22389dc44ceSjose borrego return (err); 22489dc44ceSjose borrego } 22589dc44ceSjose borrego 22689dc44ceSjose borrego len = strlen(usepath); 22789dc44ceSjose borrego local_cur_node = vss_cur_node; 22889dc44ceSjose borrego local_root_node = vss_root_node; 22989dc44ceSjose borrego } 23089dc44ceSjose borrego 23189dc44ceSjose borrego if (usepath[len - 1] == '/') 23289dc44ceSjose borrego trailing_slash = 1; 23389dc44ceSjose borrego 23489dc44ceSjose borrego (void) strcanon(usepath, "/"); 23589dc44ceSjose borrego 236*b24e356bSPeer Dampmann (void) pn_alloc_sz(&ppn, SMB_MAXPATHLEN); 237da6c28aaSamw 238da6c28aaSamw if ((err = pn_set(&ppn, usepath)) != 0) { 239da6c28aaSamw (void) pn_free(&ppn); 240*b24e356bSPeer Dampmann kmem_free(usepath, SMB_MAXPATHLEN); 24189dc44ceSjose borrego if (vss_cur_node != NULL) 24289dc44ceSjose borrego (void) smb_node_release(vss_cur_node); 24389dc44ceSjose borrego if (vss_root_node != NULL) 24489dc44ceSjose borrego (void) smb_node_release(vss_root_node); 245da6c28aaSamw return (err); 246da6c28aaSamw } 247da6c28aaSamw 248da6c28aaSamw /* 249da6c28aaSamw * If a path does not have a trailing slash, strip off the 250da6c28aaSamw * last component. (We only need to return an smb_node for 251da6c28aaSamw * the second to last component; a name is returned for the 252da6c28aaSamw * last component.) 253da6c28aaSamw */ 254da6c28aaSamw 255da6c28aaSamw if (trailing_slash) { 256da6c28aaSamw (void) strlcpy(last_component, ".", MAXNAMELEN); 257da6c28aaSamw } else { 258da6c28aaSamw (void) pn_setlast(&ppn); 259da6c28aaSamw (void) strlcpy(last_component, ppn.pn_path, MAXNAMELEN); 260da6c28aaSamw ppn.pn_path[0] = '\0'; 261da6c28aaSamw } 262da6c28aaSamw 263fc724630SAlan Wright if ((strcmp(ppn.pn_buf, "/") == 0) || (ppn.pn_buf[0] == '\0')) { 26489dc44ceSjose borrego smb_node_ref(local_cur_node); 26589dc44ceSjose borrego *dir_node = local_cur_node; 266da6c28aaSamw } else { 26789dc44ceSjose borrego err = smb_pathname(sr, ppn.pn_buf, lookup_flags, 26889dc44ceSjose borrego local_root_node, local_cur_node, NULL, dir_node, cred); 269da6c28aaSamw } 270da6c28aaSamw 271da6c28aaSamw (void) pn_free(&ppn); 272*b24e356bSPeer Dampmann kmem_free(usepath, SMB_MAXPATHLEN); 273da6c28aaSamw 274da6c28aaSamw /* 2755f1ef25cSAram Hăvărneanu * Prevent traversal to another file system if mount point 2765f1ef25cSAram Hăvărneanu * traversal is disabled. 277da6c28aaSamw * 278da6c28aaSamw * Note that we disregard whether the traversal of the path went 279da6c28aaSamw * outside of the file system and then came back (say via a link). 2805f1ef25cSAram Hăvărneanu * This means that only symlinks that are expressed relatively to 2815f1ef25cSAram Hăvărneanu * the share root work. 2825f1ef25cSAram Hăvărneanu * 2835f1ef25cSAram Hăvărneanu * share_root_node is NULL when mapping a share, so we disregard 2845f1ef25cSAram Hăvărneanu * that case. 285da6c28aaSamw */ 286da6c28aaSamw 287da6c28aaSamw if ((err == 0) && share_root_node) { 2885f1ef25cSAram Hăvărneanu if (share_root_node->vp->v_vfsp != (*dir_node)->vp->v_vfsp) { 289da6c28aaSamw err = EACCES; 2905f1ef25cSAram Hăvărneanu if ((sr) && (sr)->tid_tree && 2915f1ef25cSAram Hăvărneanu smb_tree_has_feature((sr)->tid_tree, 2925f1ef25cSAram Hăvărneanu SMB_TREE_TRAVERSE_MOUNTS)) 2935f1ef25cSAram Hăvărneanu err = 0; 2945f1ef25cSAram Hăvărneanu } 295da6c28aaSamw } 296da6c28aaSamw 297da6c28aaSamw if (err) { 298da6c28aaSamw if (*dir_node) { 299da6c28aaSamw (void) smb_node_release(*dir_node); 300da6c28aaSamw *dir_node = NULL; 301da6c28aaSamw } 302da6c28aaSamw *last_component = 0; 303da6c28aaSamw } 304da6c28aaSamw 30589dc44ceSjose borrego if (vss_cur_node != NULL) 30689dc44ceSjose borrego (void) smb_node_release(vss_cur_node); 30789dc44ceSjose borrego if (vss_root_node != NULL) 30889dc44ceSjose borrego (void) smb_node_release(vss_root_node); 30989dc44ceSjose borrego 310da6c28aaSamw return (err); 311da6c28aaSamw } 312da6c28aaSamw 313da6c28aaSamw /* 3148b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * smb_pathname() 3158b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * wrapper to lookuppnvp(). Handles name unmangling. 316da6c28aaSamw * 317da6c28aaSamw * *dir_node is the true directory of the target *node. 318da6c28aaSamw * 319da6c28aaSamw * If any component but the last in the path is not found, ENOTDIR instead of 320da6c28aaSamw * ENOENT will be returned. 321da6c28aaSamw * 322da6c28aaSamw * Path components are processed one at a time so that smb_nodes can be 3231fcced4cSJordan Brown * created for each component. This allows the n_dnode field in the 324da6c28aaSamw * smb_node to be properly populated. 325da6c28aaSamw * 3268b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * Because of the above, links are also processed in this routine 3278b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * (i.e., we do not pass the FOLLOW flag to lookuppnvp()). This 3288b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * will allow smb_nodes to be created for each component of a link. 3298b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * 3308b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * Mangle checking is per component. If a name is mangled, when the 3318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * unmangled name is passed to smb_pathname_lookup() do not pass 3328b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * FIGNORECASE, since the unmangled name is the real on-disk name. 3338b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise pass FIGNORECASE if it's set in flags. This will cause the 3348b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * file system to return "first match" in the event of a case collision. 3358b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * 3368b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * If CATIA character translation is enabled it is applied to each 3378b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * component before passing the component to smb_pathname_lookup(). 3388b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * After smb_pathname_lookup() the reverse translation is applied. 339da6c28aaSamw */ 340da6c28aaSamw 341da6c28aaSamw int 3428b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname(smb_request_t *sr, char *path, int flags, 3438b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *root_node, smb_node_t *cur_node, smb_node_t **dir_node, 3448b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t **ret_node, cred_t *cred) 345da6c28aaSamw { 3468b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States char *component, *real_name, *namep; 3478b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States pathname_t pn, rpn, upn, link_pn; 3488b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *dnode, *fnode; 3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_attr_t attr; 3508b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States vnode_t *rootvp, *vp; 351da6c28aaSamw size_t pathleft; 352da6c28aaSamw int err = 0; 353da6c28aaSamw int nlink = 0; 354da6c28aaSamw int local_flags; 355e3f2c991SKeyur Desai uint32_t abe_flag = 0; 3568b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States char namebuf[MAXNAMELEN]; 357da6c28aaSamw 358da6c28aaSamw if (path == NULL) 359da6c28aaSamw return (EINVAL); 360da6c28aaSamw 361da6c28aaSamw ASSERT(root_node); 362da6c28aaSamw ASSERT(cur_node); 363da6c28aaSamw ASSERT(ret_node); 364da6c28aaSamw 365da6c28aaSamw *ret_node = NULL; 366da6c28aaSamw 367da6c28aaSamw if (dir_node) 368da6c28aaSamw *dir_node = NULL; 369da6c28aaSamw 370*b24e356bSPeer Dampmann (void) pn_alloc_sz(&upn, SMB_MAXPATHLEN); 371da6c28aaSamw 372da6c28aaSamw if ((err = pn_set(&upn, path)) != 0) { 373da6c28aaSamw (void) pn_free(&upn); 374da6c28aaSamw return (err); 375da6c28aaSamw } 376da6c28aaSamw 377e3f2c991SKeyur Desai if (SMB_TREE_SUPPORTS_ABE(sr)) 378e3f2c991SKeyur Desai abe_flag = SMB_ABE; 379e3f2c991SKeyur Desai 380da6c28aaSamw (void) pn_alloc(&pn); 381da6c28aaSamw (void) pn_alloc(&rpn); 382da6c28aaSamw 383da6c28aaSamw component = kmem_alloc(MAXNAMELEN, KM_SLEEP); 384da6c28aaSamw real_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); 385da6c28aaSamw 3868b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States fnode = NULL; 387da6c28aaSamw dnode = cur_node; 388da6c28aaSamw smb_node_ref(dnode); 3898b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States rootvp = root_node->vp; 39055bf511dSas 391da6c28aaSamw while ((pathleft = pn_pathleft(&upn)) != 0) { 392da6c28aaSamw if (fnode) { 393da6c28aaSamw smb_node_release(dnode); 394da6c28aaSamw dnode = fnode; 395da6c28aaSamw fnode = NULL; 396da6c28aaSamw } 397da6c28aaSamw 398da6c28aaSamw if ((err = pn_getcomponent(&upn, component)) != 0) 399da6c28aaSamw break; 400da6c28aaSamw 4018b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if ((namep = smb_pathname_catia_v5tov4(sr, component, 4028b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States namebuf, sizeof (namebuf))) == NULL) { 4038b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States err = EILSEQ; 4048b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States break; 405da6c28aaSamw } 406da6c28aaSamw 407da6c28aaSamw if ((err = pn_set(&pn, namep)) != 0) 408da6c28aaSamw break; 409da6c28aaSamw 4108b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States local_flags = flags & FIGNORECASE; 4118b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States err = smb_pathname_lookup(&pn, &rpn, local_flags, 4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &vp, rootvp, dnode->vp, &attr, cred); 413da6c28aaSamw 4148b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (err) { 415cb174861Sjoyce mcintosh if (!SMB_TREE_SUPPORTS_SHORTNAMES(sr) || 416cb174861Sjoyce mcintosh !smb_maybe_mangled(component)) 4178b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States break; 4188b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 419148c5f43SAlan Wright if ((err = smb_unmangle(dnode, component, 420e3f2c991SKeyur Desai real_name, MAXNAMELEN, abe_flag)) != 0) 4218b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States break; 422da6c28aaSamw 4238b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if ((namep = smb_pathname_catia_v5tov4(sr, real_name, 4248b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States namebuf, sizeof (namebuf))) == NULL) { 4258b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States err = EILSEQ; 4268b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States break; 4278b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 428da6c28aaSamw 4298b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if ((err = pn_set(&pn, namep)) != 0) 4308b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States break; 4318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 4328b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States local_flags = 0; 4338b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States err = smb_pathname_lookup(&pn, &rpn, local_flags, 4349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &vp, rootvp, dnode->vp, &attr, cred); 4358b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (err) 4368b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States break; 4378b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 438da6c28aaSamw 4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * This check MUST be done before symlink check 4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * since a reparse point is of type VLNK but should 4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * not be handled like a regular symlink. 4439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 4449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (attr.sa_dosattr & FILE_ATTRIBUTE_REPARSE_POINT) { 4459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States err = EREMOTE; 4469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States VN_RELE(vp); 4479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 4499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 450da6c28aaSamw if ((vp->v_type == VLNK) && 451da6c28aaSamw ((flags & FOLLOW) || pn_pathleft(&upn))) { 452da6c28aaSamw 453da6c28aaSamw if (++nlink > MAXSYMLINKS) { 454da6c28aaSamw err = ELOOP; 4557f667e74Sjose borrego VN_RELE(vp); 456da6c28aaSamw break; 457da6c28aaSamw } 458da6c28aaSamw 459da6c28aaSamw (void) pn_alloc(&link_pn); 460da6c28aaSamw err = pn_getsymlink(vp, &link_pn, cred); 4617f667e74Sjose borrego VN_RELE(vp); 462da6c28aaSamw 4638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (err == 0) { 4648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (pn_pathleft(&link_pn) == 0) 4658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States (void) pn_set(&link_pn, "."); 4668b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States err = pn_insert(&upn, &link_pn, 4678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States strlen(component)); 468da6c28aaSamw } 469da6c28aaSamw pn_free(&link_pn); 470da6c28aaSamw 471da6c28aaSamw if (err) 472da6c28aaSamw break; 473da6c28aaSamw 474da6c28aaSamw if (upn.pn_pathlen == 0) { 475da6c28aaSamw err = ENOENT; 476da6c28aaSamw break; 477da6c28aaSamw } 478da6c28aaSamw 479da6c28aaSamw if (upn.pn_path[0] == '/') { 480da6c28aaSamw fnode = root_node; 481da6c28aaSamw smb_node_ref(fnode); 482da6c28aaSamw } 483da6c28aaSamw 484da6c28aaSamw if (pn_fixslash(&upn)) 485da6c28aaSamw flags |= FOLLOW; 486da6c28aaSamw 487da6c28aaSamw } else { 488da6c28aaSamw if (flags & FIGNORECASE) { 489da6c28aaSamw if (strcmp(rpn.pn_path, "/") != 0) 490da6c28aaSamw pn_setlast(&rpn); 491da6c28aaSamw namep = rpn.pn_path; 4928b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } else { 493da6c28aaSamw namep = pn.pn_path; 4948b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 4958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 4968b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States namep = smb_pathname_catia_v4tov5(sr, namep, 4978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States namebuf, sizeof (namebuf)); 498da6c28aaSamw 499da6c28aaSamw fnode = smb_node_lookup(sr, NULL, cred, vp, namep, 500037cac00Sjoyce mcintosh dnode, NULL); 5017f667e74Sjose borrego VN_RELE(vp); 502da6c28aaSamw 503da6c28aaSamw if (fnode == NULL) { 504da6c28aaSamw err = ENOMEM; 505da6c28aaSamw break; 506da6c28aaSamw } 507da6c28aaSamw } 508da6c28aaSamw 509da6c28aaSamw while (upn.pn_path[0] == '/') { 510da6c28aaSamw upn.pn_path++; 511da6c28aaSamw upn.pn_pathlen--; 512da6c28aaSamw } 5137f667e74Sjose borrego 514da6c28aaSamw } 515da6c28aaSamw 516da6c28aaSamw if ((pathleft) && (err == ENOENT)) 517da6c28aaSamw err = ENOTDIR; 518da6c28aaSamw 519da6c28aaSamw if (err) { 520da6c28aaSamw if (fnode) 521da6c28aaSamw smb_node_release(fnode); 522da6c28aaSamw if (dnode) 523da6c28aaSamw smb_node_release(dnode); 524da6c28aaSamw } else { 525da6c28aaSamw *ret_node = fnode; 526da6c28aaSamw 527da6c28aaSamw if (dir_node) 528da6c28aaSamw *dir_node = dnode; 529da6c28aaSamw else 530da6c28aaSamw smb_node_release(dnode); 531da6c28aaSamw } 532da6c28aaSamw 533da6c28aaSamw kmem_free(component, MAXNAMELEN); 534da6c28aaSamw kmem_free(real_name, MAXNAMELEN); 535da6c28aaSamw (void) pn_free(&pn); 536da6c28aaSamw (void) pn_free(&rpn); 537da6c28aaSamw (void) pn_free(&upn); 538da6c28aaSamw 539da6c28aaSamw return (err); 540da6c28aaSamw } 54189dc44ceSjose borrego 5428b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /* 5438b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * Holds on dvp and rootvp (if not rootdir) are required by lookuppnvp() 5448b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * and will be released within lookuppnvp(). 5458b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States */ 5468b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static int 5478b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_lookup(pathname_t *pn, pathname_t *rpn, int flags, 5489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States vnode_t **vp, vnode_t *rootvp, vnode_t *dvp, smb_attr_t *attr, cred_t *cred) 5498b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States { 5508b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States int err; 5518b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5528b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States *vp = NULL; 5538b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States VN_HOLD(dvp); 5548b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (rootvp != rootdir) 5558b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States VN_HOLD(rootvp); 5568b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5578b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States err = lookuppnvp(pn, rpn, flags, NULL, vp, rootvp, dvp, cred); 5589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((err == 0) && (attr != NULL)) 5598622ec45SGordon Ross (void) smb_vop_getattr(*vp, NULL, attr, 0, zone_kcred()); 5609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 5618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States return (err); 5628b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 5638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /* 5658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * CATIA Translation of a pathname component prior to passing it to lookuppnvp 5668b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * 5678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * If the translated component name contains a '/' NULL is returned. 5688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * The caller should treat this as error EILSEQ. It is not valid to 5698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * have a directory name with a '/'. 5708b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States */ 5718b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static char * 5728b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_catia_v5tov4(smb_request_t *sr, char *name, 5738b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States char *namebuf, int buflen) 5748b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States { 5758b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States char *namep; 5768b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5778b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_TREE_SUPPORTS_CATIA(sr)) { 5788b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States namep = smb_vop_catia_v5tov4(name, namebuf, buflen); 5798b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (strchr(namep, '/') != NULL) 5808b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 5818b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States return (namep); 5828b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 5838b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5848b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States return (name); 5858b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 5868b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5878b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /* 5888b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * CATIA translation of a pathname component after returning from lookuppnvp 5898b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States */ 5908b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static char * 5918b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_catia_v4tov5(smb_request_t *sr, char *name, 5928b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States char *namebuf, int buflen) 5938b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States { 5948b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_TREE_SUPPORTS_CATIA(sr)) { 5958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_vop_catia_v4tov5(name, namebuf, buflen); 5968b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States return (namebuf); 5978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 5988b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 5998b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States return (name); 6008b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 6018b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 60289dc44ceSjose borrego /* 60389dc44ceSjose borrego * sr - needed to check for case sense 60489dc44ceSjose borrego * path - non mangled path needed to be looked up from the startvp 60589dc44ceSjose borrego * startvp - the vnode to start the lookup from 60689dc44ceSjose borrego * rootvp - the vnode of the root of the filesystem 60789dc44ceSjose borrego * returns the vnode found when starting at startvp and using the path 60889dc44ceSjose borrego * 60989dc44ceSjose borrego * Finds a vnode starting at startvp and parsing the non mangled path 61089dc44ceSjose borrego */ 61189dc44ceSjose borrego 61289dc44ceSjose borrego vnode_t * 61389dc44ceSjose borrego smb_lookuppathvptovp(smb_request_t *sr, char *path, vnode_t *startvp, 61489dc44ceSjose borrego vnode_t *rootvp) 61589dc44ceSjose borrego { 61689dc44ceSjose borrego pathname_t pn; 61789dc44ceSjose borrego vnode_t *vp = NULL; 61889dc44ceSjose borrego int lookup_flags = FOLLOW; 61989dc44ceSjose borrego 62089dc44ceSjose borrego if (SMB_TREE_IS_CASEINSENSITIVE(sr)) 62189dc44ceSjose borrego lookup_flags |= FIGNORECASE; 62289dc44ceSjose borrego 62389dc44ceSjose borrego (void) pn_alloc(&pn); 62489dc44ceSjose borrego 62589dc44ceSjose borrego if (pn_set(&pn, path) == 0) { 626037cac00Sjoyce mcintosh VN_HOLD(startvp); 62789dc44ceSjose borrego if (rootvp != rootdir) 62889dc44ceSjose borrego VN_HOLD(rootvp); 62989dc44ceSjose borrego 63089dc44ceSjose borrego /* lookuppnvp should release the holds */ 63189dc44ceSjose borrego if (lookuppnvp(&pn, NULL, lookup_flags, NULL, &vp, 6328622ec45SGordon Ross rootvp, startvp, zone_kcred()) != 0) { 63389dc44ceSjose borrego pn_free(&pn); 63489dc44ceSjose borrego return (NULL); 63589dc44ceSjose borrego } 63689dc44ceSjose borrego } 63789dc44ceSjose borrego 63889dc44ceSjose borrego pn_free(&pn); 63989dc44ceSjose borrego return (vp); 64089dc44ceSjose borrego } 641fe1c642dSBill Krier 642fe1c642dSBill Krier /* 643fe1c642dSBill Krier * smb_pathname_init 644fe1c642dSBill Krier * Parse path: pname\\fname:sname:stype 645fe1c642dSBill Krier * 646fe1c642dSBill Krier * Elements of the smb_pathname_t structure are allocated using request 647fe1c642dSBill Krier * specific storage and will be free'd when the sr is destroyed. 648fe1c642dSBill Krier * 649fe1c642dSBill Krier * Populate pn structure elements with the individual elements 650fe1c642dSBill Krier * of pn->pn_path. pn->pn_sname will contain the whole stream name 651fe1c642dSBill Krier * including the stream type and preceding colon: :sname:%DATA 652fe1c642dSBill Krier * pn_stype will point to the stream type within pn_sname. 653fe1c642dSBill Krier * 6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If the pname element is missing pn_pname will be set to NULL. 655fe1c642dSBill Krier * If any other element is missing the pointer in pn will be NULL. 656fe1c642dSBill Krier */ 657fe1c642dSBill Krier void 658fe1c642dSBill Krier smb_pathname_init(smb_request_t *sr, smb_pathname_t *pn, char *path) 659fe1c642dSBill Krier { 660fe1c642dSBill Krier char *pname, *fname, *sname; 661fe1c642dSBill Krier int len; 662fe1c642dSBill Krier 663fe1c642dSBill Krier bzero(pn, sizeof (smb_pathname_t)); 664fe1c642dSBill Krier pn->pn_path = smb_pathname_strdup(sr, path); 665fe1c642dSBill Krier 666fe1c642dSBill Krier smb_pathname_preprocess(sr, pn); 667fe1c642dSBill Krier 668fe1c642dSBill Krier /* parse pn->pn_path into its constituent parts */ 669fe1c642dSBill Krier pname = pn->pn_path; 670fe1c642dSBill Krier fname = strrchr(pn->pn_path, '\\'); 671fe1c642dSBill Krier 672fe1c642dSBill Krier if (fname) { 673fe1c642dSBill Krier if (fname == pname) { 6749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn->pn_pname = NULL; 675fe1c642dSBill Krier } else { 676fe1c642dSBill Krier *fname = '\0'; 677fe1c642dSBill Krier pn->pn_pname = 678fe1c642dSBill Krier smb_pathname_strdup(sr, pname); 679fe1c642dSBill Krier *fname = '\\'; 680fe1c642dSBill Krier } 681fe1c642dSBill Krier ++fname; 682fe1c642dSBill Krier } else { 683fe1c642dSBill Krier fname = pname; 6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn->pn_pname = NULL; 685fe1c642dSBill Krier } 686fe1c642dSBill Krier 687fe1c642dSBill Krier if (fname[0] == '\0') { 688fe1c642dSBill Krier pn->pn_fname = NULL; 689fe1c642dSBill Krier return; 690fe1c642dSBill Krier } 691fe1c642dSBill Krier 692fe1c642dSBill Krier if (!smb_is_stream_name(fname)) { 693fe1c642dSBill Krier pn->pn_fname = smb_pathname_strdup(sr, fname); 694fe1c642dSBill Krier return; 695fe1c642dSBill Krier } 696fe1c642dSBill Krier 697fe1c642dSBill Krier /* 698fe1c642dSBill Krier * find sname and stype in fname. 699fe1c642dSBill Krier * sname can't be NULL smb_is_stream_name checks this 700fe1c642dSBill Krier */ 701fe1c642dSBill Krier sname = strchr(fname, ':'); 702fe1c642dSBill Krier if (sname == fname) 703fe1c642dSBill Krier fname = NULL; 704fe1c642dSBill Krier else { 705fe1c642dSBill Krier *sname = '\0'; 706fe1c642dSBill Krier pn->pn_fname = 707fe1c642dSBill Krier smb_pathname_strdup(sr, fname); 708fe1c642dSBill Krier *sname = ':'; 709fe1c642dSBill Krier } 710fe1c642dSBill Krier 711fe1c642dSBill Krier pn->pn_sname = smb_pathname_strdup(sr, sname); 712fe1c642dSBill Krier pn->pn_stype = strchr(pn->pn_sname + 1, ':'); 713fe1c642dSBill Krier if (pn->pn_stype) { 714fe1c642dSBill Krier (void) smb_strupr(pn->pn_stype); 715fe1c642dSBill Krier } else { 716fe1c642dSBill Krier len = strlen(pn->pn_sname); 717fe1c642dSBill Krier pn->pn_sname = smb_pathname_strcat(sr, pn->pn_sname, ":$DATA"); 718fe1c642dSBill Krier pn->pn_stype = pn->pn_sname + len; 719fe1c642dSBill Krier } 720fe1c642dSBill Krier ++pn->pn_stype; 721fe1c642dSBill Krier } 722fe1c642dSBill Krier 723fe1c642dSBill Krier /* 724fe1c642dSBill Krier * smb_pathname_preprocess 725fe1c642dSBill Krier * 726fe1c642dSBill Krier * Perform common pre-processing of pn->pn_path: 727fe1c642dSBill Krier * - if the pn_path is blank, set it to '\\' 728fe1c642dSBill Krier * - perform unicode wildcard converstion. 729fe1c642dSBill Krier * - convert any '/' to '\\' 730fe1c642dSBill Krier * - eliminate duplicate slashes 731fe1c642dSBill Krier * - remove trailing slashes 7329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * - quota directory specific pre-processing 733fe1c642dSBill Krier */ 734fe1c642dSBill Krier static void 735fe1c642dSBill Krier smb_pathname_preprocess(smb_request_t *sr, smb_pathname_t *pn) 736fe1c642dSBill Krier { 737fe1c642dSBill Krier char *p; 738fe1c642dSBill Krier 739fe1c642dSBill Krier /* treat empty path as "\\" */ 740fe1c642dSBill Krier if (strlen(pn->pn_path) == 0) { 741fe1c642dSBill Krier pn->pn_path = smb_pathname_strdup(sr, "\\"); 742fe1c642dSBill Krier return; 743fe1c642dSBill Krier } 744fe1c642dSBill Krier 745c13be35aSGordon Ross if (sr->session->dialect < NT_LM_0_12) 746c13be35aSGordon Ross smb_convert_wildcards(pn->pn_path); 747fe1c642dSBill Krier 748fe1c642dSBill Krier /* treat '/' as '\\' */ 749fe1c642dSBill Krier (void) strsubst(pn->pn_path, '/', '\\'); 750fe1c642dSBill Krier 751fe1c642dSBill Krier (void) strcanon(pn->pn_path, "\\"); 752fe1c642dSBill Krier 753fe1c642dSBill Krier /* remove trailing '\\' */ 754fe1c642dSBill Krier p = pn->pn_path + strlen(pn->pn_path) - 1; 755fe1c642dSBill Krier if ((p != pn->pn_path) && (*p == '\\')) 756fe1c642dSBill Krier *p = '\0'; 7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_preprocess_quota(sr, pn); 7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_preprocess_adminshare(sr, pn); 7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 7639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * smb_pathname_preprocess_quota 7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 7659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * There is a special file required by windows so that the quota 7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * tab will be displayed by windows clients. This is created in 7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * a special directory, $EXTEND, at the root of the shared file 7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * system. To hide this directory prepend a '.' (dot). 7699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 7709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_preprocess_quota(smb_request_t *sr, smb_pathname_t *pn) 7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *name = "$EXTEND"; 7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *new_name = ".$EXTEND"; 7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *p, *slash; 7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int len; 7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_node_is_vfsroot(sr->tid_tree->t_snode)) 7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return; 7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States p = pn->pn_path; 7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* ignore any initial "\\" */ 7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States p += strspn(p, "\\"); 7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_strcasecmp(p, name, strlen(name)) != 0) 7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return; 7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States p += strlen(name); 7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((*p != ':') && (*p != '\\') && (*p != '\0')) 7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return; 7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States slash = (pn->pn_path[0] == '\\') ? "\\" : ""; 7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States len = strlen(pn->pn_path) + 2; 7949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn->pn_path = smb_srm_alloc(sr, len); 7959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(pn->pn_path, len, "%s%s%s", slash, new_name, p); 7969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_strupr(pn->pn_path); 7979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 8009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * smb_pathname_preprocess_adminshare 8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 8029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Convert any path with share name "C$" or "c$" (Admin share) in to lower case. 8039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 8049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 8059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_preprocess_adminshare(smb_request_t *sr, smb_pathname_t *pn) 8069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 8079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (strcasecmp(sr->tid_tree->t_sharename, "c$") == 0) 8089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_strlwr(pn->pn_path); 809fe1c642dSBill Krier } 810fe1c642dSBill Krier 811fe1c642dSBill Krier /* 812fe1c642dSBill Krier * smb_pathname_strdup 813fe1c642dSBill Krier * 814fe1c642dSBill Krier * Duplicate NULL terminated string s. 815fe1c642dSBill Krier * 816fe1c642dSBill Krier * The new string is allocated using request specific storage and will 817fe1c642dSBill Krier * be free'd when the sr is destroyed. 818fe1c642dSBill Krier */ 819fe1c642dSBill Krier static char * 820fe1c642dSBill Krier smb_pathname_strdup(smb_request_t *sr, const char *s) 821fe1c642dSBill Krier { 822fe1c642dSBill Krier char *s2; 823fe1c642dSBill Krier size_t n; 824fe1c642dSBill Krier 825fe1c642dSBill Krier n = strlen(s) + 1; 8269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States s2 = smb_srm_zalloc(sr, n); 827fe1c642dSBill Krier (void) strlcpy(s2, s, n); 828fe1c642dSBill Krier return (s2); 829fe1c642dSBill Krier } 830fe1c642dSBill Krier 831fe1c642dSBill Krier /* 832fe1c642dSBill Krier * smb_pathname_strcat 833fe1c642dSBill Krier * 834fe1c642dSBill Krier * Reallocate NULL terminated string s1 to accommodate 835fe1c642dSBill Krier * concatenating NULL terminated string s2. 836fe1c642dSBill Krier * Append s2 and return resulting NULL terminated string. 837fe1c642dSBill Krier * 838fe1c642dSBill Krier * The string buffer is reallocated using request specific 839fe1c642dSBill Krier * storage and will be free'd when the sr is destroyed. 840fe1c642dSBill Krier */ 841fe1c642dSBill Krier static char * 842fe1c642dSBill Krier smb_pathname_strcat(smb_request_t *sr, char *s1, const char *s2) 843fe1c642dSBill Krier { 844fe1c642dSBill Krier size_t n; 845fe1c642dSBill Krier 846fe1c642dSBill Krier n = strlen(s1) + strlen(s2) + 1; 8479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States s1 = smb_srm_rezalloc(sr, s1, n); 848fe1c642dSBill Krier (void) strlcat(s1, s2, n); 849fe1c642dSBill Krier return (s1); 850fe1c642dSBill Krier } 851fe1c642dSBill Krier 852fe1c642dSBill Krier /* 853fe1c642dSBill Krier * smb_pathname_validate 854fe1c642dSBill Krier * 855fe1c642dSBill Krier * Perform basic validation of pn: 856fe1c642dSBill Krier * - If first component of pn->path is ".." -> PATH_SYNTAX_BAD 857fe1c642dSBill Krier * - If there are wildcards in pn->pn_pname -> OBJECT_NAME_INVALID 858fe1c642dSBill Krier * - If fname is "." -> INVALID_OBJECT_NAME 859fe1c642dSBill Krier * 860fe1c642dSBill Krier * On unix .. at the root of a file system links to the root. Thus 861fe1c642dSBill Krier * an attempt to lookup "/../../.." will be the same as looking up "/" 862fe1c642dSBill Krier * CIFs clients expect the above to result in 863fe1c642dSBill Krier * NT_STATUS_OBJECT_PATH_SYNTAX_BAD. It is currently not possible 864fe1c642dSBill Krier * (and questionable if it's desirable) to deal with all cases 865fe1c642dSBill Krier * but paths beginning with \\.. are handled. 866fe1c642dSBill Krier * 867fe1c642dSBill Krier * Returns: B_TRUE if pn is valid, 868fe1c642dSBill Krier * otherwise returns B_FALSE and sets error status in sr. 869fe1c642dSBill Krier */ 870fe1c642dSBill Krier boolean_t 871fe1c642dSBill Krier smb_pathname_validate(smb_request_t *sr, smb_pathname_t *pn) 872fe1c642dSBill Krier { 873fe1c642dSBill Krier char *path = pn->pn_path; 874fe1c642dSBill Krier 875fe1c642dSBill Krier /* ignore any initial "\\" */ 876fe1c642dSBill Krier path += strspn(path, "\\"); 877fe1c642dSBill Krier 878fe1c642dSBill Krier /* If first component of path is ".." -> PATH_SYNTAX_BAD */ 879fe1c642dSBill Krier if ((strcmp(path, "..") == 0) || (strncmp(path, "..\\", 3) == 0)) { 880fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_OBJECT_PATH_SYNTAX_BAD, 881fe1c642dSBill Krier ERRDOS, ERROR_BAD_PATHNAME); 882fe1c642dSBill Krier return (B_FALSE); 883fe1c642dSBill Krier } 884fe1c642dSBill Krier 885fe1c642dSBill Krier /* If there are wildcards in pn->pn_pname -> OBJECT_NAME_INVALID */ 886fe1c642dSBill Krier if (pn->pn_pname && smb_contains_wildcards(pn->pn_pname)) { 887fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 888fe1c642dSBill Krier ERRDOS, ERROR_INVALID_NAME); 889fe1c642dSBill Krier return (B_FALSE); 890fe1c642dSBill Krier } 891fe1c642dSBill Krier 892fe1c642dSBill Krier /* If fname is "." -> INVALID_OBJECT_NAME */ 893fe1c642dSBill Krier if (pn->pn_fname && (strcmp(pn->pn_fname, ".") == 0)) { 894fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 895fe1c642dSBill Krier ERRDOS, ERROR_PATH_NOT_FOUND); 896fe1c642dSBill Krier return (B_FALSE); 897fe1c642dSBill Krier } 898fe1c642dSBill Krier 899fe1c642dSBill Krier return (B_TRUE); 900fe1c642dSBill Krier } 901fe1c642dSBill Krier 902fe1c642dSBill Krier /* 903fe1c642dSBill Krier * smb_validate_dirname 904fe1c642dSBill Krier * 905fe1c642dSBill Krier * smb_pathname_validate() should have already been performed on pn. 906fe1c642dSBill Krier * 907fe1c642dSBill Krier * Very basic directory name validation: checks for colons in a path. 908fe1c642dSBill Krier * Need to skip the drive prefix since it contains a colon. 909fe1c642dSBill Krier * 910fe1c642dSBill Krier * Returns: B_TRUE if the name is valid, 911fe1c642dSBill Krier * otherwise returns B_FALSE and sets error status in sr. 912fe1c642dSBill Krier */ 913fe1c642dSBill Krier boolean_t 914fe1c642dSBill Krier smb_validate_dirname(smb_request_t *sr, smb_pathname_t *pn) 915fe1c642dSBill Krier { 916fe1c642dSBill Krier char *name; 917fe1c642dSBill Krier char *path = pn->pn_path; 918fe1c642dSBill Krier 919fe1c642dSBill Krier if ((name = path) != 0) { 920fe1c642dSBill Krier name += strspn(name, "\\"); 921fe1c642dSBill Krier 922fe1c642dSBill Krier if (strchr(name, ':') != 0) { 923fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY, 924fe1c642dSBill Krier ERRDOS, ERROR_INVALID_NAME); 925fe1c642dSBill Krier return (B_FALSE); 926fe1c642dSBill Krier } 927fe1c642dSBill Krier } 928fe1c642dSBill Krier 929fe1c642dSBill Krier return (B_TRUE); 930fe1c642dSBill Krier } 931fe1c642dSBill Krier 932fe1c642dSBill Krier /* 933fe1c642dSBill Krier * smb_validate_object_name 934fe1c642dSBill Krier * 935fe1c642dSBill Krier * smb_pathname_validate() should have already been pertformed on pn. 936fe1c642dSBill Krier * 937fe1c642dSBill Krier * Very basic file name validation. 938fe1c642dSBill Krier * For filenames, we check for names of the form "AAAn:". Names that 939fe1c642dSBill Krier * contain three characters, a single digit and a colon (:) are reserved 940fe1c642dSBill Krier * as DOS device names, i.e. "COM1:". 941fe1c642dSBill Krier * Stream name validation is handed off to smb_validate_stream_name 942fe1c642dSBill Krier * 943fe1c642dSBill Krier * Returns: B_TRUE if pn->pn_fname is valid, 944fe1c642dSBill Krier * otherwise returns B_FALSE and sets error status in sr. 945fe1c642dSBill Krier */ 946fe1c642dSBill Krier boolean_t 947fe1c642dSBill Krier smb_validate_object_name(smb_request_t *sr, smb_pathname_t *pn) 948fe1c642dSBill Krier { 949fe1c642dSBill Krier if (pn->pn_fname && 950fe1c642dSBill Krier strlen(pn->pn_fname) == 5 && 951fe1c642dSBill Krier smb_isdigit(pn->pn_fname[3]) && 952fe1c642dSBill Krier pn->pn_fname[4] == ':') { 953fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 954fe1c642dSBill Krier ERRDOS, ERROR_INVALID_NAME); 955fe1c642dSBill Krier return (B_FALSE); 956fe1c642dSBill Krier } 957fe1c642dSBill Krier 958fe1c642dSBill Krier if (pn->pn_sname) 959fe1c642dSBill Krier return (smb_validate_stream_name(sr, pn)); 960fe1c642dSBill Krier 961fe1c642dSBill Krier return (B_TRUE); 962fe1c642dSBill Krier } 963fe1c642dSBill Krier 964fe1c642dSBill Krier /* 965fe1c642dSBill Krier * smb_stream_parse_name 966fe1c642dSBill Krier * 967fe1c642dSBill Krier * smb_stream_parse_name should only be called for a path that 968fe1c642dSBill Krier * contains a valid named stream. Path validation should have 969fe1c642dSBill Krier * been performed before this function is called. 970fe1c642dSBill Krier * 971fe1c642dSBill Krier * Find the last component of path and split it into filename 972fe1c642dSBill Krier * and stream name. 973fe1c642dSBill Krier * 974fe1c642dSBill Krier * On return the named stream type will be present. The stream 975fe1c642dSBill Krier * type defaults to ":$DATA", if it has not been defined 976fe1c642dSBill Krier * For exmaple, 'stream' contains :<sname>:$DATA 977fe1c642dSBill Krier */ 978fe1c642dSBill Krier void 979fe1c642dSBill Krier smb_stream_parse_name(char *path, char *filename, char *stream) 980fe1c642dSBill Krier { 981fe1c642dSBill Krier char *fname, *sname, *stype; 982fe1c642dSBill Krier 983fe1c642dSBill Krier ASSERT(path); 984fe1c642dSBill Krier ASSERT(filename); 985fe1c642dSBill Krier ASSERT(stream); 986fe1c642dSBill Krier 987fe1c642dSBill Krier fname = strrchr(path, '\\'); 988fe1c642dSBill Krier fname = (fname == NULL) ? path : fname + 1; 989fe1c642dSBill Krier (void) strlcpy(filename, fname, MAXNAMELEN); 990fe1c642dSBill Krier 991fe1c642dSBill Krier sname = strchr(filename, ':'); 992fe1c642dSBill Krier (void) strlcpy(stream, sname, MAXNAMELEN); 993fe1c642dSBill Krier *sname = '\0'; 994fe1c642dSBill Krier 995fe1c642dSBill Krier stype = strchr(stream + 1, ':'); 996fe1c642dSBill Krier if (stype == NULL) 997fe1c642dSBill Krier (void) strlcat(stream, ":$DATA", MAXNAMELEN); 998fe1c642dSBill Krier else 999fe1c642dSBill Krier (void) smb_strupr(stype); 1000fe1c642dSBill Krier } 1001fe1c642dSBill Krier 1002fe1c642dSBill Krier /* 1003fe1c642dSBill Krier * smb_is_stream_name 1004fe1c642dSBill Krier * 1005fe1c642dSBill Krier * Determines if 'path' specifies a named stream. 1006fe1c642dSBill Krier * 1007fe1c642dSBill Krier * path is a NULL terminated string which could be a stream path. 1008fe1c642dSBill Krier * [pathname/]fname[:stream_name[:stream_type]] 1009fe1c642dSBill Krier * 1010fe1c642dSBill Krier * - If there is no colon in the path or it's the last char 1011fe1c642dSBill Krier * then it's not a stream name 1012fe1c642dSBill Krier * 1013fe1c642dSBill Krier * - '::' is a non-stream and is commonly used by Windows to designate 1014fe1c642dSBill Krier * the unamed stream in the form "::$DATA" 1015fe1c642dSBill Krier */ 1016fe1c642dSBill Krier boolean_t 1017fe1c642dSBill Krier smb_is_stream_name(char *path) 1018fe1c642dSBill Krier { 1019fe1c642dSBill Krier char *colonp; 1020fe1c642dSBill Krier 1021fe1c642dSBill Krier if (path == NULL) 1022fe1c642dSBill Krier return (B_FALSE); 1023fe1c642dSBill Krier 1024fe1c642dSBill Krier colonp = strchr(path, ':'); 1025fe1c642dSBill Krier if ((colonp == NULL) || (*(colonp+1) == '\0')) 1026fe1c642dSBill Krier return (B_FALSE); 1027fe1c642dSBill Krier 1028fe1c642dSBill Krier if (strstr(path, "::")) 1029fe1c642dSBill Krier return (B_FALSE); 1030fe1c642dSBill Krier 1031fe1c642dSBill Krier return (B_TRUE); 1032fe1c642dSBill Krier } 1033fe1c642dSBill Krier 1034fe1c642dSBill Krier /* 1035fe1c642dSBill Krier * smb_validate_stream_name 1036fe1c642dSBill Krier * 1037fe1c642dSBill Krier * B_FALSE will be returned, and the error status ser in the sr, if: 1038fe1c642dSBill Krier * - the path is not a stream name 1039fe1c642dSBill Krier * - a path is specified but the fname is ommitted. 1040fe1c642dSBill Krier * - the stream_type is specified but not valid. 1041fe1c642dSBill Krier * 1042fe1c642dSBill Krier * Note: the stream type is case-insensitive. 1043fe1c642dSBill Krier */ 1044fe1c642dSBill Krier boolean_t 1045fe1c642dSBill Krier smb_validate_stream_name(smb_request_t *sr, smb_pathname_t *pn) 1046fe1c642dSBill Krier { 1047fe1c642dSBill Krier static char *strmtype[] = { 1048fe1c642dSBill Krier "$DATA", 1049fe1c642dSBill Krier "$INDEX_ALLOCATION" 1050fe1c642dSBill Krier }; 1051fe1c642dSBill Krier int i; 1052fe1c642dSBill Krier 1053fe1c642dSBill Krier ASSERT(pn); 1054fe1c642dSBill Krier ASSERT(pn->pn_sname); 1055fe1c642dSBill Krier 1056fe1c642dSBill Krier if ((!(pn->pn_sname)) || 1057fe1c642dSBill Krier ((pn->pn_pname) && !(pn->pn_fname))) { 1058fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 1059fe1c642dSBill Krier ERRDOS, ERROR_INVALID_NAME); 1060fe1c642dSBill Krier return (B_FALSE); 1061fe1c642dSBill Krier } 1062fe1c642dSBill Krier 1063fe1c642dSBill Krier 1064fe1c642dSBill Krier if (pn->pn_stype != NULL) { 1065fe1c642dSBill Krier for (i = 0; i < sizeof (strmtype) / sizeof (strmtype[0]); ++i) { 1066fe1c642dSBill Krier if (strcasecmp(pn->pn_stype, strmtype[i]) == 0) 1067fe1c642dSBill Krier return (B_TRUE); 1068fe1c642dSBill Krier } 1069fe1c642dSBill Krier 1070fe1c642dSBill Krier smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 1071fe1c642dSBill Krier ERRDOS, ERROR_INVALID_NAME); 1072fe1c642dSBill Krier return (B_FALSE); 1073fe1c642dSBill Krier } 1074fe1c642dSBill Krier 1075fe1c642dSBill Krier return (B_TRUE); 1076fe1c642dSBill Krier } 10779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 10799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * valid DFS I/O path: 10809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * \server-or-domain\share 10829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * \server-or-domain\share\path 10839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 10849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * All the returned errors by this function needs to be 10859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * checked against Windows. 10869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 10879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int 10889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_dfs_preprocess(smb_request_t *sr, char *path, size_t pathsz) 10899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 10909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_unc_t unc; 10919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *linkpath; 10929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 10939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (sr->tid_tree == NULL) 10959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (0); 10969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_unc_init(path, &unc)) != 0) 10989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 10999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_strcasecmp(unc.unc_share, sr->tid_tree->t_sharename, 0)) { 11019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_unc_free(&unc); 11029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (EINVAL); 11039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States linkpath = unc.unc_path; 11069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(path, pathsz, "/%s", (linkpath) ? linkpath : ""); 11079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_unc_free(&unc); 11099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (0); 11109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 1111