int smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr, vnode_t **vpp, vnode_t **xattrdirvpp, int flags, cred_t *cr) { char *solaris_stream_name; int error; if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp, LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0) return (error); /* * Prepend SMB_STREAM_PREFIX to stream name */ solaris_stream_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); (void) sprintf(solaris_stream_name, "%s%s", SMB_STREAM_PREFIX, stream_name); if ((error = smb_vop_create(*xattrdirvpp, solaris_stream_name, attr, vpp, flags, cr, NULL)) != 0) VN_RELE(*xattrdirvpp); kmem_free(solaris_stream_name, MAXNAMELEN); return (error); }
int smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr) { char *solaris_stream_name; vnode_t *xattrdirvp; int error; error = smb_vop_lookup_xattrdir(vp, &xattrdirvp, LOOKUP_XATTR, cr); if (error != 0) return (error); /* * Prepend SMB_STREAM_PREFIX to stream name */ solaris_stream_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); (void) sprintf(solaris_stream_name, "%s%s", SMB_STREAM_PREFIX, stream_name); /* XXX might have to use kcred */ error = smb_vop_remove(xattrdirvp, solaris_stream_name, flags, cr); kmem_free(solaris_stream_name, MAXNAMELEN); return (error); }
/* * smb_vop_stream_lookup() * * The name returned in od_name is the on-disk name of the stream with the * SMB_STREAM_PREFIX stripped off. od_name should be allocated to MAXNAMELEN * by the caller. */ int smb_vop_stream_lookup( vnode_t *fvp, char *stream_name, vnode_t **vpp, char *od_name, vnode_t **xattrdirvpp, int flags, vnode_t *rootvp, cred_t *cr) { char *solaris_stream_name; char *name; int error, tmpflgs; if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp, LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0) return (error); /* * Prepend SMB_STREAM_PREFIX to stream name */ solaris_stream_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); (void) sprintf(solaris_stream_name, "%s%s", SMB_STREAM_PREFIX, stream_name); /* * "name" will hold the on-disk name returned from smb_vop_lookup * for the stream, including the SMB_STREAM_PREFIX. */ name = kmem_zalloc(MAXNAMELEN, KM_SLEEP); if ((error = smb_vop_lookup(*xattrdirvpp, solaris_stream_name, vpp, name, flags, &tmpflgs, rootvp, cr)) != 0) { VN_RELE(*xattrdirvpp); } else { (void) strlcpy(od_name, &(name[SMB_STREAM_PREFIX_LEN]), MAXNAMELEN); } kmem_free(solaris_stream_name, MAXNAMELEN); kmem_free(name, MAXNAMELEN); return (error); }
/* * smb_odir_openat * * Create an odir representing the extended attribute directory * associated with the file (or directory) represented by unode. * * Returns: * odid - Unique identifier of newly created odir. * 0 - error, error details set in sr. */ uint16_t smb_odir_openat(smb_request_t *sr, smb_node_t *unode) { int rc; vnode_t *xattr_dvp; uint16_t odid; cred_t *cr; char pattern[SMB_STREAM_PREFIX_LEN + 2]; smb_node_t *xattr_dnode; ASSERT(sr); ASSERT(sr->sr_magic == SMB_REQ_MAGIC); ASSERT(unode); ASSERT(unode->n_magic == SMB_NODE_MAGIC); if (SMB_TREE_CONTAINS_NODE(sr, unode) == 0 || SMB_TREE_HAS_ACCESS(sr, ACE_LIST_DIRECTORY) == 0) { smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERROR_ACCESS_DENIED); return (0); } cr = zone_kcred(); /* find the xattrdir vnode */ rc = smb_vop_lookup_xattrdir(unode->vp, &xattr_dvp, LOOKUP_XATTR, cr); if (rc != 0) { smbsr_errno(sr, rc); return (0); } /* lookup the xattrdir's smb_node */ xattr_dnode = smb_node_lookup(sr, NULL, cr, xattr_dvp, XATTR_DIR, unode, NULL); VN_RELE(xattr_dvp); if (xattr_dnode == NULL) { smbsr_error(sr, NT_STATUS_NO_MEMORY, ERRDOS, ERROR_NOT_ENOUGH_MEMORY); return (0); } (void) snprintf(pattern, sizeof (pattern), "%s*", SMB_STREAM_PREFIX); odid = smb_odir_create(sr, xattr_dnode, pattern, SMB_SEARCH_ATTRIBUTES, cr); smb_node_release(xattr_dnode); return (odid); }