Search in sources :

Example 1 with SMBServer

use of org.alfresco.jlan.smb.server.SMBServer in project alfresco-repository by Alfresco.

the class ContentDiskDriver2 method openFile.

/**
 * Open the file - Repo Specific implementation
 */
public NetworkFile openFile(SrvSession session, TreeConnection tree, NodeRef rootNode, String path, OpenFileMode mode, boolean truncate) throws IOException {
    ContentContext ctx = (ContentContext) tree.getContext();
    if (logger.isDebugEnabled()) {
        logger.debug("openFile :" + path + ", mode:" + mode);
    }
    try {
        String name = path;
        NodeRef nodeRef = getNodeForPath(rootNode, path);
        boolean readOnly = false;
        // Check permissions on the file/folder
        switch(mode) {
            case READ_ONLY:
            // follow through
            case ATTRIBUTES_ONLY:
                if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("about to throw an no read access denied exception path:" + path);
                    }
                    throw new AccessDeniedException("No read access to " + path);
                }
                readOnly = true;
                break;
            case READ_WRITE:
            case WRITE_ONLY:
                if (!m_transactionService.getAllowWrite()) {
                    throw new AccessDeniedException("Repo is write only, No write access to " + path);
                }
                if (permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("about to throw an no write access denied exception path:" + path);
                    }
                    throw new AccessDeniedException("No write access to " + path);
                }
                lockService.checkForLock(nodeRef);
                readOnly = false;
                break;
            case DELETE:
                if (!m_transactionService.getAllowWrite()) {
                    throw new AccessDeniedException("Repo is write only, No write access to " + path);
                }
                lockService.checkForLock(nodeRef);
        }
        // Check if the node is a link node
        NodeRef linkRef = (NodeRef) nodeService.getProperty(nodeRef, ContentModel.PROP_LINK_DESTINATION);
        NetworkFile netFile = null;
        if (linkRef == null) {
            // A normal node, not a link node
            // TODO MER REWRITE HERE
            FileInfo fileInfo = cifsHelper.getFileInformation(nodeRef, "", false, false);
            // TODO this is wasteful - the isDirectory is in the params.   We should split off an openDirectory method.
            if (fileInfo.isDirectory()) {
                logger.debug("open file - is a directory!");
                netFile = new AlfrescoFolder(path, fileInfo, readOnly);
            } else {
                // A normal file
                switch(mode) {
                    case READ_ONLY:
                        logger.debug("open file for read only");
                        netFile = ContentNetworkFile.createFile(nodeService, contentService, mimetypeService, getCifsHelper(), nodeRef, path, true, false, session);
                        netFile.setGrantedAccess(NetworkFile.READONLY);
                        break;
                    case READ_WRITE:
                        {
                            logger.debug("open file for read write");
                            File file = TempFileProvider.createTempFile("cifs", ".bin");
                            lockKeeper.addLock(nodeRef);
                            if (!truncate) {
                                // Need to open a temp file with a copy of the content.
                                ContentReader reader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
                                if (reader != null) {
                                    reader.getContent(file);
                                }
                            }
                            netFile = new TempNetworkFile(file, name);
                            netFile.setCreationDate(fileInfo.getCreationDateTime());
                            netFile.setModifyDate(fileInfo.getModifyDateTime());
                            netFile.setGrantedAccess(NetworkFile.READWRITE);
                            if (truncate) {
                                netFile.truncateFile(0);
                            }
                            if (logger.isDebugEnabled()) {
                                logger.debug("Created file: path=" + name + " node=" + nodeRef + " network file=" + netFile);
                            }
                        }
                        break;
                    case ATTRIBUTES_ONLY:
                        logger.debug("open file for attributes only");
                        netFile = ContentNetworkFile.createFile(nodeService, contentService, mimetypeService, getCifsHelper(), nodeRef, path, true, true, session);
                        netFile.setGrantedAccess(NetworkFile.READONLY);
                        break;
                    case DELETE:
                        // TODO Not sure about this one.
                        logger.debug("open file for delete");
                        netFile = ContentNetworkFile.createFile(nodeService, contentService, mimetypeService, getCifsHelper(), nodeRef, path, true, false, session);
                        netFile.setGrantedAccess(NetworkFile.READONLY);
                        break;
                    case WRITE_ONLY:
                        {
                            // consider this as open read/write/truncate)
                            logger.debug("open file write only");
                            File file = TempFileProvider.createTempFile("cifs", ".bin");
                            netFile = new TempNetworkFile(file, name);
                            // Needs to be READWRITE for JavaNetworkFile - there's no such thing as WRITEONLY!
                            netFile.setGrantedAccess(NetworkFile.READWRITE);
                            if (logger.isDebugEnabled()) {
                                logger.debug("Created temporary file: path=" + name + " node=" + nodeRef + " network file=" + netFile);
                            }
                        }
                }
            }
        // end of a normal file
        } else {
            // This is a link node
            // TODO - This server name stuff should be replaced In particular the
            // See PseudoFileOverlayImp
            // Get the CIFS server name
            String srvName = null;
            SMBServer cifsServer = (SMBServer) session.getServer().getConfiguration().findServer("CIFS");
            if (session instanceof SMBSrvSession) {
                SMBSrvSession smbSess = (SMBSrvSession) session;
                srvName = smbSess.getShareHostName();
            } else if (cifsServer != null) {
                // Use the CIFS server name in the URL
                srvName = cifsServer.getServerName();
            } else {
                // Use the local server name in the URL
                srvName = InetAddress.getLocalHost().getHostName();
            }
            // Convert the target node to a path, convert to URL format
            String pathl = getPathForNode(rootNode, linkRef);
            path = pathl.replace(FileName.DOS_SEPERATOR, '/');
            String lnkForWinPath = convertStringToUnicode(path);
            // Build the URL file data
            StringBuilder urlStr = new StringBuilder();
            urlStr.append("[InternetShortcut]\r\n");
            urlStr.append("URL=file://");
            urlStr.append(srvName);
            urlStr.append("/");
            urlStr.append(tree.getSharedDevice().getName());
            urlStr.append(lnkForWinPath);
            urlStr.append("\r\n");
            // Create the in memory pseudo file for the URL link
            byte[] urlData = urlStr.toString().getBytes();
            // Get the file information for the link node
            FileInfo fInfo = getCifsHelper().getFileInformation(nodeRef, false, isLockedFilesAsOffline);
            // Set the file size to the actual data length
            fInfo.setFileSize(urlData.length);
            // Create the network file using the in-memory file data
            netFile = new LinkMemoryNetworkFile(fInfo.getFileName(), urlData, fInfo, nodeRef);
            netFile.setFullName(pathl);
        }
        if (netFile != null) {
            long id = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID));
            netFile.setFileId((int) (id & 0xFFFFFFFFL));
            // Indicate the file is open
            netFile.setClosed(false);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Opened network file: path=" + path + " network file=" + netFile);
        }
        return netFile;
    } catch (NodeLockedException nle) {
        if (logger.isDebugEnabled()) {
            logger.debug("Open file - node is locked, " + path);
        }
        throw new AccessDeniedException("File is locked, no write access to " + path);
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Open file - access denied, " + path);
        }
        throw new AccessDeniedException("Open file " + path);
    } catch (AlfrescoRuntimeException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Open file error", ex);
        }
        throw new IOException("Open file " + path, ex);
    }
}
Also used : AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) FileContentReader(org.alfresco.repo.content.filestore.FileContentReader) ContentReader(org.alfresco.service.cmr.repository.ContentReader) SMBServer(org.alfresco.jlan.smb.server.SMBServer) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException) NodeRef(org.alfresco.service.cmr.repository.NodeRef) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) SMBSrvSession(org.alfresco.jlan.smb.server.SMBSrvSession) NodeLockedException(org.alfresco.service.cmr.lock.NodeLockedException) NetworkFile(org.alfresco.jlan.server.filesys.NetworkFile) NetworkFile(org.alfresco.jlan.server.filesys.NetworkFile) File(java.io.File)

