FsysSecurity.cpp
资源名称:warftpd.zip [点击查看]
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:23k
源码类别:
Ftp客户端
开发平台:
Visual C++
- // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
- // Copyright 1996 by Jarle Aase. All rights reserved.
- // See the "War Software Series Licende Agreement" for details concerning
- // use and distribution.
- // ---
- // This source code, executables and programs containing source code or
- // binaries or proprietetary technology from the War Software Series are
- // NOT alloed used, viewed or tested by any governmental agencies in
- // any countries. This includes the government, departments, police,
- // military etc.
- // ---
- // This file is intended for use with Tab space = 2
- // Created and maintained in MSVC Developer Studio
- // ---
- // NAME : FsysSecurity.cpp
- // PURPOSE : File System security
- // PROGRAM :
- // DATE : Oct. 9 1996
- // AUTHOR : Jarle Aase
- // ---
- // REVISION HISTORY
- //
- /*
- The design of the security system is a combination of the UNIX security
- system and the "classic" DOS/FTP based security. The flexibility makes
- the security a little slower than other FTP servers, but it ease the
- maintainance of the sites with a uniform way of handeling the file
- system.
- Basically all files have the UNIX Perms; Read, Write and Execute.
- On directories the user must have execute permission to access the
- directory entry (if the execute permission miss, the user can not
- see the directory, or any of it's subdirs).
- Direcotories:
- Read - The user can see files in the directory
- Write - The user can create files and directories in the directory
- Execute - The user can access the directory.
- Files:
- Read - The user can read the file
- Write - The user can overwrite/delete the file
- Execute - The user can execute the file (if it is an executable)
- When the server search for permissions, it begins from the system root
- and walks down the path till the desired item is reached. If the user miss
- the execute permission on a directory along the path, the access is denied.
- The files have 3 set of permissions.
- Owner - The permissions that applies for the owner of the file
- Class - The permissions that applies for the member of the owners class
- Other - The permissions that applies for all other users.
- In order to add a little flexibility on this design, there can be defined
- several different permissions for "other".
- The rules are:
- If the current user are the owner, the "other" applies for the FTP "default" level
- (system wide or virtual server).
- If the current user not is the owner, the server checks if the current user has his
- own special permissions for this object. If he dont, the same check is performed for
- the group he belongs to (the file system itself dont distinguish between users and
- groups - they all have unique numbers. An object can therefore belong to a user or
- a group without breaking the integrety of the filesystem).
- If the current user (or his group) have special permissions, these are used as the
- "other" permissions. (If the object is owned by the users group, the user is *not*
- considered owner).
- Also: The UNIX "owner" and "class" flags are static for an object. The "other" flags
- are dynamic and can be set specially for any user or user-group. If both the user and
- his group have special rights, the uses group permissions are ignored, and the users
- personal rights used.
- The only flags that can be set on these three levels are read, write and execute.
- Other file permissions like "free file" and "dupe exception" are shared among all
- users of the object.
- In order to speed things up and avoid wasting permission files everywhere, each directory
- has a set of "default" permissions for it's directories and files. If a file or directory
- is undefined in the list, these default permissions applies. The default attributes
- are inherited by it's children, uless it has it's own attributes defined.
- This is non-standard, and allows attributes to be chained down the paths if the paths
- dont have their own permissions set. If they have their own permission set, these will
- apply and the chaining will stop.
- If no descriptos are found anywhere, the user will get "read + execute" permission on
- directories, but no permissions on the files. The users will also be able to browse, but
- not access any files.
- The security system does not check the paths against the users root-path. But the user will
- never be able to access any files below his root path, unless they apper as links to the user,
- and the link is part of the path given from the user.
- When the Find*File() functions looks for files, they first get a handle to the security
- descriptors for the Find*File() start-path. If they need to traverse directories, they
- can use this handle so that the security system dont have to perform a new scan from root.
- When the handle is closed the information is freed, and the next time the user want to
- access something, a new scan is performed.
- If the virtual file system is used this is fast, as all the information is cached. Without
- the virtual file system, the security functions have to read the information from disk.
- Each user has a UMASK for files and directories, so that files created by this user
- gets the right permissions.
- Note: This module is accessed by several threads/processes. Syncronization is
- left to the calling module. At implementation time, VfSys will ensure locking
- of the affected dir, and then call <device>.dll to get the permissions, which
- in turn call this module. Handles will only be called by one thread, and closed
- as soon as a ditrectory is scanned.
- */
- #include "stdafx.h"
- #include <sys/stat.h>
- #include "WarSoftware.h"
- #include "FsysSecurity.h"
- #include "ctype.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- // Get a SECFILE file. If we are in write mode and fail to create
- // the file in the Path, we look in .Index.ini for the path. If the
- // path dont exist, we try to create a new file in the .Index
- // directory, and when done, we add the entry to the .ini file su that
- // we can recognize the file later on...
- // In read mode we just fail if the file dont exist in the Path
- // or in the .ini file.
- FILE *CFsysSecurity::OpenSecurityGroupFile(LPCSTR Path, LPCSTR Mode)
- {
- ASSERT(AfxIsValidString(Path));
- ASSERT(AfxIsValidString(Mode));
- FILE *fp = NULL;
- LPCSTR p;
- CString cMyPath = Path;
- CString cBuf;
- CString cMyKey;
- LPCSTR TagName = strrchr(Path, '\');
- if (!TagName || !*++TagName)
- TagName = ".suspect";
- // Check for root path
- if (!*Path)
- {
- TagName = ".Root";
- cMyKey = "@root@";
- goto ini_fallback;
- }
- // Check for disk drive X: ...|
- if (cMyPath.GetLength() <= 3)
- {
- ASSERT(strlen(cMyPath) <= 3);
- ASSERT((toupper(cMyPath[0]) >= 'A') && (toupper(cMyPath[0]) <= 'Z'));
- cMyKey.Format("@drive@%c@", cMyPath[0]);
- goto ini_fallback;
- }
- cMyPath += "\"SECFILE;
- if ((fp = fopen(cMyPath,Mode)) == NULL)
- {
- LogMsg(LOGF_DEBUG,"OpenSecurityGroupFile(%s,%s) failed. %s", Path, Mode, GetLastErrorText());
- p = Path;
- cMyKey.Empty();
- while(*p)
- {
- if (!isalpha(*p) && !isdigit(*p))
- {
- char buf[8];
- sprintf(buf,"@%x@", (unsigned)*p);
- cMyKey += buf;
- }
- else
- cMyKey += *p;
- ++p;
- }
- ini_fallback:
- CString FsysPath = GetStartupPath();
- {
- LPSTR p = FsysPath.GetBuffer(1);
- p = strrchr(p, '\');
- if (*p)
- *p = 0;
- FsysPath.ReleaseBuffer();
- FsysPath += "\Fsys";
- }
- CString IndexDirPath = FsysPath;
- IndexDirPath += "\"SECFILE".DIR";
- CString IndexIniPath = IndexDirPath;
- IndexIniPath += "\"SECFILE".ini";
- GetIniItem(NULL, IndexIniPath, "Maps", cMyKey, cMyPath, "");
- if (cMyPath.IsEmpty() && strchr(Mode,'w'))
- {
- // Make sure that we have the .Index dir available
- if (GetFileAttributes(IndexDirPath) == 0xFFFFFFFF)
- {
- CreateDirectory(IndexDirPath, NULL);
- }
- int Retries = 0;
- // Create a unique file name for this group
- for(Retries = 0; Retries < 1000; Retries ++)
- {
- struct _stat st;
- cMyPath.Format("%s\%s-%lu.txt", IndexDirPath, TagName, Retries);
- if (!_stat(cMyPath,&st))
- continue; // File exist
- if ((fp = fopen(cMyPath, Mode)) != NULL)
- PutIniItem(NULL, IndexIniPath, "Maps", cMyKey, cMyPath);
- break;
- }
- }
- else if (!cMyPath.IsEmpty())
- {
- // The path was found in the .ini file
- fp = fopen(cMyPath, Mode);
- }
- }
- return fp;
- }
- // Load the security descriptors for a directory
- // Path is always the directory where the permission
- // group applies
- HANDLE CFsysSecurity::LoadSecurityGroup(LPCSTR Path, BOOL DoScanNodes)
- {
- #define MYBUFSIZ (1024 * 10)
- LPSTR LineBuf = NULL;
- FILE *fp = OpenSecurityGroupFile(Path, "r");
- HANDLE Rval = INVALID_HANDLE_VALUE;
- CFsysSecurityGrp *fsg = NULL;
- CFsysSecurityNode *fsn = NULL;
- #ifdef _DEBUG
- LogMsg(LOGF_DEBUG,"LoadSecurityGroup(%s [%s]) - Called.", Path,
- DoScanNodes ? "Scan_nodes" : "skip_nodes");
- #endif
- char *FileName = NULL;
- char *RealPath = NULL;
- char *Comment = NULL;
- char *UserName = NULL;
- char *ClassName = NULL;
- DWORD Perms, SpecialNewFilePerms, DlCnt, DefaultPermDir, DefaultPermFiles;
- int FileVersion = 0;
- if (!fp)
- {
- LogMsg(LOGF_DEBUG,"LoadSecurityGroup(%s) - No security group file found.", Path);
- goto done;
- }
- LineBuf = new char[MYBUFSIZ];
- FileName = new char[MAX_PATH * 2];
- RealPath = new char[MAX_PATH * 2];
- Comment = new char[1024];
- UserName = new char[64];
- ClassName = new char[64];
- if (!fgets(LineBuf, MYBUFSIZ, fp))
- {
- LogMsg(LOGF_DEBUG,"LoadSecurityGroup(%s) - Read at 1st line.", Path);
- goto done;
- }
- sscanf(LineBuf,"%s %s %d", FileName,RealPath,&FileVersion);
- if ((FileVersion > 4) || (FileVersion < 2))
- {
- LogMsg(LOGF_WARNINGS,"LoadSecurityGroup(%s): Unknown file format (%d).", Path, FileVersion);
- goto done;
- }
- if (FileVersion == 4) // War version 2.0
- {
- if (!fgets(LineBuf, MYBUFSIZ, fp))
- {
- LogMsg(LOGF_WARNINGS,"LoadSecurityGroup(%s) - No second line.", Path);
- goto done;
- }
- MySscanf(LineBuf,"%O %O", &DefaultPermDir, &DefaultPermFiles);
- }
- else
- {
- // Fallback to War 1.* versions of the file
- DefaultPermDir = 0775; // Owner all, class all, other list + cd
- DefaultPermFiles = 0740; // Owner all, class read, other none.
- }
- // Allocate buffers for the information
- fsg = new CFsysSecurityGrp;
- fsg->DefaultPermFiles = DefaultPermFiles;
- fsg->DefaultPermDirs = DefaultPermDir;
- fsg->m_Path = Path;
- fsn = NULL;
- if (!DoScanNodes)
- goto skip_scan; // We only needed the default perms this time..
- while(fgets(LineBuf,MYBUFSIZ,fp) != NULL)
- {
- Perms = 0; SpecialNewFilePerms = 0; *FileName = 0; *RealPath = 0; *Comment = 0; *UserName = 0; *ClassName = 0; DlCnt = 0;
- if (*LineBuf == '*')
- {
- // Link
- if (FileVersion == 2)
- MySscanf(LineBuf+1,"1%s1 %O %s %s 1%s1",
- FileName, &Perms, UserName, ClassName, RealPath);
- else
- MySscanf(LineBuf+1,"1%s1 %O 1%s1 1%s1 1%s1",
- FileName, &Perms, UserName, ClassName, RealPath);
- if (*UserName == '(') *UserName = 0;
- if (*ClassName == '(') *ClassName = 0;
- if ((Perms == 0) || !*RealPath || (*RealPath == '('))
- continue; // Bad data...
- }
- else
- {
- // Normal file info
- if (FileVersion == 2)
- MySscanf(LineBuf,"1%s1 %O %s %s %O %ld 1%s1",
- FileName, &Perms, UserName, ClassName, &SpecialNewFilePerms, &DlCnt, Comment);
- else
- MySscanf(LineBuf,"1%s1 %O 1%s1 1%s1 %d %ld 1%s1",
- FileName, &Perms, UserName, ClassName, &SpecialNewFilePerms, &DlCnt, Comment);
- if (*UserName == '(') *UserName = 0;
- if (*ClassName == '(') *ClassName = 0;
- if (!stricmp(Comment,"(null)")) *Comment = 0;
- if (!*FileName)
- continue; // Bad data...
- fsn = new CFsysSecurityNode;
- int i;
- fsn->Perms = Perms;
- fsn->DlCnt = DlCnt;
- fsn->Owner = *UserName ? (i = atoi(UserName)) ? i : 0 : 0;
- fsn->Class = *ClassName ? (i = atoi(ClassName)) ? i : 0 : 0;
- //#ifdef _DEBUG
- {
- LPSTR p = strchr(Comment,'n');
- if (p)
- *p = 0;
- p = strchr(Comment,'r');
- if (p)
- *p = 0;
- }
- //#endif
- fsn->Comment = Comment;
- fsn->FileName = FileName;
- fsn->SpecialNewFilePerms = SpecialNewFilePerms;
- fsg->m_Nodes.AddLast((LPVOID)fsn);
- }
- }
- skip_scan:
- Rval = (HANDLE)fsg;
- done:
- if (Rval == INVALID_HANDLE_VALUE)
- {
- if (fsg)
- delete fsg;
- }
- if (LineBuf)
- {
- delete LineBuf;
- delete FileName;
- delete RealPath;
- delete Comment;
- delete UserName;
- delete ClassName;
- }
- if (fp)
- fclose(fp);
- return Rval;
- #undef MYBUFSIZ
- }
- HANDLE CFsysSecurity::GetSecurityDescriptor(HANDLE pGrp, LPCSTR FileName)
- {
- if (pGrp == INVALID_HANDLE_VALUE)
- return INVALID_HANDLE_VALUE;
- CFsysSecurityGrp *fsg = (CFsysSecurityGrp *)pGrp;
- CFsysSecurityNode *fsn;
- CLinkedListItem *Item;
- for(Item = fsg->m_Nodes.First(); Item; Item = fsg->m_Nodes.Next(Item))
- {
- fsn = (CFsysSecurityNode *)fsg->m_Nodes.Ptr(Item);
- ASSERT(AfxIsValidString(fsn->FileName));
- ASSERT(AfxIsValidString(fsn->Comment));
- if (!stricmp(fsn->FileName,FileName))
- return (HANDLE)fsn;
- }
- return INVALID_HANDLE_VALUE;
- }
- void CFsysSecurity::LogMsg(int flag, LPCSTR Format, ...)
- {
- CString cBuf;
- if (!ShouldLog(CLog::GetLog(), flag))
- return;
- ASSERT(AfxIsValidString(Format, FALSE));
- ASSERT(CLog::GetLog() != NULL);
- ASSERT(AfxIsValidAddress(CLog::GetLog(),sizeof(CLog)));
- cBuf.Format("CFsysSecurity: %s", Format);
- va_list argList;
- va_start(argList, Format);
- CLog::GetLog()->LogMsgV(flag, cBuf, argList);
- va_end(argList);
- }
- BOOL CFsysSecurity::CloseSecurityGroup(HANDLE pGrp)
- {
- CFsysSecurityGrp *pMyGrp = (CFsysSecurityGrp *)pGrp;
- ASSERT(AfxIsValidAddress(pMyGrp, sizeof(CFsysSecurityGrp)));
- if (pMyGrp->m_fp)
- {
- fclose(pMyGrp->m_fp);
- pMyGrp->m_fp = NULL;
- // Try to hide the file
- // If we fail, we can assume that the file is mapped into the ..Index dir and
- // then we don't care...
- CString cMyPath;
- cMyPath.Format("%s\"SECFILE, pMyGrp->m_Path);
- CFileStatus fs;
- if (CFile::GetStatus(cMyPath,fs))
- {
- fs.m_attribute |= 0x02; // Hidden
- try
- {
- CFile::SetStatus(cMyPath, fs);
- }
- catch(CFileException *e)
- {
- LogMsg(LOGF_WARNINGS,"CloseSecurityGroup() - Caught FILE ERROR exception (%d) in file '%s' while hiding the file.",
- e->m_cause, e->m_strFileName);
- e->Delete();
- }
- }
- }
- delete pMyGrp;
- return TRUE;
- }
- HANDLE CFsysSecurity::CreateNode(int User, HANDLE pGrp, BOOL IsDir, LPCSTR FileName)
- {
- CFsysSecurityGrp *pMyGrp = (CFsysSecurityGrp *)pGrp;
- ASSERT(AfxIsValidAddress(pMyGrp, sizeof(CFsysSecurityGrp)));
- ASSERT(AfxIsValidString(FileName));
- HANDLE h = GetSecurityDescriptor(pGrp, FileName);
- if (h != INVALID_HANDLE_VALUE)
- return h;
- CFsysSecurityNode *fsn = new CFsysSecurityNode;
- fsn->Perms = IsDir ? pMyGrp->DefaultPermDirs : pMyGrp->DefaultPermFiles;
- fsn->Owner = 0;
- fsn->Class = 0;
- fsn->DlCnt = 0;
- fsn->Comment.Empty();
- fsn->FileName = FileName;
- pMyGrp->m_Nodes.AddLast((HANDLE) fsn);
- return (HANDLE) fsn;
- }
- // Open a security group for update (flush). Just open the file and
- // write the header.
- // Path is the file system path to the directory.
- // If Default* == 0xffffffff, get the default values ourself.
- HANDLE CFsysSecurity::OpenSecurityGroupForUpdate(LPCSTR Path,
- DWORD DefaultPermFiles,
- DWORD DefaultPermDirs)
- {
- if ((DefaultPermFiles == 0xffffffff) || (DefaultPermDirs == 0xffffffff))
- {
- HANDLE h = LoadSecurityGroup(Path, FALSE);
- if (h == INVALID_HANDLE_VALUE)
- {
- // Set hardcoded default values (LIST + browse)
- if (DefaultPermFiles == 0xffffffff)
- DefaultPermFiles = 0;
- if (DefaultPermDirs == 0xffffffff)
- DefaultPermDirs = 0555;
- }
- else
- {
- // Get default values
- CFsysSecurityGrp *pSG = (CFsysSecurityGrp *)h;
- if (DefaultPermFiles == 0xffffffff)
- DefaultPermFiles = pSG->DefaultPermFiles;
- if (DefaultPermDirs == 0xffffffff)
- DefaultPermDirs = pSG->DefaultPermDirs;
- CloseSecurityGroup(h);
- }
- }
- // Open file
- CFsysSecurityGrp *pSG = new CFsysSecurityGrp;
- ASSERT(AfxIsValidAddress(pSG, sizeof(CFsysSecurityGrp)));
- pSG->m_Path = Path;
- pSG->DefaultPermFiles = DefaultPermFiles;
- pSG->DefaultPermDirs = DefaultPermDirs;
- pSG->m_fp = OpenSecurityGroupFile(Path, "w");
- if (!pSG->m_fp)
- {
- LogMsg(LOGF_WARNINGS,"OpenSecurityGroupForUpdate(%s) - Failed to open security group for update.",
- Path);
- return FALSE;
- }
- fprintf(pSG->m_fp,"WarSoftware Series2 4n0%o 0%on",
- pSG->DefaultPermDirs, pSG->DefaultPermFiles);
- return (HANDLE)pSG;
- }
- void CFsysSecurity::FlushNode(
- HANDLE hSecGrp,
- LPCSTR FileName,
- DWORD Perms,
- int Owner,
- int Class,
- int DlCnt,
- LPCSTR Comment,
- DWORD SpecialNewFilePerms)
- {
- ASSERT(hSecGrp != INVALID_HANDLE_VALUE);
- CFsysSecurityGrp *pSG = (CFsysSecurityGrp *)hSecGrp;
- ASSERT(pSG->m_fp != NULL);
- #ifdef _DEBUG
- ASSERT(AfxIsValidString(FileName));
- ASSERT(AfxIsValidString(Comment));
- ASSERT(!strchr(Comment,'n'));
- ASSERT(!strchr(Comment,'r'));
- #endif
- fprintf(pSG->m_fp, "1%s1 0%o 1%d1 1%d1 0%o %d 1%s1n",
- FileName,
- Perms,
- Owner,
- Class,
- SpecialNewFilePerms,
- DlCnt,
- Comment);
- }
- // Update the SECFILE file from the data in memory. At the same time, delete
- // obsolete entries.
- BOOL CFsysSecurity::FlushGroup(HANDLE pGrp)
- {
- /*
- CFsysSecurityGrp *pMyGrp = (CFsysSecurityGrp *)pGrp;
- ASSERT(AfxIsValidAddress(pMyGrp, sizeof(CFsysSecurityGrp)));
- m_Lock.Lock();
- FILE *fp = OpenSecurityGroupFile(pMyGrp->m_Path, "w");
- if (!fp)
- {
- LogMsg(LOGF_WARNINGS,"FlushGroup(%s) - Failed to update file permissions.",
- pMyGrp->m_Path);
- m_Lock.Unlock();
- return FALSE;
- }
- fprintf(fp,"WarSoftware Series2 4n0%o 0%on",
- pMyGrp->DefaultPermDirs, pMyGrp->DefaultPermFiles);
- CFsysSecurityNode *fsn;
- CLinkedListItem *Item;
- for(Item = pMyGrp->m_Nodes.First(); Item; Item = pMyGrp->m_Nodes.Next(Item))
- {
- fsn = (CFsysSecurityNode *)pMyGrp->m_Nodes.Ptr(Item);
- ASSERT(AfxIsValidString(fsn->FileName));
- ASSERT(AfxIsValidString(fsn->Comment));
- WIN32_FIND_DATA Data;
- HANDLE h = CFsys::m_pCFsys->FindFirstFile(0, pMyGrp->m_Path, &Data);
- if (h == INVALID_HANDLE_VALUE)
- {
- // Path dont extist.
- continue;
- }
- CFsys::m_pCFsys->FindClose(h);
- // Update
- fprintf(fp,"1%s1 0%o 1%d1 1%d1 %d %ld 1%s1n",
- fsn->FileName,
- fsn->Perms,
- fsn->Owner,
- fsn->Class,
- 0, // Obsolete War 1.# inode flags...
- fsn->DlCnt,
- fsn->Comment);
- }
- fclose(fp);
- // Try to hide the file
- // If we fail, we can assume that the file is mapped into the ..Index dir and
- // then we don't care...
- CString cMyPath;
- cMyPath.Format("%s\"SECFILE, pMyGrp->m_Path);
- CFsys::DosPath(cMyPath.GetBuffer(1));
- cMyPath.ReleaseBuffer();
- CFileStatus fs;
- if (CFile::GetStatus(cMyPath,fs))
- {
- fs.m_attribute |= 0x02; // Hidden
- try
- {
- CFile::SetStatus(cMyPath, fs);
- }
- catch(CFileException *e)
- {
- LogMsg(LOGF_WARNINGS,"FlushGroup() - Caught FILE ERROR exception (%d) in file '%s' while hiding the file.",
- e->m_cause, e->m_strFileName);
- e->Delete();
- }
- }
- m_Lock.Unlock();*/
- return TRUE;
- }
- // Fill in security information
- BOOL CFsysSecurity::GetFsysSecurityProperties(HANDLE hGrp, CFileInfo& FileInfo)
- {
- BOOL Rval = FALSE;
- CFsysSecurityGrp *pMyGrp = (CFsysSecurityGrp *)hGrp;
- ASSERT(AfxIsValidAddress(pMyGrp, sizeof(CFsysSecurityGrp)));
- ASSERT(AfxIsValidString(FileInfo.m_Name));
- HANDLE h = GetSecurityDescriptor(hGrp, FileInfo.m_Name);
- if (h == INVALID_HANDLE_VALUE)
- {
- FileInfo.m_Comment = "";
- FileInfo.m_DLcount = 0;
- FileInfo.m_User = INVALID_USER_VALUE;
- FileInfo.m_Group = INVALID_USER_VALUE;
- FileInfo.m_Hide = FALSE;
- FileInfo.m_Flags = (FileInfo.m_DOSflags & FILE_ATTRIBUTE_DIRECTORY)
- ? pMyGrp->DefaultPermDirs : pMyGrp->DefaultPermFiles;
- FileInfo.m_SpecialNewFilePerms = 0;
- }
- else
- {
- CFsysSecurityNode *fsn = (CFsysSecurityNode *)h;
- FileInfo.m_Comment = fsn->Comment;
- FileInfo.m_DLcount = fsn->DlCnt;
- FileInfo.m_User = fsn->Owner;
- FileInfo.m_Group = fsn->Class;
- FileInfo.m_Hide = FALSE;
- FileInfo.m_Flags = fsn->Perms;
- FileInfo.m_SpecialNewFilePerms = fsn->SpecialNewFilePerms;
- Rval = TRUE;
- }
- if (FileInfo.m_DOSflags & FILE_ATTRIBUTE_DIRECTORY)
- FileInfo.m_Flags |= NODE_DIR;
- if (FileInfo.m_DOSflags & FILE_ATTRIBUTE_READONLY)
- {
- FileInfo.m_Flags |= NODE_READONLY;
- FileInfo.m_Flags &= ~(NODE_WRITEMSK);
- }
- return Rval;
- }
- int CFsysSecurity::GetPermissions(int User, int Class,
- HANDLE pGrp, LPCSTR FileName, BOOL IsDir, int *Mask,
- CFsysSecurityNode **pFsn, BOOL ShowRealPerms)
- {
- CFsysSecurityGrp *pMyGrp = (CFsysSecurityGrp *)pGrp;
- ASSERT(AfxIsValidAddress(pMyGrp, sizeof(CFsysSecurityGrp)));
- ASSERT(AfxIsValidString(FileName));
- HANDLE h = GetSecurityDescriptor(pGrp, FileName);
- int Perms = 0;
- if (!ShowRealPerms && (!User))
- {
- if (Mask)
- *Mask = 0777;
- return 0777; // Superuser or server call. Override security...
- }
- if (h == INVALID_HANDLE_VALUE)
- {
- if (Mask)
- *Mask = S_IRWXO;
- Perms = IsDir ? pMyGrp->DefaultPermDirs : pMyGrp->DefaultPermFiles;
- }
- else
- {
- CFsysSecurityNode *fsn = (CFsysSecurityNode *)h;
- Perms = fsn->Perms;
- if (Mask)
- {
- *Mask = S_IRWXO;
- if (fsn->Owner && (User == fsn->Owner))
- *Mask |= S_IRWXU;
- if (fsn->Class && (Class == fsn->Class))
- *Mask |= S_IRWXG;
- }
- if (pFsn)
- *pFsn = fsn;
- // TODO: Check for extra permissions for this user/class
- }
- return Perms;
- }
- // Handle fopen(path,"w") to hidden files
- FILE *CFsysSecurity::fopen(LPCSTR DosPath, LPCSTR Mode)
- {
- DWORD dw = GetFileAttributes(DosPath);
- if (strchr(Mode,'w') && (dw != 0xFFFFFFFF) && (dw & FILE_ATTRIBUTE_HIDDEN))
- {
- FILE *fp;
- // Turn off the readonly flag
- dw &= ~FILE_ATTRIBUTE_HIDDEN;
- SetFileAttributes(DosPath,dw);
- // open the file
- fp = ::fopen(DosPath,Mode);
- // Turn on the readonly flag
- dw |= FILE_ATTRIBUTE_HIDDEN;
- SetFileAttributes(DosPath,dw);
- return fp;
- }
- return ::fopen(DosPath,Mode);
- }
- void CFsysSecurityGrp::DeleteAllNodes()
- {
- CFsysSecurityNode *fsn;
- while(fsn = (CFsysSecurityNode *)m_Nodes.GetAndDeleteFirst())
- delete fsn;
- }
- CFsysSecurityNode::~CFsysSecurityNode()
- {
- ASSERT(AfxIsValidAddress(this,sizeof(CFsysSecurityNode)));
- }
- CFsysSecurityGrp::CFsysSecurityGrp()
- {
- m_fp = NULL;
- }
- CFsysSecurityGrp::~CFsysSecurityGrp()
- {
- ASSERT(AfxIsValidAddress(this,sizeof(CFsysSecurityGrp)));
- DeleteAllNodes();
- ASSERT(m_fp == NULL);
- }