Reputation: 22327
First off, let me ask, do ACL permissions change on per-user basis on Windows-NT? The reason I'm asking is because the accesschk utility seems to take user name as a parameter, while also requiring an object to check (folder path in my case).
In either case, how do you obtain the ACL permissions (this stuff) for a folder for a specific Windows user with C++? I'm assuming I need to call GetNamedSecurityInfo but how do I get permissions out of it for a user account?
Upvotes: 2
Views: 5361
Reputation: 11
#include <windows.h>
#include <iostream>
#include<fileapi.h>
#include<aclapi.h>
#include <unistd.h>
#include <sys/stat.h>
#include<time.h>
using namespace std;
void printFileProperties(struct stat stats)
{
struct tm dt;
printf("\nFile access: ");
if (stats.st_mode & R_OK)
printf("read ");
if (stats.st_mode & W_OK)
printf("write ");
if (stats.st_mode & X_OK)
printf("execute");
printf("\nFile size: %d Bytes", stats.st_size);
dt = *(gmtime(&stats.st_ctime));
printf("\nCreated on: %d-%d-%d %d:%d:%d", dt.tm_mday, dt.tm_mon, dt.tm_year + 1900,
dt.tm_hour, dt.tm_min, dt.tm_sec);
dt = *(gmtime(&stats.st_mtime));
printf("\nModified on: %d-%d-%d %d:%d:%d", dt.tm_mday, dt.tm_mon, dt.tm_year + 1900,
dt.tm_hour, dt.tm_min, dt.tm_sec);
dt = *(gmtime(&stats.st_atime));
printf("\nAccessed on: %d-%d-%d %d:%d:%d", dt.tm_mday, dt.tm_mon, dt.tm_year + 1900,
dt.tm_hour, dt.tm_min, dt.tm_sec);
}
void printGroupProperties(char filepath[])
{
LPCSTR fname;
fname = filepath;
DWORD dwRtnCode = 0;
PSECURITY_DESCRIPTOR psd = NULL;
PACL pdacl;
ACL_SIZE_INFORMATION aclSize = {0};
PSID sidowner = NULL;
PSID sidgroup = NULL;
HANDLE hFile;
LPTSTR oname = NULL;
LPTSTR doname=NULL;
DWORD namelen=0;
DWORD domainnamelen=0;
SID_NAME_USE peUse;
ACCESS_ALLOWED_ACE* ace;
dwRtnCode = GetNamedSecurityInfo(fname
,SE_FILE_OBJECT
,OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
,&sidowner
,&sidgroup
,&pdacl
,NULL
,&psd);
LookupAccountSid(NULL, sidowner, oname, (LPDWORD) &namelen, doname, (LPDWORD) &domainnamelen, &peUse);
oname = (LPTSTR)GlobalAlloc(
GMEM_FIXED,
namelen);
doname = (LPTSTR)GlobalAlloc(
GMEM_FIXED,
domainnamelen);
// wcout<<"Owner: " << doname << "/" << oname <<"\n";
LookupAccountSid(NULL, sidgroup, oname, (LPDWORD) &namelen, doname, (LPDWORD)&domainnamelen, &peUse);
wcout<<"\n\nGroup: " << doname << "/" << oname;
wcout<< "\n::ACCESS CONTROL LIST::";
SID *sid;
unsigned long i, mask;
char *stringsid;
for (int i=0; i<(*pdacl).AceCount; i++) {
int c=1;
namelen=0;
domainnamelen=0;
BOOL b = GetAce(pdacl, i, (PVOID*)&ace);
//SID *sid = (SID *) ace->SidStart;
if (((ACCESS_ALLOWED_ACE *) ace)->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) {
sid = (SID *) &((ACCESS_ALLOWED_ACE *) ace)->SidStart;
LookupAccountSid(NULL, sid, oname, (LPDWORD) &namelen, doname, (LPDWORD)&domainnamelen, &peUse);
oname = (LPTSTR)GlobalAlloc(GMEM_FIXED,namelen);
doname = (LPTSTR)GlobalAlloc(GMEM_FIXED,domainnamelen);
LookupAccountSid(NULL, sid, oname, (LPDWORD) &namelen, doname, (LPDWORD)&domainnamelen, &peUse);
wcout<<"\nUser Group "<<i+1<<":"<< doname << "/" << oname;
mask = ((ACCESS_ALLOWED_ACE *) ace)->Mask;
}
else if (((ACCESS_DENIED_ACE *) ace)->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
sid = (SID *) &((ACCESS_DENIED_ACE *) ace)->SidStart;
LookupAccountSid(NULL, sid, oname,(LPDWORD) &namelen, doname, (LPDWORD)&domainnamelen, &peUse);
oname = (LPTSTR)GlobalAlloc(GMEM_FIXED,namelen);
doname = (LPTSTR)GlobalAlloc(GMEM_FIXED,domainnamelen);
LookupAccountSid(NULL, sid, oname, (LPDWORD) &namelen, doname, (LPDWORD)&domainnamelen, &peUse);
wcout<<"\nUser Group "<<i+1<<":"<< doname << "/" << oname;
mask = ((ACCESS_DENIED_ACE *) ace)->Mask;
}
else printf("Other ACE\n");
cout<<"\nPERMISSIONS:\n";
// wcout<<"ACE: mask:" << ace->Mask << " sidStart:" << ace->SidStart << " header type=" << ace->Header.AceType << " header flags=" << ace->Header.AceFlags <<"\n";
if (DELETE & ace->Mask) {
wcout<< " Delete" << "\n";
}
if (FILE_GENERIC_READ & ace->Mask) {
wcout<< " File_Generic_Read" << "\n";
}
if (FILE_GENERIC_WRITE & ace->Mask) {
wcout<< " File_Generic_Write" << "\n";
}
if (FILE_GENERIC_EXECUTE & ace->Mask) {
wcout<< " File_Generic_Execute" << "\n";
}
if (GENERIC_READ & ace->Mask) {
wcout<< " Generic_Read" << "\n";
}
if (GENERIC_WRITE & ace->Mask) {
wcout<< " Generic_Write" << "\n";
}
if (GENERIC_EXECUTE & ace->Mask) {
wcout<< " Generic_Execute" << "\n";
}
if (GENERIC_ALL & ace->Mask) {
wcout<< " Generic_All" << "\n";
}
if (READ_CONTROL & ace->Mask) {
wcout<< " Read_Control" << "\n";
}
if (WRITE_DAC & ace->Mask) {
wcout<< " Write_DAC" << "\n";
}
if (WRITE_OWNER & ace->Mask) {
wcout<< " Write_Owner" << "\n";
}
if (SYNCHRONIZE & ace->Mask) {
wcout<< " Synchronize" << "\n";
}
wcout<<"\n";
}
SECURITY_DESCRIPTOR* p1 = (SECURITY_DESCRIPTOR*)psd;
wcout<< "\n::SECURITY_DESCRIPTOR_CONTROL::" << "\n";
SECURITY_DESCRIPTOR_CONTROL ctrl = (*p1).Control;
if (SE_OWNER_DEFAULTED & ctrl) {
wcout<< " SE_OWNER_DEFAULTED" << "\n";
}
if (SE_DACL_PRESENT & ctrl) {
wcout<< " SE_DACL_PRESENT" << "\n";
}
if (SE_DACL_DEFAULTED & ctrl) {
wcout<< " SE_DACL_DEFAULTED" << "\n";
}
if (SE_SACL_PRESENT & ctrl) {
wcout<< " SE_SACL_PRESENT" << "\n";
}
if (SE_SACL_DEFAULTED & ctrl) {
wcout<< " SE_SACL_DEFAULTED" << "\n";
}
if (SE_DACL_AUTO_INHERIT_REQ & ctrl) {
wcout<< " SE_DACL_AUTO_INHERIT_REQ" << "\n";
}
if (SE_SACL_AUTO_INHERIT_REQ & ctrl) {
wcout<< " SE_SACL_AUTO_INHERIT_REQ" << "\n";
}
if (SE_SACL_AUTO_INHERITED & ctrl) {
wcout<< " SE_SACL_AUTO_INHERITED" << "\n";
}
if (SE_DACL_PROTECTED & ctrl) {
wcout<< " SE_DACL_PROTECTED" << "\n";
}
if (SE_SACL_PROTECTED & ctrl) {
wcout<< " SE_SACL_PROTECTED" << "\n";
}
if (SE_RM_CONTROL_VALID & ctrl) {
wcout<< " SE_RM_CONTROL_VALID" << "\n";
}
if (SE_SELF_RELATIVE & ctrl) {
wcout<< " SE_SELF_RELATIVE" << "\n";
}
// LocalFree(psd);
// LocalFree(sidowner);
// LocalFree(pdacl);
}
void printFileAttributes(char filepath[])
{
long unsigned int FileAttributes;
FileAttributes=GetFileAttributesA(filepath);
printf("\nFile type:");
if (FileAttributes & FILE_ATTRIBUTE_ARCHIVE)
{
printf("Archive ");
}
if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
printf("Directory ");
}
if (FileAttributes & FILE_ATTRIBUTE_READONLY)
{
printf("Read-Only ");
}
if (FileAttributes & FILE_ATTRIBUTE_HIDDEN)
{
printf("Hidden");
}
}
int main()
{
WIN32_FIND_DATA data;
char dir[100];
cout<<"\nEnter the directory path:";
gets(dir);
char dirname[100];
strcpy(dirname,dir);
strcat(dirname,"\\*");
//cout<<dirname;
HANDLE hFind = FindFirstFile(dirname, &data); // DIRECTORY
struct stat stats;
if ( hFind != INVALID_HANDLE_VALUE ) {
do {
std::cout << "\n\nFile name:"<<data.cFileName;
//cout<<"\nFile Type:";
char filepath[100];
strcpy(filepath,dir);
strcat(filepath,"\\");
strcat(filepath,data.cFileName);
if( stat(filepath, &stats) == 0)
{
printFileProperties(stats);
}
printFileAttributes(filepath);
printGroupProperties(filepath);
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
}
Upvotes: 0
Reputation: 82
"In either case, how do you obtain the ACL permissions (this stuff) for a folder for a specific Windows user with C++?"
DACL returns a pointer that you can use to pull values from.
I have a demo program you can look at, it basically loads DACL info from a given file or directory. The link to the page is shown below.
Sample GetNamedSecurityInfo() call
"I'm assuming I need to call GetNamedSecurityInfo but how do I get permissions out of it for a user account?"
You can walk the list by calling GetAce() and pull the domain/username from each item.
Again, see my example code which is written in C++.
Upvotes: 1
Reputation: 180305
The whole point of ACLs is to differ between users. They're Access Control Lists; they control which users have access to a resource.
You're right on GetNamedSecurityInfo
. It gets you both kinds of ACL's, the SACL and the DACL. SACL deals with file access auditing (rarely used), DACL has permissions. You can break down the DACL returned with GetExplicitEntriesFromAcl
.
Upvotes: 3