Example 2 with SMBServer

use of org.alfresco.jlan.smb.server.SMBServer in project alfresco-repository by Alfresco.

the class ContentDiskDriver method openFile.

/**
 * Open a file or folder
 *
 * @param sess SrvSession
 * @param tree TreeConnection
 * @param params FileOpenParams
 * @return NetworkFile
 * @exception IOException
 */
public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException {
    // Create the transaction
    beginReadTransaction(sess);
    ContentContext ctx = (ContentContext) tree.getContext();
    try {
        // Not a pseudo file, try and open a normal file/folder node
        NodeRef nodeRef = getNodeForPath(tree, params.getPath());
        if (params.hasAccessMode(AccessMode.NTRead) && permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED)
            throw new AccessDeniedException("No read access to " + params.getFullPath());
        if (params.hasAccessMode(AccessMode.NTWrite) && permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED)
            throw new AccessDeniedException("No write access to " + params.getFullPath());
        // Check for delete access
        // if ( params.hasAccessMode(AccessMode.NTDelete) &&
        // permissionService.hasPermission(nodeRef, PermissionService.DELETE) == AccessStatus.DENIED)
        // throw new AccessDeniedException("No delete access to " + params.getFullPath());
        // Check if the file has a lock
        String lockTypeStr = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCK_TYPE);
        if (params.hasAccessMode(AccessMode.NTWrite) && lockTypeStr != null)
            throw new AccessDeniedException("File is locked, no write access to " + params.getFullPath());
        // Check if there is a file state for the file
        FileState fstate = null;
        if (ctx.hasStateCache()) {
            // Check if there is a file state for the file
            fstate = ctx.getStateCache().findFileState(params.getPath());
            if (fstate != null) {
                if (fstate.exists() == false)
                    throw new FileNotFoundException();
            } else {
                // Create a file state for the path
                fstate = ctx.getStateCache().findFileState(params.getPath(), true);
            }
            // Check if the current file open allows the required shared access
            boolean nosharing = false;
            String noshrReason = null;
            if (params.getAccessMode() == AccessMode.NTFileGenericExecute && params.getPath().toLowerCase().endsWith(".exe") == false) {
                if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE)) {
                    logger.debug("Execute access mode, path" + params.getPath());
                    logger.debug("  Fstate=" + fstate);
                }
                throw new AccessDeniedException("Invalid access mode");
            }
            if (fstate.getOpenCount() > 0 && params.isAttributesOnlyAccess() == false) {
                if (params.getSecurityLevel() == WinNT.SecurityImpersonation && params.getProcessId() == fstate.getProcessId())
                    nosharing = false;
                else if (params.isReadOnlyAccess() && (fstate.getSharedAccess() & SharingMode.READ) != 0)
                    nosharing = false;
                else if ((params.isReadWriteAccess() || params.isWriteOnlyAccess()) && (fstate.getSharedAccess() & SharingMode.WRITE) == 0) {
                    nosharing = true;
                    noshrReason = "Sharing mode disallows write";
                    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                        logger.debug("Sharing mode disallows write access path=" + params.getPath());
                } else if (fstate.getSharedAccess() == SharingMode.NOSHARING) {
                    nosharing = true;
                    noshrReason = "Sharing mode exclusive";
                } else if ((fstate.getSharedAccess() & params.getSharedAccess()) != params.getSharedAccess()) {
                    nosharing = true;
                    noshrReason = "Sharing mode mismatch";
                    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                        logger.debug("Local share mode=0x" + Integer.toHexString(fstate.getSharedAccess()) + ", params share mode=0x" + Integer.toHexString(params.getSharedAccess()));
                } else if (params.getSharedAccess() == SharingMode.NOSHARING) {
                    nosharing = true;
                    noshrReason = "Requestor wants exclusive mode";
                }
            }
            if (nosharing == true) {
                if (params.getPath().equals("\\") == false) {
                    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                        logger.debug("Sharing violation path=" + params.getPath() + ", sharing=0x" + Integer.toHexString(fstate.getSharedAccess()) + ",reason=" + noshrReason);
                    throw new FileSharingException("File already open, " + params.getPath());
                }
            }
            // Update the file sharing mode and process id, if this is the first file open
            fstate.setSharedAccess(params.getSharedAccess());
            fstate.setProcessId(params.getProcessId());
            if (logger.isDebugEnabled() && fstate.getOpenCount() == 0 && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                logger.debug("Path " + params.getPath() + ", sharing=0x" + Integer.toHexString(params.getSharedAccess()) + ", PID=" + params.getProcessId());
        }
        // Check if the node is a link node
        NodeRef linkRef = (NodeRef) nodeService.getProperty(nodeRef, ContentModel.PROP_LINK_DESTINATION);
        AlfrescoNetworkFile netFile = null;
        if (linkRef == null) {
            if (tree.openFileCount() > 0 && params.isAttributesOnlyAccess() == false) {
                // Search the open file table for this session/virtual circuit
                int idx = 0;
                while (idx < tree.getFileTableLength() && netFile == null) {
                    // Get the current file from the open file table
                    NetworkFile curFile = tree.findFile(idx);
                    if (curFile != null && curFile instanceof ContentNetworkFile) {
                        // Check if the file is the same path and process id
                        ContentNetworkFile contentFile = (ContentNetworkFile) curFile;
                        if (contentFile.getProcessId() == params.getProcessId() && contentFile.getFullName().equalsIgnoreCase(params.getFullPath())) {
                            if ((params.isReadWriteAccess() && contentFile.getGrantedAccess() == NetworkFile.READWRITE) || (params.isReadOnlyAccess() && contentFile.getGrantedAccess() == NetworkFile.READONLY)) {
                                // Found a match, re-use the open file
                                netFile = contentFile;
                                // Increment the file open count, last file close will actually close the file/stream
                                contentFile.incrementOpenCount();
                                if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                                    logger.debug("Re-use existing file open Path " + params.getPath() + ", PID=" + params.getProcessId() + ", params=" + (params.isReadOnlyAccess() ? "ReadOnly" : "Write") + ", file=" + (contentFile.getGrantedAccess() <= NetworkFile.READONLY ? "ReadOnly" : "Write"));
                            } else if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                                logger.debug("Not re-using file path=" + params.getPath() + ", readWrite=" + (params.isReadWriteAccess() ? "true" : "false") + ", readOnly=" + (params.isReadOnlyAccess() ? "true" : "false") + ", grantedAccess=" + contentFile.getGrantedAccessAsString());
                        }
                    }
                    // Update the file table index
                    idx++;
                }
            }
            if (netFile == null) {
                // Create a new network file for the open request
                netFile = ContentNetworkFile.createFile(nodeService, contentService, mimetypeService, cifsHelper, nodeRef, params.getPath(), params.isReadOnlyAccess(), params.isAttributesOnlyAccess(), sess);
            }
        } else {
            // Get the CIFS server name
            String srvName = null;
            SMBServer cifsServer = (SMBServer) sess.getServer().getConfiguration().findServer("CIFS");
            if (sess instanceof SMBSrvSession) {
                SMBSrvSession smbSess = (SMBSrvSession) sess;
                srvName = smbSess.getShareHostName();
            } else if (cifsServer != null) {
                // Use the CIFS server name in the URL
                srvName = cifsServer.getServerName();
            } else {
                // Use the local server name in the URL
                srvName = InetAddress.getLocalHost().getHostName();
            }
            // Convert the target node to a path, convert to URL format
            String path = getPathForNode(tree, linkRef);
            path = path.replace(FileName.DOS_SEPERATOR, '/');
            // Build the URL file data
            StringBuilder urlStr = new StringBuilder();
            urlStr.append("[InternetShortcut]\r\n");
            urlStr.append("URL=file://");
            urlStr.append(srvName);
            urlStr.append("/");
            urlStr.append(tree.getSharedDevice().getName());
            urlStr.append(path);
            urlStr.append("\r\n");
            // Create the in memory pseudo file for the URL link
            byte[] urlData = urlStr.toString().getBytes();
            // Get the file information for the link node
            FileInfo fInfo = cifsHelper.getFileInformation(nodeRef, isReadOnly, isLockedFilesAsOffline);
            // Set the file size to the actual data length
            fInfo.setFileSize(urlData.length);
            // Create the network file using the in-memory file data
            netFile = new LinkMemoryNetworkFile(fInfo.getFileName(), urlData, fInfo, nodeRef);
            netFile.setFullName(params.getPath());
        }
        if (netFile != null) {
            long id = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID));
            netFile.setFileId((int) (id & 0xFFFFFFFFL));
            // Indicate the file is open
            netFile.setClosed(false);
        }
        if (params.isOverwrite() && netFile != null) {
            // Truncate the file to zero length
            netFile.truncateFile(0L);
        }
        if (ctx.hasStateCache()) {
            if (fstate == null)
                fstate = ctx.getStateCache().findFileState(params.getPath(), true);
            if (netFile.getGrantedAccess() > NetworkFile.ATTRIBUTESONLY)
                fstate.incrementOpenCount();
            fstate.setFilesystemObject(nodeRef);
            // Store the state with the file
            netFile.setFileState(fstate);
            if (fstate.hasFileSize())
                netFile.setFileSize(fstate.getFileSize());
        }
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
            logger.debug("Opened network file: path=" + params.getPath() + " file open parameters=" + params + " network file=" + netFile);
        return netFile;
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
            logger.debug("Open file - access denied, " + params.getFullPath());
        throw new AccessDeniedException("Open file " + params.getFullPath());
    } catch (RuntimeException ex) {
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
            logger.debug("Open file error", ex);
        throw new IOException("Open file " + params.getFullPath());
    }
}
Also used : FileState(org.alfresco.jlan.server.filesys.cache.FileState) AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) FileNotFoundException(java.io.FileNotFoundException) NodeRef(org.alfresco.service.cmr.repository.NodeRef) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) AlfrescoNetworkFile(org.alfresco.filesys.alfresco.AlfrescoNetworkFile) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) SMBSrvSession(org.alfresco.jlan.smb.server.SMBSrvSession) NetworkFile(org.alfresco.jlan.server.filesys.NetworkFile) AlfrescoNetworkFile(org.alfresco.filesys.alfresco.AlfrescoNetworkFile) SMBServer(org.alfresco.jlan.smb.server.SMBServer) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException) FileSharingException(org.alfresco.jlan.server.filesys.FileSharingException)

Aggregations

IOException (java.io.IOException)2 AlfrescoRuntimeException (org.alfresco.error.AlfrescoRuntimeException)2 AccessDeniedException (org.alfresco.jlan.server.filesys.AccessDeniedException)2 FileInfo (org.alfresco.jlan.server.filesys.FileInfo)2 NetworkFile (org.alfresco.jlan.server.filesys.NetworkFile)2 SMBServer (org.alfresco.jlan.smb.server.SMBServer)2 SMBSrvSession (org.alfresco.jlan.smb.server.SMBSrvSession)2 ContentIOException (org.alfresco.service.cmr.repository.ContentIOException)2 NodeRef (org.alfresco.service.cmr.repository.NodeRef)2 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 AlfrescoNetworkFile (org.alfresco.filesys.alfresco.AlfrescoNetworkFile)1 FileSharingException (org.alfresco.jlan.server.filesys.FileSharingException)1 FileState (org.alfresco.jlan.server.filesys.cache.FileState)1 FileContentReader (org.alfresco.repo.content.filestore.FileContentReader)1 NodeLockedException (org.alfresco.service.cmr.lock.NodeLockedException)1 ContentReader (org.alfresco.service.cmr.repository.ContentReader)1