|
From: falco on 1 Oct 2006 09:35 Hi all! Hoping that someone might be able to give me a hint or two here. I'm trying to check that the current user has permission to write to or delete a file on disk. Using pretty bare C++, no COM etc. I've looked everywhere for an example, but just couldn't find anything. So in the end I hacked something together, which seems to work 95% of the time, but the remaining 5% eludes me. So, the question is - if I want to find out if the current user can write to or delete a file pointed to by a string path, how do I go about it? My current code is pasted below, but as I say, it's a bit on the faulty side. For anyone looking at the code, it's worth paying attention to the code directly after "//Note - these below are never hit." - these are what I would have expected to provide the info required, but as the comment says, those bits are never set. The only one that seemed to be doing what was expected was the delete permission flag, which is what I tried to use, but that's obviously insufficient. The specific failure: On one machine (Windows 2000 Professional, Dutch language), this code reports that the user doesn't have permission to delete a file, when the file is obviously modifiable, and in fact can be deleted manually from within Explorer without problems. What have I messed up? Am I close to the answer, or completely misguided? Hints, suggestions etc gladly accepted! //Example: //Does the current user have permission to update a given file? //Cobbled together from various examples and functions, //needs tidy-up. ace_list* m_sAceList = NULL; // list of Access Control Entries BOOL bSuccess = TRUE; BYTE* pSecDescriptorBuf; DWORD dwSizeNeeded = 0; // Find out size of needed buffer for security descriptor with DACL // DACL = Discretionary Access Control List bSuccess = GetFileSecurityW((BSTR)sPath, DACL_SECURITY_INFORMATION, NULL, 0, &dwSizeNeeded); if (0 == dwSizeNeeded) { return failure; } pSecDescriptorBuf = new BYTE[dwSizeNeeded]; // Retrieve security descriptor with DACL information bSuccess = GetFileSecurityW((BSTR)sPath, DACL_SECURITY_INFORMATION, pSecDescriptorBuf, dwSizeNeeded, &dwSizeNeeded); // Check if we successfully retrieved security descriptor with DACL information if (!bSuccess) { DWORD dwError = GetLastError(); return failure; } // Getting DACL from Security Descriptor PACL pacl; BOOL bDaclPresent, bDaclDefaulted; bSuccess = GetSecurityDescriptorDacl((SECURITY_DESCRIPTOR*)pSecDescriptorBuf, &bDaclPresent, &pacl, &bDaclDefaulted); // Check if we successfully retrieved DACL if (!bSuccess) { DWORD dwError = GetLastError(); //cout << "Failed to retrieve DACL from security descriptor (" << dwError << ")\n"; return failure; } // Check if DACL present in security descriptor if (!bDaclPresent) { //cout << "DACL was not found.\n"; return failure; } //Check to see if the current user has access. wchar_t wszAccName[100] = L""; DWORD accNameSize = sizeof(wszAccName); PSID ppSid; DWORD cbSid = 0; DWORD cchDomainName = 0; //DWORD dwDomainBufferSize = INITIAL_SIZE; wchar_t * wszDomainName = NULL; SID_NAME_USE eSidType; //Allocate SID buffer. ppSid = (PSID) new BYTE[1024]; cbSid = 1024; wszDomainName = new wchar_t[1024]; cchDomainName = 1024; if (!GetUserName( wszAccName, &accNameSize ) ){ //fail } if (LookupAccountName( NULL, // Computer name.NULL for the local computer wszAccName, ppSid, // Pointer to the SID buffer. Use NULL to get the size needed, &cbSid, // Size of the SID buffer needed. wszDomainName, // wszDomainName, &cchDomainName, &eSidType )) { if (IsValidSid(ppSid) == FALSE) { gMessageBox("Error: Invalid SID for %s.", wszAccName); return failure; } else { TRUSTEE trustee; BuildTrusteeWithSid(&trustee, ppSid); ACCESS_MASK mask = 0; DWORD dwRetVal = GetEffectiveRightsFromAcl(pacl, &trustee, &mask); if (!(mask & 65536)){ Assert(false); return failure; } //Note - these below are never hit. This is the first sign that things are going wrong... if (mask & GENERIC_READ) DebugOut("I can read!"); if (mask & GENERIC_WRITE) DebugOut("I can write!"); if (mask & GENERIC_EXECUTE) DebugOut("I can exe!"); if (mask & GENERIC_ALL) DebugOut("I can everything!"); } } else { DWORD lErrorCode = GetLastError(); // Check if one of the buffers was too small. if (lErrorCode == ERROR_INSUFFICIENT_BUFFER){ } }
From: Alexander Grigoriev on 1 Oct 2006 12:11 This function may not map specific access rights to generic. Check specific rights mask, such as FILE_READ_DATA, etc. <falco(a)fenz.net> wrote in message news:1159709758.931222.151860(a)k70g2000cwa.googlegroups.com... > Hi all! > > Hoping that someone might be able to give me a hint or two here. I'm > trying to check that the current user has permission to write to or > delete a file on disk. Using pretty bare C++, no COM etc. I've looked > everywhere for an example, but just couldn't find anything. So in the > end I hacked something together, which seems to work 95% of the time, > but the remaining 5% eludes me. So, the question is - if I want to find > out if the current user can write to or delete a file pointed to by a > string path, how do I go about it? My current code is pasted below, but > as I say, it's a bit on the faulty side. For anyone looking at the > code, it's worth paying attention to the code directly after "//Note - > these below are never hit." - these are what I would have expected to > provide the info required, but as the comment says, those bits are > never set. The only one that seemed to be doing what was expected was > the delete permission flag, which is what I tried to use, but that's > obviously insufficient. > > The specific failure: On one machine (Windows 2000 Professional, Dutch > language), this code reports that the user doesn't have permission to > delete a file, when the file is obviously modifiable, and in fact can > be deleted manually from within Explorer without problems. > > What have I messed up? Am I close to the answer, or completely > misguided? Hints, suggestions etc gladly accepted! > > > //Example: > //Does the current user have permission to update a given file? > //Cobbled together from various examples and functions, > //needs tidy-up. > > > ace_list* m_sAceList = NULL; // list of Access Control Entries > BOOL bSuccess = TRUE; > BYTE* pSecDescriptorBuf; > DWORD dwSizeNeeded = 0; > > // Find out size of needed buffer for security descriptor with DACL > // DACL = Discretionary Access Control List > bSuccess = GetFileSecurityW((BSTR)sPath, > DACL_SECURITY_INFORMATION, > NULL, > 0, > &dwSizeNeeded); > > if (0 == dwSizeNeeded) > { > return failure; > } > pSecDescriptorBuf = new BYTE[dwSizeNeeded]; > > // Retrieve security descriptor with DACL information > bSuccess = GetFileSecurityW((BSTR)sPath, > DACL_SECURITY_INFORMATION, > pSecDescriptorBuf, > dwSizeNeeded, > &dwSizeNeeded); > > // Check if we successfully retrieved security descriptor with DACL > information > if (!bSuccess) > { > DWORD dwError = GetLastError(); > return failure; > } > > // Getting DACL from Security Descriptor > PACL pacl; > BOOL bDaclPresent, bDaclDefaulted; > bSuccess = > GetSecurityDescriptorDacl((SECURITY_DESCRIPTOR*)pSecDescriptorBuf, > &bDaclPresent, &pacl, &bDaclDefaulted); > > // Check if we successfully retrieved DACL > if (!bSuccess) > { > DWORD dwError = GetLastError(); > //cout << "Failed to retrieve DACL from security descriptor (" << > dwError << ")\n"; > return failure; > } > > // Check if DACL present in security descriptor > if (!bDaclPresent) > { > //cout << "DACL was not found.\n"; > return failure; > } > > //Check to see if the current user has access. > wchar_t wszAccName[100] = L""; > DWORD accNameSize = sizeof(wszAccName); > PSID ppSid; > DWORD cbSid = 0; > DWORD cchDomainName = 0; > //DWORD dwDomainBufferSize = INITIAL_SIZE; > wchar_t * wszDomainName = NULL; > SID_NAME_USE eSidType; > > > //Allocate SID buffer. > ppSid = (PSID) new BYTE[1024]; > cbSid = 1024; > wszDomainName = new wchar_t[1024]; > cchDomainName = 1024; > > > if (!GetUserName( wszAccName, &accNameSize ) ){ > //fail > } > if (LookupAccountName( NULL, // Computer name.NULL for the local > computer > wszAccName, ppSid, // Pointer to the SID buffer. Use NULL to get the > size needed, > &cbSid, // Size of the SID buffer needed. > wszDomainName, // wszDomainName, > &cchDomainName, &eSidType )) > { > if (IsValidSid(ppSid) == FALSE) > { > gMessageBox("Error: Invalid SID for %s.", wszAccName); > return failure; > } else { > > TRUSTEE trustee; > BuildTrusteeWithSid(&trustee, ppSid); > > ACCESS_MASK mask = 0; > DWORD dwRetVal = GetEffectiveRightsFromAcl(pacl, > &trustee, > &mask); > > > if (!(mask & 65536)){ > Assert(false); > return failure; > } > //Note - these below are never hit. This is the first sign that things > are going wrong... > if (mask & GENERIC_READ) DebugOut("I can read!"); > if (mask & GENERIC_WRITE) DebugOut("I can write!"); > if (mask & GENERIC_EXECUTE) DebugOut("I can exe!"); > if (mask & GENERIC_ALL) DebugOut("I can everything!"); > } > } else { > DWORD lErrorCode = GetLastError(); // Check if one of the buffers was > too small. > if (lErrorCode == ERROR_INSUFFICIENT_BUFFER){ > } > } >
From: falco on 1 Oct 2006 21:53 Hi Alexander, Thanks very much for that hint - looking at my notes it should have been obvious! Oh well - I've changed that and sent a new version to the guy who was having trouble, hopefully it'll fix it. If not I'll post a note here! Thanks, Mike. Alexander Grigoriev wrote: > This function may not map specific access rights to generic. Check specific > rights mask, such as FILE_READ_DATA, etc.
|
Pages: 1 Prev: function in DLL Next: error MFC80UD.dll not found when running in debug mode |