1*11337SWilliam.Krier@Sun.COM /* 2*11337SWilliam.Krier@Sun.COM * CDDL HEADER START 3*11337SWilliam.Krier@Sun.COM * 4*11337SWilliam.Krier@Sun.COM * The contents of this file are subject to the terms of the 5*11337SWilliam.Krier@Sun.COM * Common Development and Distribution License (the "License"). 6*11337SWilliam.Krier@Sun.COM * You may not use this file except in compliance with the License. 7*11337SWilliam.Krier@Sun.COM * 8*11337SWilliam.Krier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*11337SWilliam.Krier@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*11337SWilliam.Krier@Sun.COM * See the License for the specific language governing permissions 11*11337SWilliam.Krier@Sun.COM * and limitations under the License. 12*11337SWilliam.Krier@Sun.COM * 13*11337SWilliam.Krier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*11337SWilliam.Krier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*11337SWilliam.Krier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*11337SWilliam.Krier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*11337SWilliam.Krier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*11337SWilliam.Krier@Sun.COM * 19*11337SWilliam.Krier@Sun.COM * CDDL HEADER END 20*11337SWilliam.Krier@Sun.COM */ 21*11337SWilliam.Krier@Sun.COM /* 22*11337SWilliam.Krier@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*11337SWilliam.Krier@Sun.COM * Use is subject to license terms. 24*11337SWilliam.Krier@Sun.COM */ 25*11337SWilliam.Krier@Sun.COM 26*11337SWilliam.Krier@Sun.COM #include <smbsrv/smb_kproto.h> 27*11337SWilliam.Krier@Sun.COM #include <smbsrv/smb_fsops.h> 28*11337SWilliam.Krier@Sun.COM #include <sys/pathname.h> 29*11337SWilliam.Krier@Sun.COM #include <sys/sdt.h> 30*11337SWilliam.Krier@Sun.COM 31*11337SWilliam.Krier@Sun.COM static char *smb_pathname_catia_v5tov4(smb_request_t *, char *, char *, int); 32*11337SWilliam.Krier@Sun.COM static char *smb_pathname_catia_v4tov5(smb_request_t *, char *, char *, int); 33*11337SWilliam.Krier@Sun.COM static int smb_pathname_lookup(pathname_t *, pathname_t *, int, 34*11337SWilliam.Krier@Sun.COM vnode_t **, vnode_t *, vnode_t *, cred_t *); 35*11337SWilliam.Krier@Sun.COM static char *smb_pathname_strdup(smb_request_t *, const char *); 36*11337SWilliam.Krier@Sun.COM static char *smb_pathname_strcat(smb_request_t *, char *, const char *); 37*11337SWilliam.Krier@Sun.COM static void smb_pathname_preprocess(smb_request_t *, smb_pathname_t *); 38*11337SWilliam.Krier@Sun.COM 39*11337SWilliam.Krier@Sun.COM uint32_t 40*11337SWilliam.Krier@Sun.COM smb_is_executable(char *path) 41*11337SWilliam.Krier@Sun.COM { 42*11337SWilliam.Krier@Sun.COM char extension[5]; 43*11337SWilliam.Krier@Sun.COM int len = strlen(path); 44*11337SWilliam.Krier@Sun.COM 45*11337SWilliam.Krier@Sun.COM if ((len >= 4) && (path[len - 4] == '.')) { 46*11337SWilliam.Krier@Sun.COM (void) strcpy(extension, &path[len - 3]); 47*11337SWilliam.Krier@Sun.COM (void) smb_strupr(extension); 48*11337SWilliam.Krier@Sun.COM 49*11337SWilliam.Krier@Sun.COM if (strcmp(extension, "EXE") == 0) 50*11337SWilliam.Krier@Sun.COM return (NODE_FLAGS_EXECUTABLE); 51*11337SWilliam.Krier@Sun.COM 52*11337SWilliam.Krier@Sun.COM if (strcmp(extension, "COM") == 0) 53*11337SWilliam.Krier@Sun.COM return (NODE_FLAGS_EXECUTABLE); 54*11337SWilliam.Krier@Sun.COM 55*11337SWilliam.Krier@Sun.COM if (strcmp(extension, "DLL") == 0) 56*11337SWilliam.Krier@Sun.COM return (NODE_FLAGS_EXECUTABLE); 57*11337SWilliam.Krier@Sun.COM 58*11337SWilliam.Krier@Sun.COM if (strcmp(extension, "SYM") == 0) 59*11337SWilliam.Krier@Sun.COM return (NODE_FLAGS_EXECUTABLE); 60*11337SWilliam.Krier@Sun.COM } 61*11337SWilliam.Krier@Sun.COM 62*11337SWilliam.Krier@Sun.COM return (0); 63*11337SWilliam.Krier@Sun.COM } 64*11337SWilliam.Krier@Sun.COM 65*11337SWilliam.Krier@Sun.COM /* 66*11337SWilliam.Krier@Sun.COM * smb_pathname_reduce 67*11337SWilliam.Krier@Sun.COM * 68*11337SWilliam.Krier@Sun.COM * smb_pathname_reduce() takes a path and returns the smb_node for the 69*11337SWilliam.Krier@Sun.COM * second-to-last component of the path. It also returns the name of the last 70*11337SWilliam.Krier@Sun.COM * component. Pointers for both of these fields must be supplied by the caller. 71*11337SWilliam.Krier@Sun.COM * 72*11337SWilliam.Krier@Sun.COM * Upon success, 0 is returned. 73*11337SWilliam.Krier@Sun.COM * 74*11337SWilliam.Krier@Sun.COM * Upon error, *dir_node will be set to 0. 75*11337SWilliam.Krier@Sun.COM * 76*11337SWilliam.Krier@Sun.COM * *sr (in) 77*11337SWilliam.Krier@Sun.COM * --- 78*11337SWilliam.Krier@Sun.COM * smb_request structure pointer 79*11337SWilliam.Krier@Sun.COM * 80*11337SWilliam.Krier@Sun.COM * *cred (in) 81*11337SWilliam.Krier@Sun.COM * ----- 82*11337SWilliam.Krier@Sun.COM * credential 83*11337SWilliam.Krier@Sun.COM * 84*11337SWilliam.Krier@Sun.COM * *path (in) 85*11337SWilliam.Krier@Sun.COM * ----- 86*11337SWilliam.Krier@Sun.COM * pathname to be looked up 87*11337SWilliam.Krier@Sun.COM * 88*11337SWilliam.Krier@Sun.COM * *share_root_node (in) 89*11337SWilliam.Krier@Sun.COM * ---------------- 90*11337SWilliam.Krier@Sun.COM * File operations which are share-relative should pass sr->tid_tree->t_snode. 91*11337SWilliam.Krier@Sun.COM * If the call is not for a share-relative operation, this parameter must be 0 92*11337SWilliam.Krier@Sun.COM * (e.g. the call from smbsr_setup_share()). (Such callers will have path 93*11337SWilliam.Krier@Sun.COM * operations done using root_smb_node.) This parameter is used to determine 94*11337SWilliam.Krier@Sun.COM * whether mount points can be crossed. 95*11337SWilliam.Krier@Sun.COM * 96*11337SWilliam.Krier@Sun.COM * share_root_node should have at least one reference on it. This reference 97*11337SWilliam.Krier@Sun.COM * will stay intact throughout this routine. 98*11337SWilliam.Krier@Sun.COM * 99*11337SWilliam.Krier@Sun.COM * *cur_node (in) 100*11337SWilliam.Krier@Sun.COM * --------- 101*11337SWilliam.Krier@Sun.COM * The smb_node for the current directory (for relative paths). 102*11337SWilliam.Krier@Sun.COM * cur_node should have at least one reference on it. 103*11337SWilliam.Krier@Sun.COM * This reference will stay intact throughout this routine. 104*11337SWilliam.Krier@Sun.COM * 105*11337SWilliam.Krier@Sun.COM * **dir_node (out) 106*11337SWilliam.Krier@Sun.COM * ---------- 107*11337SWilliam.Krier@Sun.COM * Directory for the penultimate component of the original path. 108*11337SWilliam.Krier@Sun.COM * (Note that this is not the same as the parent directory of the ultimate 109*11337SWilliam.Krier@Sun.COM * target in the case of a link.) 110*11337SWilliam.Krier@Sun.COM * 111*11337SWilliam.Krier@Sun.COM * The directory smb_node is returned held. The caller will need to release 112*11337SWilliam.Krier@Sun.COM * the hold or otherwise make sure it will get released (e.g. in a destroy 113*11337SWilliam.Krier@Sun.COM * routine if made part of a global structure). 114*11337SWilliam.Krier@Sun.COM * 115*11337SWilliam.Krier@Sun.COM * last_component (out) 116*11337SWilliam.Krier@Sun.COM * -------------- 117*11337SWilliam.Krier@Sun.COM * The last component of the path. (This may be different from the name of any 118*11337SWilliam.Krier@Sun.COM * link target to which the last component may resolve.) 119*11337SWilliam.Krier@Sun.COM * 120*11337SWilliam.Krier@Sun.COM * 121*11337SWilliam.Krier@Sun.COM * ____________________________ 122*11337SWilliam.Krier@Sun.COM * 123*11337SWilliam.Krier@Sun.COM * The CIFS server lookup path needs to have logic equivalent to that of 124*11337SWilliam.Krier@Sun.COM * smb_fsop_lookup(), smb_vop_lookup() and other smb_vop_*() routines in the 125*11337SWilliam.Krier@Sun.COM * following areas: 126*11337SWilliam.Krier@Sun.COM * 127*11337SWilliam.Krier@Sun.COM * - non-traversal of child mounts (handled by smb_pathname_reduce) 128*11337SWilliam.Krier@Sun.COM * - unmangling (handled in smb_pathname) 129*11337SWilliam.Krier@Sun.COM * - "chroot" behavior of share root (handled by lookuppnvp) 130*11337SWilliam.Krier@Sun.COM * 131*11337SWilliam.Krier@Sun.COM * In addition, it needs to replace backslashes with forward slashes. It also 132*11337SWilliam.Krier@Sun.COM * ensures that link processing is done correctly, and that directory 133*11337SWilliam.Krier@Sun.COM * information requested by the caller is correctly returned (i.e. for paths 134*11337SWilliam.Krier@Sun.COM * with a link in the last component, the directory information of the 135*11337SWilliam.Krier@Sun.COM * link and not the target needs to be returned). 136*11337SWilliam.Krier@Sun.COM */ 137*11337SWilliam.Krier@Sun.COM 138*11337SWilliam.Krier@Sun.COM int 139*11337SWilliam.Krier@Sun.COM smb_pathname_reduce( 140*11337SWilliam.Krier@Sun.COM smb_request_t *sr, 141*11337SWilliam.Krier@Sun.COM cred_t *cred, 142*11337SWilliam.Krier@Sun.COM const char *path, 143*11337SWilliam.Krier@Sun.COM smb_node_t *share_root_node, 144*11337SWilliam.Krier@Sun.COM smb_node_t *cur_node, 145*11337SWilliam.Krier@Sun.COM smb_node_t **dir_node, 146*11337SWilliam.Krier@Sun.COM char *last_component) 147*11337SWilliam.Krier@Sun.COM { 148*11337SWilliam.Krier@Sun.COM smb_node_t *root_node; 149*11337SWilliam.Krier@Sun.COM pathname_t ppn; 150*11337SWilliam.Krier@Sun.COM char *usepath; 151*11337SWilliam.Krier@Sun.COM int lookup_flags = FOLLOW; 152*11337SWilliam.Krier@Sun.COM int trailing_slash = 0; 153*11337SWilliam.Krier@Sun.COM int err = 0; 154*11337SWilliam.Krier@Sun.COM int len; 155*11337SWilliam.Krier@Sun.COM smb_node_t *vss_cur_node; 156*11337SWilliam.Krier@Sun.COM smb_node_t *vss_root_node; 157*11337SWilliam.Krier@Sun.COM smb_node_t *local_cur_node; 158*11337SWilliam.Krier@Sun.COM smb_node_t *local_root_node; 159*11337SWilliam.Krier@Sun.COM 160*11337SWilliam.Krier@Sun.COM ASSERT(dir_node); 161*11337SWilliam.Krier@Sun.COM ASSERT(last_component); 162*11337SWilliam.Krier@Sun.COM 163*11337SWilliam.Krier@Sun.COM *dir_node = NULL; 164*11337SWilliam.Krier@Sun.COM *last_component = '\0'; 165*11337SWilliam.Krier@Sun.COM vss_cur_node = NULL; 166*11337SWilliam.Krier@Sun.COM vss_root_node = NULL; 167*11337SWilliam.Krier@Sun.COM 168*11337SWilliam.Krier@Sun.COM if (sr && sr->tid_tree) { 169*11337SWilliam.Krier@Sun.COM if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) 170*11337SWilliam.Krier@Sun.COM return (EACCES); 171*11337SWilliam.Krier@Sun.COM } 172*11337SWilliam.Krier@Sun.COM 173*11337SWilliam.Krier@Sun.COM if (SMB_TREE_IS_CASEINSENSITIVE(sr)) 174*11337SWilliam.Krier@Sun.COM lookup_flags |= FIGNORECASE; 175*11337SWilliam.Krier@Sun.COM 176*11337SWilliam.Krier@Sun.COM if (path == NULL) 177*11337SWilliam.Krier@Sun.COM return (EINVAL); 178*11337SWilliam.Krier@Sun.COM 179*11337SWilliam.Krier@Sun.COM if (*path == '\0') 180*11337SWilliam.Krier@Sun.COM return (ENOENT); 181*11337SWilliam.Krier@Sun.COM 182*11337SWilliam.Krier@Sun.COM usepath = kmem_alloc(MAXPATHLEN, KM_SLEEP); 183*11337SWilliam.Krier@Sun.COM 184*11337SWilliam.Krier@Sun.COM if ((len = strlcpy(usepath, path, MAXPATHLEN)) >= MAXPATHLEN) { 185*11337SWilliam.Krier@Sun.COM kmem_free(usepath, MAXPATHLEN); 186*11337SWilliam.Krier@Sun.COM return (ENAMETOOLONG); 187*11337SWilliam.Krier@Sun.COM } 188*11337SWilliam.Krier@Sun.COM 189*11337SWilliam.Krier@Sun.COM (void) strsubst(usepath, '\\', '/'); 190*11337SWilliam.Krier@Sun.COM 191*11337SWilliam.Krier@Sun.COM if (share_root_node) 192*11337SWilliam.Krier@Sun.COM root_node = share_root_node; 193*11337SWilliam.Krier@Sun.COM else 194*11337SWilliam.Krier@Sun.COM root_node = sr->sr_server->si_root_smb_node; 195*11337SWilliam.Krier@Sun.COM 196*11337SWilliam.Krier@Sun.COM if (cur_node == NULL) 197*11337SWilliam.Krier@Sun.COM cur_node = root_node; 198*11337SWilliam.Krier@Sun.COM 199*11337SWilliam.Krier@Sun.COM local_cur_node = cur_node; 200*11337SWilliam.Krier@Sun.COM local_root_node = root_node; 201*11337SWilliam.Krier@Sun.COM 202*11337SWilliam.Krier@Sun.COM if (sr && (sr->smb_flg2 & SMB_FLAGS2_REPARSE_PATH)) { 203*11337SWilliam.Krier@Sun.COM err = smb_vss_lookup_nodes(sr, root_node, cur_node, 204*11337SWilliam.Krier@Sun.COM usepath, &vss_cur_node, &vss_root_node); 205*11337SWilliam.Krier@Sun.COM 206*11337SWilliam.Krier@Sun.COM if (err != 0) { 207*11337SWilliam.Krier@Sun.COM kmem_free(usepath, MAXPATHLEN); 208*11337SWilliam.Krier@Sun.COM return (err); 209*11337SWilliam.Krier@Sun.COM } 210*11337SWilliam.Krier@Sun.COM 211*11337SWilliam.Krier@Sun.COM len = strlen(usepath); 212*11337SWilliam.Krier@Sun.COM local_cur_node = vss_cur_node; 213*11337SWilliam.Krier@Sun.COM local_root_node = vss_root_node; 214*11337SWilliam.Krier@Sun.COM } 215*11337SWilliam.Krier@Sun.COM 216*11337SWilliam.Krier@Sun.COM if (usepath[len - 1] == '/') 217*11337SWilliam.Krier@Sun.COM trailing_slash = 1; 218*11337SWilliam.Krier@Sun.COM 219*11337SWilliam.Krier@Sun.COM (void) strcanon(usepath, "/"); 220*11337SWilliam.Krier@Sun.COM 221*11337SWilliam.Krier@Sun.COM (void) pn_alloc(&ppn); 222*11337SWilliam.Krier@Sun.COM 223*11337SWilliam.Krier@Sun.COM if ((err = pn_set(&ppn, usepath)) != 0) { 224*11337SWilliam.Krier@Sun.COM (void) pn_free(&ppn); 225*11337SWilliam.Krier@Sun.COM kmem_free(usepath, MAXPATHLEN); 226*11337SWilliam.Krier@Sun.COM if (vss_cur_node != NULL) 227*11337SWilliam.Krier@Sun.COM (void) smb_node_release(vss_cur_node); 228*11337SWilliam.Krier@Sun.COM if (vss_root_node != NULL) 229*11337SWilliam.Krier@Sun.COM (void) smb_node_release(vss_root_node); 230*11337SWilliam.Krier@Sun.COM return (err); 231*11337SWilliam.Krier@Sun.COM } 232*11337SWilliam.Krier@Sun.COM 233*11337SWilliam.Krier@Sun.COM /* 234*11337SWilliam.Krier@Sun.COM * If a path does not have a trailing slash, strip off the 235*11337SWilliam.Krier@Sun.COM * last component. (We only need to return an smb_node for 236*11337SWilliam.Krier@Sun.COM * the second to last component; a name is returned for the 237*11337SWilliam.Krier@Sun.COM * last component.) 238*11337SWilliam.Krier@Sun.COM */ 239*11337SWilliam.Krier@Sun.COM 240*11337SWilliam.Krier@Sun.COM if (trailing_slash) { 241*11337SWilliam.Krier@Sun.COM (void) strlcpy(last_component, ".", MAXNAMELEN); 242*11337SWilliam.Krier@Sun.COM } else { 243*11337SWilliam.Krier@Sun.COM (void) pn_setlast(&ppn); 244*11337SWilliam.Krier@Sun.COM (void) strlcpy(last_component, ppn.pn_path, MAXNAMELEN); 245*11337SWilliam.Krier@Sun.COM ppn.pn_path[0] = '\0'; 246*11337SWilliam.Krier@Sun.COM } 247*11337SWilliam.Krier@Sun.COM 248*11337SWilliam.Krier@Sun.COM if ((strcmp(ppn.pn_buf, "/") == 0) || (ppn.pn_buf[0] == '\0')) { 249*11337SWilliam.Krier@Sun.COM smb_node_ref(local_cur_node); 250*11337SWilliam.Krier@Sun.COM *dir_node = local_cur_node; 251*11337SWilliam.Krier@Sun.COM } else { 252*11337SWilliam.Krier@Sun.COM err = smb_pathname(sr, ppn.pn_buf, lookup_flags, 253*11337SWilliam.Krier@Sun.COM local_root_node, local_cur_node, NULL, dir_node, cred); 254*11337SWilliam.Krier@Sun.COM } 255*11337SWilliam.Krier@Sun.COM 256*11337SWilliam.Krier@Sun.COM (void) pn_free(&ppn); 257*11337SWilliam.Krier@Sun.COM kmem_free(usepath, MAXPATHLEN); 258*11337SWilliam.Krier@Sun.COM 259*11337SWilliam.Krier@Sun.COM /* 260*11337SWilliam.Krier@Sun.COM * Prevent access to anything outside of the share root, except 261*11337SWilliam.Krier@Sun.COM * when mapping a share because that may require traversal from 262*11337SWilliam.Krier@Sun.COM * / to a mounted file system. share_root_node is NULL when 263*11337SWilliam.Krier@Sun.COM * mapping a share. 264*11337SWilliam.Krier@Sun.COM * 265*11337SWilliam.Krier@Sun.COM * Note that we disregard whether the traversal of the path went 266*11337SWilliam.Krier@Sun.COM * outside of the file system and then came back (say via a link). 267*11337SWilliam.Krier@Sun.COM */ 268*11337SWilliam.Krier@Sun.COM 269*11337SWilliam.Krier@Sun.COM if ((err == 0) && share_root_node) { 270*11337SWilliam.Krier@Sun.COM if (share_root_node->vp->v_vfsp != (*dir_node)->vp->v_vfsp) 271*11337SWilliam.Krier@Sun.COM err = EACCES; 272*11337SWilliam.Krier@Sun.COM } 273*11337SWilliam.Krier@Sun.COM 274*11337SWilliam.Krier@Sun.COM if (err) { 275*11337SWilliam.Krier@Sun.COM if (*dir_node) { 276*11337SWilliam.Krier@Sun.COM (void) smb_node_release(*dir_node); 277*11337SWilliam.Krier@Sun.COM *dir_node = NULL; 278*11337SWilliam.Krier@Sun.COM } 279*11337SWilliam.Krier@Sun.COM *last_component = 0; 280*11337SWilliam.Krier@Sun.COM } 281*11337SWilliam.Krier@Sun.COM 282*11337SWilliam.Krier@Sun.COM if (vss_cur_node != NULL) 283*11337SWilliam.Krier@Sun.COM (void) smb_node_release(vss_cur_node); 284*11337SWilliam.Krier@Sun.COM if (vss_root_node != NULL) 285*11337SWilliam.Krier@Sun.COM (void) smb_node_release(vss_root_node); 286*11337SWilliam.Krier@Sun.COM 287*11337SWilliam.Krier@Sun.COM return (err); 288*11337SWilliam.Krier@Sun.COM } 289*11337SWilliam.Krier@Sun.COM 290*11337SWilliam.Krier@Sun.COM /* 291*11337SWilliam.Krier@Sun.COM * smb_pathname() 292*11337SWilliam.Krier@Sun.COM * wrapper to lookuppnvp(). Handles name unmangling. 293*11337SWilliam.Krier@Sun.COM * 294*11337SWilliam.Krier@Sun.COM * *dir_node is the true directory of the target *node. 295*11337SWilliam.Krier@Sun.COM * 296*11337SWilliam.Krier@Sun.COM * If any component but the last in the path is not found, ENOTDIR instead of 297*11337SWilliam.Krier@Sun.COM * ENOENT will be returned. 298*11337SWilliam.Krier@Sun.COM * 299*11337SWilliam.Krier@Sun.COM * Path components are processed one at a time so that smb_nodes can be 300*11337SWilliam.Krier@Sun.COM * created for each component. This allows the n_dnode field in the 301*11337SWilliam.Krier@Sun.COM * smb_node to be properly populated. 302*11337SWilliam.Krier@Sun.COM * 303*11337SWilliam.Krier@Sun.COM * Because of the above, links are also processed in this routine 304*11337SWilliam.Krier@Sun.COM * (i.e., we do not pass the FOLLOW flag to lookuppnvp()). This 305*11337SWilliam.Krier@Sun.COM * will allow smb_nodes to be created for each component of a link. 306*11337SWilliam.Krier@Sun.COM * 307*11337SWilliam.Krier@Sun.COM * Mangle checking is per component. If a name is mangled, when the 308*11337SWilliam.Krier@Sun.COM * unmangled name is passed to smb_pathname_lookup() do not pass 309*11337SWilliam.Krier@Sun.COM * FIGNORECASE, since the unmangled name is the real on-disk name. 310*11337SWilliam.Krier@Sun.COM * Otherwise pass FIGNORECASE if it's set in flags. This will cause the 311*11337SWilliam.Krier@Sun.COM * file system to return "first match" in the event of a case collision. 312*11337SWilliam.Krier@Sun.COM * 313*11337SWilliam.Krier@Sun.COM * If CATIA character translation is enabled it is applied to each 314*11337SWilliam.Krier@Sun.COM * component before passing the component to smb_pathname_lookup(). 315*11337SWilliam.Krier@Sun.COM * After smb_pathname_lookup() the reverse translation is applied. 316*11337SWilliam.Krier@Sun.COM */ 317*11337SWilliam.Krier@Sun.COM 318*11337SWilliam.Krier@Sun.COM int 319*11337SWilliam.Krier@Sun.COM smb_pathname(smb_request_t *sr, char *path, int flags, 320*11337SWilliam.Krier@Sun.COM smb_node_t *root_node, smb_node_t *cur_node, smb_node_t **dir_node, 321*11337SWilliam.Krier@Sun.COM smb_node_t **ret_node, cred_t *cred) 322*11337SWilliam.Krier@Sun.COM { 323*11337SWilliam.Krier@Sun.COM char *component, *real_name, *namep; 324*11337SWilliam.Krier@Sun.COM pathname_t pn, rpn, upn, link_pn; 325*11337SWilliam.Krier@Sun.COM smb_node_t *dnode, *fnode; 326*11337SWilliam.Krier@Sun.COM vnode_t *rootvp, *vp; 327*11337SWilliam.Krier@Sun.COM size_t pathleft; 328*11337SWilliam.Krier@Sun.COM int err = 0; 329*11337SWilliam.Krier@Sun.COM int nlink = 0; 330*11337SWilliam.Krier@Sun.COM int local_flags; 331*11337SWilliam.Krier@Sun.COM uint32_t abe_flag = 0; 332*11337SWilliam.Krier@Sun.COM char namebuf[MAXNAMELEN]; 333*11337SWilliam.Krier@Sun.COM 334*11337SWilliam.Krier@Sun.COM if (path == NULL) 335*11337SWilliam.Krier@Sun.COM return (EINVAL); 336*11337SWilliam.Krier@Sun.COM 337*11337SWilliam.Krier@Sun.COM ASSERT(root_node); 338*11337SWilliam.Krier@Sun.COM ASSERT(cur_node); 339*11337SWilliam.Krier@Sun.COM ASSERT(ret_node); 340*11337SWilliam.Krier@Sun.COM 341*11337SWilliam.Krier@Sun.COM *ret_node = NULL; 342*11337SWilliam.Krier@Sun.COM 343*11337SWilliam.Krier@Sun.COM if (dir_node) 344*11337SWilliam.Krier@Sun.COM *dir_node = NULL; 345*11337SWilliam.Krier@Sun.COM 346*11337SWilliam.Krier@Sun.COM (void) pn_alloc(&upn); 347*11337SWilliam.Krier@Sun.COM 348*11337SWilliam.Krier@Sun.COM if ((err = pn_set(&upn, path)) != 0) { 349*11337SWilliam.Krier@Sun.COM (void) pn_free(&upn); 350*11337SWilliam.Krier@Sun.COM return (err); 351*11337SWilliam.Krier@Sun.COM } 352*11337SWilliam.Krier@Sun.COM 353*11337SWilliam.Krier@Sun.COM if (SMB_TREE_SUPPORTS_ABE(sr)) 354*11337SWilliam.Krier@Sun.COM abe_flag = SMB_ABE; 355*11337SWilliam.Krier@Sun.COM 356*11337SWilliam.Krier@Sun.COM (void) pn_alloc(&pn); 357*11337SWilliam.Krier@Sun.COM (void) pn_alloc(&rpn); 358*11337SWilliam.Krier@Sun.COM 359*11337SWilliam.Krier@Sun.COM component = kmem_alloc(MAXNAMELEN, KM_SLEEP); 360*11337SWilliam.Krier@Sun.COM real_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); 361*11337SWilliam.Krier@Sun.COM 362*11337SWilliam.Krier@Sun.COM fnode = NULL; 363*11337SWilliam.Krier@Sun.COM dnode = cur_node; 364*11337SWilliam.Krier@Sun.COM smb_node_ref(dnode); 365*11337SWilliam.Krier@Sun.COM rootvp = root_node->vp; 366*11337SWilliam.Krier@Sun.COM 367*11337SWilliam.Krier@Sun.COM while ((pathleft = pn_pathleft(&upn)) != 0) { 368*11337SWilliam.Krier@Sun.COM if (fnode) { 369*11337SWilliam.Krier@Sun.COM smb_node_release(dnode); 370*11337SWilliam.Krier@Sun.COM dnode = fnode; 371*11337SWilliam.Krier@Sun.COM fnode = NULL; 372*11337SWilliam.Krier@Sun.COM } 373*11337SWilliam.Krier@Sun.COM 374*11337SWilliam.Krier@Sun.COM if ((err = pn_getcomponent(&upn, component)) != 0) 375*11337SWilliam.Krier@Sun.COM break; 376*11337SWilliam.Krier@Sun.COM 377*11337SWilliam.Krier@Sun.COM if ((namep = smb_pathname_catia_v5tov4(sr, component, 378*11337SWilliam.Krier@Sun.COM namebuf, sizeof (namebuf))) == NULL) { 379*11337SWilliam.Krier@Sun.COM err = EILSEQ; 380*11337SWilliam.Krier@Sun.COM break; 381*11337SWilliam.Krier@Sun.COM } 382*11337SWilliam.Krier@Sun.COM 383*11337SWilliam.Krier@Sun.COM if ((err = pn_set(&pn, namep)) != 0) 384*11337SWilliam.Krier@Sun.COM break; 385*11337SWilliam.Krier@Sun.COM 386*11337SWilliam.Krier@Sun.COM local_flags = flags & FIGNORECASE; 387*11337SWilliam.Krier@Sun.COM err = smb_pathname_lookup(&pn, &rpn, local_flags, 388*11337SWilliam.Krier@Sun.COM &vp, rootvp, dnode->vp, cred); 389*11337SWilliam.Krier@Sun.COM 390*11337SWilliam.Krier@Sun.COM if (err) { 391*11337SWilliam.Krier@Sun.COM if (smb_maybe_mangled_name(component) == 0) 392*11337SWilliam.Krier@Sun.COM break; 393*11337SWilliam.Krier@Sun.COM 394*11337SWilliam.Krier@Sun.COM if ((err = smb_unmangle_name(dnode, component, 395*11337SWilliam.Krier@Sun.COM real_name, MAXNAMELEN, abe_flag)) != 0) 396*11337SWilliam.Krier@Sun.COM break; 397*11337SWilliam.Krier@Sun.COM 398*11337SWilliam.Krier@Sun.COM if ((namep = smb_pathname_catia_v5tov4(sr, real_name, 399*11337SWilliam.Krier@Sun.COM namebuf, sizeof (namebuf))) == NULL) { 400*11337SWilliam.Krier@Sun.COM err = EILSEQ; 401*11337SWilliam.Krier@Sun.COM break; 402*11337SWilliam.Krier@Sun.COM } 403*11337SWilliam.Krier@Sun.COM 404*11337SWilliam.Krier@Sun.COM if ((err = pn_set(&pn, namep)) != 0) 405*11337SWilliam.Krier@Sun.COM break; 406*11337SWilliam.Krier@Sun.COM 407*11337SWilliam.Krier@Sun.COM local_flags = 0; 408*11337SWilliam.Krier@Sun.COM err = smb_pathname_lookup(&pn, &rpn, local_flags, 409*11337SWilliam.Krier@Sun.COM &vp, rootvp, dnode->vp, cred); 410*11337SWilliam.Krier@Sun.COM if (err) 411*11337SWilliam.Krier@Sun.COM break; 412*11337SWilliam.Krier@Sun.COM } 413*11337SWilliam.Krier@Sun.COM 414*11337SWilliam.Krier@Sun.COM if ((vp->v_type == VLNK) && 415*11337SWilliam.Krier@Sun.COM ((flags & FOLLOW) || pn_pathleft(&upn))) { 416*11337SWilliam.Krier@Sun.COM 417*11337SWilliam.Krier@Sun.COM if (++nlink > MAXSYMLINKS) { 418*11337SWilliam.Krier@Sun.COM err = ELOOP; 419*11337SWilliam.Krier@Sun.COM VN_RELE(vp); 420*11337SWilliam.Krier@Sun.COM break; 421*11337SWilliam.Krier@Sun.COM } 422*11337SWilliam.Krier@Sun.COM 423*11337SWilliam.Krier@Sun.COM (void) pn_alloc(&link_pn); 424*11337SWilliam.Krier@Sun.COM err = pn_getsymlink(vp, &link_pn, cred); 425*11337SWilliam.Krier@Sun.COM VN_RELE(vp); 426*11337SWilliam.Krier@Sun.COM 427*11337SWilliam.Krier@Sun.COM if (err == 0) { 428*11337SWilliam.Krier@Sun.COM if (pn_pathleft(&link_pn) == 0) 429*11337SWilliam.Krier@Sun.COM (void) pn_set(&link_pn, "."); 430*11337SWilliam.Krier@Sun.COM err = pn_insert(&upn, &link_pn, 431*11337SWilliam.Krier@Sun.COM strlen(component)); 432*11337SWilliam.Krier@Sun.COM } 433*11337SWilliam.Krier@Sun.COM pn_free(&link_pn); 434*11337SWilliam.Krier@Sun.COM 435*11337SWilliam.Krier@Sun.COM if (err) 436*11337SWilliam.Krier@Sun.COM break; 437*11337SWilliam.Krier@Sun.COM 438*11337SWilliam.Krier@Sun.COM if (upn.pn_pathlen == 0) { 439*11337SWilliam.Krier@Sun.COM err = ENOENT; 440*11337SWilliam.Krier@Sun.COM break; 441*11337SWilliam.Krier@Sun.COM } 442*11337SWilliam.Krier@Sun.COM 443*11337SWilliam.Krier@Sun.COM if (upn.pn_path[0] == '/') { 444*11337SWilliam.Krier@Sun.COM fnode = root_node; 445*11337SWilliam.Krier@Sun.COM smb_node_ref(fnode); 446*11337SWilliam.Krier@Sun.COM } 447*11337SWilliam.Krier@Sun.COM 448*11337SWilliam.Krier@Sun.COM if (pn_fixslash(&upn)) 449*11337SWilliam.Krier@Sun.COM flags |= FOLLOW; 450*11337SWilliam.Krier@Sun.COM 451*11337SWilliam.Krier@Sun.COM } else { 452*11337SWilliam.Krier@Sun.COM if (flags & FIGNORECASE) { 453*11337SWilliam.Krier@Sun.COM if (strcmp(rpn.pn_path, "/") != 0) 454*11337SWilliam.Krier@Sun.COM pn_setlast(&rpn); 455*11337SWilliam.Krier@Sun.COM namep = rpn.pn_path; 456*11337SWilliam.Krier@Sun.COM } else { 457*11337SWilliam.Krier@Sun.COM namep = pn.pn_path; 458*11337SWilliam.Krier@Sun.COM } 459*11337SWilliam.Krier@Sun.COM 460*11337SWilliam.Krier@Sun.COM namep = smb_pathname_catia_v4tov5(sr, namep, 461*11337SWilliam.Krier@Sun.COM namebuf, sizeof (namebuf)); 462*11337SWilliam.Krier@Sun.COM 463*11337SWilliam.Krier@Sun.COM fnode = smb_node_lookup(sr, NULL, cred, vp, namep, 464*11337SWilliam.Krier@Sun.COM dnode, NULL); 465*11337SWilliam.Krier@Sun.COM VN_RELE(vp); 466*11337SWilliam.Krier@Sun.COM 467*11337SWilliam.Krier@Sun.COM if (fnode == NULL) { 468*11337SWilliam.Krier@Sun.COM err = ENOMEM; 469*11337SWilliam.Krier@Sun.COM break; 470*11337SWilliam.Krier@Sun.COM } 471*11337SWilliam.Krier@Sun.COM } 472*11337SWilliam.Krier@Sun.COM 473*11337SWilliam.Krier@Sun.COM while (upn.pn_path[0] == '/') { 474*11337SWilliam.Krier@Sun.COM upn.pn_path++; 475*11337SWilliam.Krier@Sun.COM upn.pn_pathlen--; 476*11337SWilliam.Krier@Sun.COM } 477*11337SWilliam.Krier@Sun.COM 478*11337SWilliam.Krier@Sun.COM } 479*11337SWilliam.Krier@Sun.COM 480*11337SWilliam.Krier@Sun.COM if ((pathleft) && (err == ENOENT)) 481*11337SWilliam.Krier@Sun.COM err = ENOTDIR; 482*11337SWilliam.Krier@Sun.COM 483*11337SWilliam.Krier@Sun.COM if (err) { 484*11337SWilliam.Krier@Sun.COM if (fnode) 485*11337SWilliam.Krier@Sun.COM smb_node_release(fnode); 486*11337SWilliam.Krier@Sun.COM if (dnode) 487*11337SWilliam.Krier@Sun.COM smb_node_release(dnode); 488*11337SWilliam.Krier@Sun.COM } else { 489*11337SWilliam.Krier@Sun.COM *ret_node = fnode; 490*11337SWilliam.Krier@Sun.COM 491*11337SWilliam.Krier@Sun.COM if (dir_node) 492*11337SWilliam.Krier@Sun.COM *dir_node = dnode; 493*11337SWilliam.Krier@Sun.COM else 494*11337SWilliam.Krier@Sun.COM smb_node_release(dnode); 495*11337SWilliam.Krier@Sun.COM } 496*11337SWilliam.Krier@Sun.COM 497*11337SWilliam.Krier@Sun.COM kmem_free(component, MAXNAMELEN); 498*11337SWilliam.Krier@Sun.COM kmem_free(real_name, MAXNAMELEN); 499*11337SWilliam.Krier@Sun.COM (void) pn_free(&pn); 500*11337SWilliam.Krier@Sun.COM (void) pn_free(&rpn); 501*11337SWilliam.Krier@Sun.COM (void) pn_free(&upn); 502*11337SWilliam.Krier@Sun.COM 503*11337SWilliam.Krier@Sun.COM return (err); 504*11337SWilliam.Krier@Sun.COM } 505*11337SWilliam.Krier@Sun.COM 506*11337SWilliam.Krier@Sun.COM /* 507*11337SWilliam.Krier@Sun.COM * Holds on dvp and rootvp (if not rootdir) are required by lookuppnvp() 508*11337SWilliam.Krier@Sun.COM * and will be released within lookuppnvp(). 509*11337SWilliam.Krier@Sun.COM */ 510*11337SWilliam.Krier@Sun.COM static int 511*11337SWilliam.Krier@Sun.COM smb_pathname_lookup(pathname_t *pn, pathname_t *rpn, int flags, 512*11337SWilliam.Krier@Sun.COM vnode_t **vp, vnode_t *rootvp, vnode_t *dvp, cred_t *cred) 513*11337SWilliam.Krier@Sun.COM { 514*11337SWilliam.Krier@Sun.COM int err; 515*11337SWilliam.Krier@Sun.COM 516*11337SWilliam.Krier@Sun.COM *vp = NULL; 517*11337SWilliam.Krier@Sun.COM VN_HOLD(dvp); 518*11337SWilliam.Krier@Sun.COM if (rootvp != rootdir) 519*11337SWilliam.Krier@Sun.COM VN_HOLD(rootvp); 520*11337SWilliam.Krier@Sun.COM 521*11337SWilliam.Krier@Sun.COM err = lookuppnvp(pn, rpn, flags, NULL, vp, rootvp, dvp, cred); 522*11337SWilliam.Krier@Sun.COM return (err); 523*11337SWilliam.Krier@Sun.COM } 524*11337SWilliam.Krier@Sun.COM 525*11337SWilliam.Krier@Sun.COM /* 526*11337SWilliam.Krier@Sun.COM * CATIA Translation of a pathname component prior to passing it to lookuppnvp 527*11337SWilliam.Krier@Sun.COM * 528*11337SWilliam.Krier@Sun.COM * If the translated component name contains a '/' NULL is returned. 529*11337SWilliam.Krier@Sun.COM * The caller should treat this as error EILSEQ. It is not valid to 530*11337SWilliam.Krier@Sun.COM * have a directory name with a '/'. 531*11337SWilliam.Krier@Sun.COM */ 532*11337SWilliam.Krier@Sun.COM static char * 533*11337SWilliam.Krier@Sun.COM smb_pathname_catia_v5tov4(smb_request_t *sr, char *name, 534*11337SWilliam.Krier@Sun.COM char *namebuf, int buflen) 535*11337SWilliam.Krier@Sun.COM { 536*11337SWilliam.Krier@Sun.COM char *namep; 537*11337SWilliam.Krier@Sun.COM 538*11337SWilliam.Krier@Sun.COM if (SMB_TREE_SUPPORTS_CATIA(sr)) { 539*11337SWilliam.Krier@Sun.COM namep = smb_vop_catia_v5tov4(name, namebuf, buflen); 540*11337SWilliam.Krier@Sun.COM if (strchr(namep, '/') != NULL) 541*11337SWilliam.Krier@Sun.COM return (NULL); 542*11337SWilliam.Krier@Sun.COM return (namep); 543*11337SWilliam.Krier@Sun.COM } 544*11337SWilliam.Krier@Sun.COM 545*11337SWilliam.Krier@Sun.COM return (name); 546*11337SWilliam.Krier@Sun.COM } 547*11337SWilliam.Krier@Sun.COM 548*11337SWilliam.Krier@Sun.COM /* 549*11337SWilliam.Krier@Sun.COM * CATIA translation of a pathname component after returning from lookuppnvp 550*11337SWilliam.Krier@Sun.COM */ 551*11337SWilliam.Krier@Sun.COM static char * 552*11337SWilliam.Krier@Sun.COM smb_pathname_catia_v4tov5(smb_request_t *sr, char *name, 553*11337SWilliam.Krier@Sun.COM char *namebuf, int buflen) 554*11337SWilliam.Krier@Sun.COM { 555*11337SWilliam.Krier@Sun.COM if (SMB_TREE_SUPPORTS_CATIA(sr)) { 556*11337SWilliam.Krier@Sun.COM smb_vop_catia_v4tov5(name, namebuf, buflen); 557*11337SWilliam.Krier@Sun.COM return (namebuf); 558*11337SWilliam.Krier@Sun.COM } 559*11337SWilliam.Krier@Sun.COM 560*11337SWilliam.Krier@Sun.COM return (name); 561*11337SWilliam.Krier@Sun.COM } 562*11337SWilliam.Krier@Sun.COM 563*11337SWilliam.Krier@Sun.COM /* 564*11337SWilliam.Krier@Sun.COM * sr - needed to check for case sense 565*11337SWilliam.Krier@Sun.COM * path - non mangled path needed to be looked up from the startvp 566*11337SWilliam.Krier@Sun.COM * startvp - the vnode to start the lookup from 567*11337SWilliam.Krier@Sun.COM * rootvp - the vnode of the root of the filesystem 568*11337SWilliam.Krier@Sun.COM * returns the vnode found when starting at startvp and using the path 569*11337SWilliam.Krier@Sun.COM * 570*11337SWilliam.Krier@Sun.COM * Finds a vnode starting at startvp and parsing the non mangled path 571*11337SWilliam.Krier@Sun.COM */ 572*11337SWilliam.Krier@Sun.COM 573*11337SWilliam.Krier@Sun.COM vnode_t * 574*11337SWilliam.Krier@Sun.COM smb_lookuppathvptovp(smb_request_t *sr, char *path, vnode_t *startvp, 575*11337SWilliam.Krier@Sun.COM vnode_t *rootvp) 576*11337SWilliam.Krier@Sun.COM { 577*11337SWilliam.Krier@Sun.COM pathname_t pn; 578*11337SWilliam.Krier@Sun.COM vnode_t *vp = NULL; 579*11337SWilliam.Krier@Sun.COM int lookup_flags = FOLLOW; 580*11337SWilliam.Krier@Sun.COM 581*11337SWilliam.Krier@Sun.COM if (SMB_TREE_IS_CASEINSENSITIVE(sr)) 582*11337SWilliam.Krier@Sun.COM lookup_flags |= FIGNORECASE; 583*11337SWilliam.Krier@Sun.COM 584*11337SWilliam.Krier@Sun.COM (void) pn_alloc(&pn); 585*11337SWilliam.Krier@Sun.COM 586*11337SWilliam.Krier@Sun.COM if (pn_set(&pn, path) == 0) { 587*11337SWilliam.Krier@Sun.COM VN_HOLD(startvp); 588*11337SWilliam.Krier@Sun.COM if (rootvp != rootdir) 589*11337SWilliam.Krier@Sun.COM VN_HOLD(rootvp); 590*11337SWilliam.Krier@Sun.COM 591*11337SWilliam.Krier@Sun.COM /* lookuppnvp should release the holds */ 592*11337SWilliam.Krier@Sun.COM if (lookuppnvp(&pn, NULL, lookup_flags, NULL, &vp, 593*11337SWilliam.Krier@Sun.COM rootvp, startvp, kcred) != 0) { 594*11337SWilliam.Krier@Sun.COM pn_free(&pn); 595*11337SWilliam.Krier@Sun.COM return (NULL); 596*11337SWilliam.Krier@Sun.COM } 597*11337SWilliam.Krier@Sun.COM } 598*11337SWilliam.Krier@Sun.COM 599*11337SWilliam.Krier@Sun.COM pn_free(&pn); 600*11337SWilliam.Krier@Sun.COM return (vp); 601*11337SWilliam.Krier@Sun.COM } 602*11337SWilliam.Krier@Sun.COM 603*11337SWilliam.Krier@Sun.COM /* 604*11337SWilliam.Krier@Sun.COM * smb_pathname_init 605*11337SWilliam.Krier@Sun.COM * Parse path: pname\\fname:sname:stype 606*11337SWilliam.Krier@Sun.COM * 607*11337SWilliam.Krier@Sun.COM * Elements of the smb_pathname_t structure are allocated using request 608*11337SWilliam.Krier@Sun.COM * specific storage and will be free'd when the sr is destroyed. 609*11337SWilliam.Krier@Sun.COM * 610*11337SWilliam.Krier@Sun.COM * Populate pn structure elements with the individual elements 611*11337SWilliam.Krier@Sun.COM * of pn->pn_path. pn->pn_sname will contain the whole stream name 612*11337SWilliam.Krier@Sun.COM * including the stream type and preceding colon: :sname:%DATA 613*11337SWilliam.Krier@Sun.COM * pn_stype will point to the stream type within pn_sname. 614*11337SWilliam.Krier@Sun.COM * 615*11337SWilliam.Krier@Sun.COM * If the pname element is missing pn_pname will be set to "\\". 616*11337SWilliam.Krier@Sun.COM * If any other element is missing the pointer in pn will be NULL. 617*11337SWilliam.Krier@Sun.COM */ 618*11337SWilliam.Krier@Sun.COM void 619*11337SWilliam.Krier@Sun.COM smb_pathname_init(smb_request_t *sr, smb_pathname_t *pn, char *path) 620*11337SWilliam.Krier@Sun.COM { 621*11337SWilliam.Krier@Sun.COM char *pname, *fname, *sname; 622*11337SWilliam.Krier@Sun.COM int len; 623*11337SWilliam.Krier@Sun.COM 624*11337SWilliam.Krier@Sun.COM bzero(pn, sizeof (smb_pathname_t)); 625*11337SWilliam.Krier@Sun.COM pn->pn_path = smb_pathname_strdup(sr, path); 626*11337SWilliam.Krier@Sun.COM 627*11337SWilliam.Krier@Sun.COM smb_pathname_preprocess(sr, pn); 628*11337SWilliam.Krier@Sun.COM 629*11337SWilliam.Krier@Sun.COM /* parse pn->pn_path into its constituent parts */ 630*11337SWilliam.Krier@Sun.COM pname = pn->pn_path; 631*11337SWilliam.Krier@Sun.COM fname = strrchr(pn->pn_path, '\\'); 632*11337SWilliam.Krier@Sun.COM 633*11337SWilliam.Krier@Sun.COM if (fname) { 634*11337SWilliam.Krier@Sun.COM if (fname == pname) { 635*11337SWilliam.Krier@Sun.COM pn->pn_pname = smb_pathname_strdup(sr, "\\"); 636*11337SWilliam.Krier@Sun.COM } else { 637*11337SWilliam.Krier@Sun.COM *fname = '\0'; 638*11337SWilliam.Krier@Sun.COM pn->pn_pname = 639*11337SWilliam.Krier@Sun.COM smb_pathname_strdup(sr, pname); 640*11337SWilliam.Krier@Sun.COM *fname = '\\'; 641*11337SWilliam.Krier@Sun.COM } 642*11337SWilliam.Krier@Sun.COM ++fname; 643*11337SWilliam.Krier@Sun.COM } else { 644*11337SWilliam.Krier@Sun.COM fname = pname; 645*11337SWilliam.Krier@Sun.COM pn->pn_pname = smb_pathname_strdup(sr, "\\"); 646*11337SWilliam.Krier@Sun.COM } 647*11337SWilliam.Krier@Sun.COM 648*11337SWilliam.Krier@Sun.COM if (fname[0] == '\0') { 649*11337SWilliam.Krier@Sun.COM pn->pn_fname = NULL; 650*11337SWilliam.Krier@Sun.COM return; 651*11337SWilliam.Krier@Sun.COM } 652*11337SWilliam.Krier@Sun.COM 653*11337SWilliam.Krier@Sun.COM if (!smb_is_stream_name(fname)) { 654*11337SWilliam.Krier@Sun.COM pn->pn_fname = smb_pathname_strdup(sr, fname); 655*11337SWilliam.Krier@Sun.COM return; 656*11337SWilliam.Krier@Sun.COM } 657*11337SWilliam.Krier@Sun.COM 658*11337SWilliam.Krier@Sun.COM /* 659*11337SWilliam.Krier@Sun.COM * find sname and stype in fname. 660*11337SWilliam.Krier@Sun.COM * sname can't be NULL smb_is_stream_name checks this 661*11337SWilliam.Krier@Sun.COM */ 662*11337SWilliam.Krier@Sun.COM sname = strchr(fname, ':'); 663*11337SWilliam.Krier@Sun.COM if (sname == fname) 664*11337SWilliam.Krier@Sun.COM fname = NULL; 665*11337SWilliam.Krier@Sun.COM else { 666*11337SWilliam.Krier@Sun.COM *sname = '\0'; 667*11337SWilliam.Krier@Sun.COM pn->pn_fname = 668*11337SWilliam.Krier@Sun.COM smb_pathname_strdup(sr, fname); 669*11337SWilliam.Krier@Sun.COM *sname = ':'; 670*11337SWilliam.Krier@Sun.COM } 671*11337SWilliam.Krier@Sun.COM 672*11337SWilliam.Krier@Sun.COM pn->pn_sname = smb_pathname_strdup(sr, sname); 673*11337SWilliam.Krier@Sun.COM pn->pn_stype = strchr(pn->pn_sname + 1, ':'); 674*11337SWilliam.Krier@Sun.COM if (pn->pn_stype) { 675*11337SWilliam.Krier@Sun.COM (void) smb_strupr(pn->pn_stype); 676*11337SWilliam.Krier@Sun.COM } else { 677*11337SWilliam.Krier@Sun.COM len = strlen(pn->pn_sname); 678*11337SWilliam.Krier@Sun.COM pn->pn_sname = smb_pathname_strcat(sr, pn->pn_sname, ":$DATA"); 679*11337SWilliam.Krier@Sun.COM pn->pn_stype = pn->pn_sname + len; 680*11337SWilliam.Krier@Sun.COM } 681*11337SWilliam.Krier@Sun.COM ++pn->pn_stype; 682*11337SWilliam.Krier@Sun.COM } 683*11337SWilliam.Krier@Sun.COM 684*11337SWilliam.Krier@Sun.COM /* 685*11337SWilliam.Krier@Sun.COM * smb_pathname_preprocess 686*11337SWilliam.Krier@Sun.COM * 687*11337SWilliam.Krier@Sun.COM * Perform common pre-processing of pn->pn_path: 688*11337SWilliam.Krier@Sun.COM * - if the pn_path is blank, set it to '\\' 689*11337SWilliam.Krier@Sun.COM * - perform unicode wildcard converstion. 690*11337SWilliam.Krier@Sun.COM * - convert any '/' to '\\' 691*11337SWilliam.Krier@Sun.COM * - eliminate duplicate slashes 692*11337SWilliam.Krier@Sun.COM * - remove trailing slashes 693*11337SWilliam.Krier@Sun.COM */ 694*11337SWilliam.Krier@Sun.COM static void 695*11337SWilliam.Krier@Sun.COM smb_pathname_preprocess(smb_request_t *sr, smb_pathname_t *pn) 696*11337SWilliam.Krier@Sun.COM { 697*11337SWilliam.Krier@Sun.COM char *p; 698*11337SWilliam.Krier@Sun.COM 699*11337SWilliam.Krier@Sun.COM /* treat empty path as "\\" */ 700*11337SWilliam.Krier@Sun.COM if (strlen(pn->pn_path) == 0) { 701*11337SWilliam.Krier@Sun.COM pn->pn_path = smb_pathname_strdup(sr, "\\"); 702*11337SWilliam.Krier@Sun.COM return; 703*11337SWilliam.Krier@Sun.COM } 704*11337SWilliam.Krier@Sun.COM 705*11337SWilliam.Krier@Sun.COM /* perform unicode wildcard conversion */ 706*11337SWilliam.Krier@Sun.COM smb_convert_wildcards(pn->pn_path); 707*11337SWilliam.Krier@Sun.COM 708*11337SWilliam.Krier@Sun.COM /* treat '/' as '\\' */ 709*11337SWilliam.Krier@Sun.COM (void) strsubst(pn->pn_path, '/', '\\'); 710*11337SWilliam.Krier@Sun.COM 711*11337SWilliam.Krier@Sun.COM (void) strcanon(pn->pn_path, "\\"); 712*11337SWilliam.Krier@Sun.COM 713*11337SWilliam.Krier@Sun.COM /* remove trailing '\\' */ 714*11337SWilliam.Krier@Sun.COM p = pn->pn_path + strlen(pn->pn_path) - 1; 715*11337SWilliam.Krier@Sun.COM if ((p != pn->pn_path) && (*p == '\\')) 716*11337SWilliam.Krier@Sun.COM *p = '\0'; 717*11337SWilliam.Krier@Sun.COM } 718*11337SWilliam.Krier@Sun.COM 719*11337SWilliam.Krier@Sun.COM /* 720*11337SWilliam.Krier@Sun.COM * smb_pathname_strdup 721*11337SWilliam.Krier@Sun.COM * 722*11337SWilliam.Krier@Sun.COM * Duplicate NULL terminated string s. 723*11337SWilliam.Krier@Sun.COM * 724*11337SWilliam.Krier@Sun.COM * The new string is allocated using request specific storage and will 725*11337SWilliam.Krier@Sun.COM * be free'd when the sr is destroyed. 726*11337SWilliam.Krier@Sun.COM */ 727*11337SWilliam.Krier@Sun.COM static char * 728*11337SWilliam.Krier@Sun.COM smb_pathname_strdup(smb_request_t *sr, const char *s) 729*11337SWilliam.Krier@Sun.COM { 730*11337SWilliam.Krier@Sun.COM char *s2; 731*11337SWilliam.Krier@Sun.COM size_t n; 732*11337SWilliam.Krier@Sun.COM 733*11337SWilliam.Krier@Sun.COM n = strlen(s) + 1; 734*11337SWilliam.Krier@Sun.COM s2 = smb_srm_alloc(sr, n); 735*11337SWilliam.Krier@Sun.COM (void) strlcpy(s2, s, n); 736*11337SWilliam.Krier@Sun.COM return (s2); 737*11337SWilliam.Krier@Sun.COM } 738*11337SWilliam.Krier@Sun.COM 739*11337SWilliam.Krier@Sun.COM /* 740*11337SWilliam.Krier@Sun.COM * smb_pathname_strcat 741*11337SWilliam.Krier@Sun.COM * 742*11337SWilliam.Krier@Sun.COM * Reallocate NULL terminated string s1 to accommodate 743*11337SWilliam.Krier@Sun.COM * concatenating NULL terminated string s2. 744*11337SWilliam.Krier@Sun.COM * Append s2 and return resulting NULL terminated string. 745*11337SWilliam.Krier@Sun.COM * 746*11337SWilliam.Krier@Sun.COM * The string buffer is reallocated using request specific 747*11337SWilliam.Krier@Sun.COM * storage and will be free'd when the sr is destroyed. 748*11337SWilliam.Krier@Sun.COM */ 749*11337SWilliam.Krier@Sun.COM static char * 750*11337SWilliam.Krier@Sun.COM smb_pathname_strcat(smb_request_t *sr, char *s1, const char *s2) 751*11337SWilliam.Krier@Sun.COM { 752*11337SWilliam.Krier@Sun.COM size_t n; 753*11337SWilliam.Krier@Sun.COM 754*11337SWilliam.Krier@Sun.COM n = strlen(s1) + strlen(s2) + 1; 755*11337SWilliam.Krier@Sun.COM s1 = smb_srm_realloc(sr, s1, n); 756*11337SWilliam.Krier@Sun.COM (void) strlcat(s1, s2, n); 757*11337SWilliam.Krier@Sun.COM return (s1); 758*11337SWilliam.Krier@Sun.COM } 759*11337SWilliam.Krier@Sun.COM 760*11337SWilliam.Krier@Sun.COM /* 761*11337SWilliam.Krier@Sun.COM * smb_pathname_validate 762*11337SWilliam.Krier@Sun.COM * 763*11337SWilliam.Krier@Sun.COM * Perform basic validation of pn: 764*11337SWilliam.Krier@Sun.COM * - If first component of pn->path is ".." -> PATH_SYNTAX_BAD 765*11337SWilliam.Krier@Sun.COM * - If there are wildcards in pn->pn_pname -> OBJECT_NAME_INVALID 766*11337SWilliam.Krier@Sun.COM * - If fname is "." -> INVALID_OBJECT_NAME 767*11337SWilliam.Krier@Sun.COM * 768*11337SWilliam.Krier@Sun.COM * On unix .. at the root of a file system links to the root. Thus 769*11337SWilliam.Krier@Sun.COM * an attempt to lookup "/../../.." will be the same as looking up "/" 770*11337SWilliam.Krier@Sun.COM * CIFs clients expect the above to result in 771*11337SWilliam.Krier@Sun.COM * NT_STATUS_OBJECT_PATH_SYNTAX_BAD. It is currently not possible 772*11337SWilliam.Krier@Sun.COM * (and questionable if it's desirable) to deal with all cases 773*11337SWilliam.Krier@Sun.COM * but paths beginning with \\.. are handled. 774*11337SWilliam.Krier@Sun.COM * 775*11337SWilliam.Krier@Sun.COM * Returns: B_TRUE if pn is valid, 776*11337SWilliam.Krier@Sun.COM * otherwise returns B_FALSE and sets error status in sr. 777*11337SWilliam.Krier@Sun.COM */ 778*11337SWilliam.Krier@Sun.COM boolean_t 779*11337SWilliam.Krier@Sun.COM smb_pathname_validate(smb_request_t *sr, smb_pathname_t *pn) 780*11337SWilliam.Krier@Sun.COM { 781*11337SWilliam.Krier@Sun.COM char *path = pn->pn_path; 782*11337SWilliam.Krier@Sun.COM 783*11337SWilliam.Krier@Sun.COM /* ignore any initial "\\" */ 784*11337SWilliam.Krier@Sun.COM path += strspn(path, "\\"); 785*11337SWilliam.Krier@Sun.COM 786*11337SWilliam.Krier@Sun.COM /* If first component of path is ".." -> PATH_SYNTAX_BAD */ 787*11337SWilliam.Krier@Sun.COM if ((strcmp(path, "..") == 0) || (strncmp(path, "..\\", 3) == 0)) { 788*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_PATH_SYNTAX_BAD, 789*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_BAD_PATHNAME); 790*11337SWilliam.Krier@Sun.COM return (B_FALSE); 791*11337SWilliam.Krier@Sun.COM } 792*11337SWilliam.Krier@Sun.COM 793*11337SWilliam.Krier@Sun.COM /* If there are wildcards in pn->pn_pname -> OBJECT_NAME_INVALID */ 794*11337SWilliam.Krier@Sun.COM if (pn->pn_pname && smb_contains_wildcards(pn->pn_pname)) { 795*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 796*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_INVALID_NAME); 797*11337SWilliam.Krier@Sun.COM return (B_FALSE); 798*11337SWilliam.Krier@Sun.COM } 799*11337SWilliam.Krier@Sun.COM 800*11337SWilliam.Krier@Sun.COM /* If fname is "." -> INVALID_OBJECT_NAME */ 801*11337SWilliam.Krier@Sun.COM if (pn->pn_fname && (strcmp(pn->pn_fname, ".") == 0)) { 802*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 803*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_PATH_NOT_FOUND); 804*11337SWilliam.Krier@Sun.COM return (B_FALSE); 805*11337SWilliam.Krier@Sun.COM } 806*11337SWilliam.Krier@Sun.COM 807*11337SWilliam.Krier@Sun.COM return (B_TRUE); 808*11337SWilliam.Krier@Sun.COM } 809*11337SWilliam.Krier@Sun.COM 810*11337SWilliam.Krier@Sun.COM /* 811*11337SWilliam.Krier@Sun.COM * smb_validate_dirname 812*11337SWilliam.Krier@Sun.COM * 813*11337SWilliam.Krier@Sun.COM * smb_pathname_validate() should have already been performed on pn. 814*11337SWilliam.Krier@Sun.COM * 815*11337SWilliam.Krier@Sun.COM * Very basic directory name validation: checks for colons in a path. 816*11337SWilliam.Krier@Sun.COM * Need to skip the drive prefix since it contains a colon. 817*11337SWilliam.Krier@Sun.COM * 818*11337SWilliam.Krier@Sun.COM * Returns: B_TRUE if the name is valid, 819*11337SWilliam.Krier@Sun.COM * otherwise returns B_FALSE and sets error status in sr. 820*11337SWilliam.Krier@Sun.COM */ 821*11337SWilliam.Krier@Sun.COM boolean_t 822*11337SWilliam.Krier@Sun.COM smb_validate_dirname(smb_request_t *sr, smb_pathname_t *pn) 823*11337SWilliam.Krier@Sun.COM { 824*11337SWilliam.Krier@Sun.COM char *name; 825*11337SWilliam.Krier@Sun.COM char *path = pn->pn_path; 826*11337SWilliam.Krier@Sun.COM 827*11337SWilliam.Krier@Sun.COM if ((name = path) != 0) { 828*11337SWilliam.Krier@Sun.COM name += strspn(name, "\\"); 829*11337SWilliam.Krier@Sun.COM 830*11337SWilliam.Krier@Sun.COM if (strchr(name, ':') != 0) { 831*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY, 832*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_INVALID_NAME); 833*11337SWilliam.Krier@Sun.COM return (B_FALSE); 834*11337SWilliam.Krier@Sun.COM } 835*11337SWilliam.Krier@Sun.COM } 836*11337SWilliam.Krier@Sun.COM 837*11337SWilliam.Krier@Sun.COM return (B_TRUE); 838*11337SWilliam.Krier@Sun.COM } 839*11337SWilliam.Krier@Sun.COM 840*11337SWilliam.Krier@Sun.COM /* 841*11337SWilliam.Krier@Sun.COM * smb_validate_object_name 842*11337SWilliam.Krier@Sun.COM * 843*11337SWilliam.Krier@Sun.COM * smb_pathname_validate() should have already been pertformed on pn. 844*11337SWilliam.Krier@Sun.COM * 845*11337SWilliam.Krier@Sun.COM * Very basic file name validation. 846*11337SWilliam.Krier@Sun.COM * For filenames, we check for names of the form "AAAn:". Names that 847*11337SWilliam.Krier@Sun.COM * contain three characters, a single digit and a colon (:) are reserved 848*11337SWilliam.Krier@Sun.COM * as DOS device names, i.e. "COM1:". 849*11337SWilliam.Krier@Sun.COM * Stream name validation is handed off to smb_validate_stream_name 850*11337SWilliam.Krier@Sun.COM * 851*11337SWilliam.Krier@Sun.COM * Returns: B_TRUE if pn->pn_fname is valid, 852*11337SWilliam.Krier@Sun.COM * otherwise returns B_FALSE and sets error status in sr. 853*11337SWilliam.Krier@Sun.COM */ 854*11337SWilliam.Krier@Sun.COM boolean_t 855*11337SWilliam.Krier@Sun.COM smb_validate_object_name(smb_request_t *sr, smb_pathname_t *pn) 856*11337SWilliam.Krier@Sun.COM { 857*11337SWilliam.Krier@Sun.COM if (pn->pn_fname && 858*11337SWilliam.Krier@Sun.COM strlen(pn->pn_fname) == 5 && 859*11337SWilliam.Krier@Sun.COM smb_isdigit(pn->pn_fname[3]) && 860*11337SWilliam.Krier@Sun.COM pn->pn_fname[4] == ':') { 861*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 862*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_INVALID_NAME); 863*11337SWilliam.Krier@Sun.COM return (B_FALSE); 864*11337SWilliam.Krier@Sun.COM } 865*11337SWilliam.Krier@Sun.COM 866*11337SWilliam.Krier@Sun.COM if (pn->pn_sname) 867*11337SWilliam.Krier@Sun.COM return (smb_validate_stream_name(sr, pn)); 868*11337SWilliam.Krier@Sun.COM 869*11337SWilliam.Krier@Sun.COM return (B_TRUE); 870*11337SWilliam.Krier@Sun.COM } 871*11337SWilliam.Krier@Sun.COM 872*11337SWilliam.Krier@Sun.COM /* 873*11337SWilliam.Krier@Sun.COM * smb_stream_parse_name 874*11337SWilliam.Krier@Sun.COM * 875*11337SWilliam.Krier@Sun.COM * smb_stream_parse_name should only be called for a path that 876*11337SWilliam.Krier@Sun.COM * contains a valid named stream. Path validation should have 877*11337SWilliam.Krier@Sun.COM * been performed before this function is called. 878*11337SWilliam.Krier@Sun.COM * 879*11337SWilliam.Krier@Sun.COM * Find the last component of path and split it into filename 880*11337SWilliam.Krier@Sun.COM * and stream name. 881*11337SWilliam.Krier@Sun.COM * 882*11337SWilliam.Krier@Sun.COM * On return the named stream type will be present. The stream 883*11337SWilliam.Krier@Sun.COM * type defaults to ":$DATA", if it has not been defined 884*11337SWilliam.Krier@Sun.COM * For exmaple, 'stream' contains :<sname>:$DATA 885*11337SWilliam.Krier@Sun.COM */ 886*11337SWilliam.Krier@Sun.COM void 887*11337SWilliam.Krier@Sun.COM smb_stream_parse_name(char *path, char *filename, char *stream) 888*11337SWilliam.Krier@Sun.COM { 889*11337SWilliam.Krier@Sun.COM char *fname, *sname, *stype; 890*11337SWilliam.Krier@Sun.COM 891*11337SWilliam.Krier@Sun.COM ASSERT(path); 892*11337SWilliam.Krier@Sun.COM ASSERT(filename); 893*11337SWilliam.Krier@Sun.COM ASSERT(stream); 894*11337SWilliam.Krier@Sun.COM 895*11337SWilliam.Krier@Sun.COM fname = strrchr(path, '\\'); 896*11337SWilliam.Krier@Sun.COM fname = (fname == NULL) ? path : fname + 1; 897*11337SWilliam.Krier@Sun.COM (void) strlcpy(filename, fname, MAXNAMELEN); 898*11337SWilliam.Krier@Sun.COM 899*11337SWilliam.Krier@Sun.COM sname = strchr(filename, ':'); 900*11337SWilliam.Krier@Sun.COM (void) strlcpy(stream, sname, MAXNAMELEN); 901*11337SWilliam.Krier@Sun.COM *sname = '\0'; 902*11337SWilliam.Krier@Sun.COM 903*11337SWilliam.Krier@Sun.COM stype = strchr(stream + 1, ':'); 904*11337SWilliam.Krier@Sun.COM if (stype == NULL) 905*11337SWilliam.Krier@Sun.COM (void) strlcat(stream, ":$DATA", MAXNAMELEN); 906*11337SWilliam.Krier@Sun.COM else 907*11337SWilliam.Krier@Sun.COM (void) smb_strupr(stype); 908*11337SWilliam.Krier@Sun.COM } 909*11337SWilliam.Krier@Sun.COM 910*11337SWilliam.Krier@Sun.COM /* 911*11337SWilliam.Krier@Sun.COM * smb_is_stream_name 912*11337SWilliam.Krier@Sun.COM * 913*11337SWilliam.Krier@Sun.COM * Determines if 'path' specifies a named stream. 914*11337SWilliam.Krier@Sun.COM * 915*11337SWilliam.Krier@Sun.COM * path is a NULL terminated string which could be a stream path. 916*11337SWilliam.Krier@Sun.COM * [pathname/]fname[:stream_name[:stream_type]] 917*11337SWilliam.Krier@Sun.COM * 918*11337SWilliam.Krier@Sun.COM * - If there is no colon in the path or it's the last char 919*11337SWilliam.Krier@Sun.COM * then it's not a stream name 920*11337SWilliam.Krier@Sun.COM * 921*11337SWilliam.Krier@Sun.COM * - '::' is a non-stream and is commonly used by Windows to designate 922*11337SWilliam.Krier@Sun.COM * the unamed stream in the form "::$DATA" 923*11337SWilliam.Krier@Sun.COM */ 924*11337SWilliam.Krier@Sun.COM boolean_t 925*11337SWilliam.Krier@Sun.COM smb_is_stream_name(char *path) 926*11337SWilliam.Krier@Sun.COM { 927*11337SWilliam.Krier@Sun.COM char *colonp; 928*11337SWilliam.Krier@Sun.COM 929*11337SWilliam.Krier@Sun.COM if (path == NULL) 930*11337SWilliam.Krier@Sun.COM return (B_FALSE); 931*11337SWilliam.Krier@Sun.COM 932*11337SWilliam.Krier@Sun.COM colonp = strchr(path, ':'); 933*11337SWilliam.Krier@Sun.COM if ((colonp == NULL) || (*(colonp+1) == '\0')) 934*11337SWilliam.Krier@Sun.COM return (B_FALSE); 935*11337SWilliam.Krier@Sun.COM 936*11337SWilliam.Krier@Sun.COM if (strstr(path, "::")) 937*11337SWilliam.Krier@Sun.COM return (B_FALSE); 938*11337SWilliam.Krier@Sun.COM 939*11337SWilliam.Krier@Sun.COM return (B_TRUE); 940*11337SWilliam.Krier@Sun.COM } 941*11337SWilliam.Krier@Sun.COM 942*11337SWilliam.Krier@Sun.COM /* 943*11337SWilliam.Krier@Sun.COM * smb_validate_stream_name 944*11337SWilliam.Krier@Sun.COM * 945*11337SWilliam.Krier@Sun.COM * B_FALSE will be returned, and the error status ser in the sr, if: 946*11337SWilliam.Krier@Sun.COM * - the path is not a stream name 947*11337SWilliam.Krier@Sun.COM * - a path is specified but the fname is ommitted. 948*11337SWilliam.Krier@Sun.COM * - the stream_type is specified but not valid. 949*11337SWilliam.Krier@Sun.COM * 950*11337SWilliam.Krier@Sun.COM * Note: the stream type is case-insensitive. 951*11337SWilliam.Krier@Sun.COM */ 952*11337SWilliam.Krier@Sun.COM boolean_t 953*11337SWilliam.Krier@Sun.COM smb_validate_stream_name(smb_request_t *sr, smb_pathname_t *pn) 954*11337SWilliam.Krier@Sun.COM { 955*11337SWilliam.Krier@Sun.COM static char *strmtype[] = { 956*11337SWilliam.Krier@Sun.COM "$DATA", 957*11337SWilliam.Krier@Sun.COM "$INDEX_ALLOCATION" 958*11337SWilliam.Krier@Sun.COM }; 959*11337SWilliam.Krier@Sun.COM int i; 960*11337SWilliam.Krier@Sun.COM 961*11337SWilliam.Krier@Sun.COM ASSERT(pn); 962*11337SWilliam.Krier@Sun.COM ASSERT(pn->pn_sname); 963*11337SWilliam.Krier@Sun.COM 964*11337SWilliam.Krier@Sun.COM if ((!(pn->pn_sname)) || 965*11337SWilliam.Krier@Sun.COM ((pn->pn_pname) && !(pn->pn_fname))) { 966*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 967*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_INVALID_NAME); 968*11337SWilliam.Krier@Sun.COM return (B_FALSE); 969*11337SWilliam.Krier@Sun.COM } 970*11337SWilliam.Krier@Sun.COM 971*11337SWilliam.Krier@Sun.COM 972*11337SWilliam.Krier@Sun.COM if (pn->pn_stype != NULL) { 973*11337SWilliam.Krier@Sun.COM for (i = 0; i < sizeof (strmtype) / sizeof (strmtype[0]); ++i) { 974*11337SWilliam.Krier@Sun.COM if (strcasecmp(pn->pn_stype, strmtype[i]) == 0) 975*11337SWilliam.Krier@Sun.COM return (B_TRUE); 976*11337SWilliam.Krier@Sun.COM } 977*11337SWilliam.Krier@Sun.COM 978*11337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 979*11337SWilliam.Krier@Sun.COM ERRDOS, ERROR_INVALID_NAME); 980*11337SWilliam.Krier@Sun.COM return (B_FALSE); 981*11337SWilliam.Krier@Sun.COM } 982*11337SWilliam.Krier@Sun.COM 983*11337SWilliam.Krier@Sun.COM return (B_TRUE); 984*11337SWilliam.Krier@Sun.COM } 985