use of org.alfresco.jlan.smb.server.SMBSrvSession 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);
}
}
use of org.alfresco.jlan.smb.server.SMBSrvSession 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());
}
}
Aggregations