read permission denied using NTFS when I denied write permission - c#

Using the below code I denied write permission for a user, even when I checked security tab only write permission is denied, but I'm not able to access the folder for reading.
ADsSecurity objADsSec;
SecurityDescriptor objSecDes;
AccessControlList objDAcl;
AccessControlEntry objAce1;
AccessControlEntry objAce2;
Object objSIdHex;
ADsSID objSId;
objADsSec = new ADsSecurityClass();
objSecDes = (SecurityDescriptor)(objADsSec.GetSecurityDescriptor("FILE://" + vPath));
objDAcl = (AccessControlList)objSecDes.DiscretionaryAcl;
objSId = new ADsSIDClass();
objSId.SetAs((int)ADSSECURITYLib.ADS_SID_FORMAT.ADS_SID_SAM, UserName.ToString());
objSIdHex = objSId.GetAs((int)ADSSECURITYLib.ADS_SID_FORMAT.ADS_SID_SDDL);
objAce2 = new AccessControlEntryClass();
objAce2.Trustee = (objSIdHex).ToString();
objAce2.AccessMask = (int)ActiveDs.ADS_RIGHTS_ENUM.ADS_RIGHT_GENERIC_WRITE;
objAce2.AceType = (int)ActiveDs.ADS_ACETYPE_ENUM.ADS_ACETYPE_ACCESS_DENIED;
objAce2.AceFlags = (int)ActiveDs.ADS_ACEFLAG_ENUM.ADS_ACEFLAG_INHERIT_ACE | 1;
objDAcl.AddAce(objAce2);
objSecDes.DiscretionaryAcl = objDAcl;
// Set permissions on the NTFS file system folder.
objADsSec.SetSecurityDescriptor(objSecDes, "FILE://" + vPath);

You're not showing objAce1
You need to order Deny ACE entries before Grant ACE entries.
Try swapping the order of entries in the ACL.
Thus, the DACL's list of ACEs should be appropriately ordered. The standard (canonical) ordering is to first place explicit denies, then explicit allows, general (group) denies, and group allows. If the canonical ordering isn't used, unanticipated allows or denies may occur
From Understanding Windows File And Registry Permissions

Related

How to use shared memory between service and User Interface App in c#?

If I write following in service:
mmfKernel = MemoryMappedFile.CreateNew("Global\\myMMF", 1024);
and following in user app:
MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("Global\\myMMF");
I get access denial to global mmf. How to grant access rights to mmfKernel to everyone with all possible rights?
But the other way round,
following in user app after I acquire SeCreateGlobalPrivilege:
mmfKernel = MemoryMappedFile.CreateNew("Global\\myMMF", 1024);
and following in service:
MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("Global\\myMMF");
I get path access denial while creating mmfKernel even though I have already SeCreateGlobalPrivilege.
How to create it as normal user but not admin?
If they run under different user accounts, and you think memory mapped files is a good IPC for your use case, you should use another CreateNew version, which accepts MemoryMappedFileSecurity argument with the permissions.
Here’s how to creates an access control list which gives full control permission to everyone:
var sid = new SecurityIdentifier( WellKnownSidType.WorldSid, null );
var ace = new AccessRule<MemoryMappedFileRights>( sid,
MemoryMappedFileRights.FullControl, AccessControlType.Allow );
var acl = new MemoryMappedFileSecurity();
acl.AddAccessRule( ace );
Then pass that acl object to MemoryMappedFile.CreateNew method.
Consider which permissions you actually need. If your desktop process only needs read access to the shared file, change the access rule accordingly. Also it’s a good idea to use more specific trustee instead of everyone, maybe AuthenticatedUserSid (=“Authenticated users”) in place of WorldSid (=“Everyone”), maybe a specific user account or security group.

List the content of a given directory for different users, Linux

Using .NET Core, C#, Linux
I've searched around a bit and can't seem to find anything. Maybe it's not possible and I need a different approach?
Can someone kindly point me in the direction of how I can go about getting the directory listing for a given path for a specific username?
I am running a web application service as Root but need to check and return directories and files for a given username (no password is available) - to report directories and files that a given username has read-access to.
Say for example "/opt/mydata/" and in there I will have a number of directories that I will manually create and set the permissions for each user group. I.e. "/opt/mydata/user_1_readable" will be returned when I do a directory listing for user1 (because this user is in the respective permissions group, or is the owner, or it is set for everyone to read) but will not be returned for user2 (this user is not in the correct group).
Essentially, I want to "impersonate" or in Linux, do the equivalent of "sudo su user1" and report what directories/files are readable within "/opt/mydata/" for a given user.
I can get the directory listing and files fine running as Root. What I can't do / don't know how to is getting the directory listing for a specific user. The examples I found and tried are all Windows Identity and Windows Security specific.
E.g. I found this example but it seemed to apply to "Mono" which I am not running, but essentially I really want to do something along the lines of this:
// Impersonate a user
using (WindowsIdentity newId = new WindowsIdentity("user1"))
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
var content = _fileProvider.GetDirectoryContents(uri);
}
Is there some third party library or some other way please?
Resource:
Change current Linux user in a C# application running with Mono?
If you look at this issue on .net core repository, Proposal: Expose POSIX functions , it looks like it won't be implemented in .net core, but only in Mono.Posix.NETStandard.
The library is compatible with .net core 2.0, and it shouldn't be too hard to implement this yourself.
You could try something like this with the package to filter which files the user can read.
public UserHasReadPermission(string username, string file)
{
var user = new UnixUserInfo(username);
var file = new UnixFileInfo(file);
// Everyone has read permission
if (file.FileAccessPermissions.HasFlag(FileAccessPermissions.OtherRead))
return true;
// User owns the file and has read permission
if (file.OwnerUser == user && file.FileAccessPermissions.HasFlag(FileAccessPermissions.UserRead))
return true;
// User group owns the file and has read permission
if (file.OwnerGroup == user.Group && file.FileAccessPermissions.HasFlag(FileAccessPermissions.GroupRead))
return true;
return false;
}
Perhaps you want to read the /etc/passwd file to get users' directories?
Once you have that, you can then get all subdirs inside the folders:
List<string> AllFiles = new List<string>();
void ParsePath(string path)
{
string[] SubDirs = Directory.GetDirectories(path);
AllFiles.AddRange(SubDirs);
AllFiles.AddRange(Directory.GetFiles(path));
foreach (string subdir in SubDirs)
ParsePath(subdir);
}

Modifying an existing access control entry

I had made a logic error in the FileSystemRights interpretation which was causing it to always applied Read permission no matter what else was entered.
I'm making a ps cmdlet which is meant to be fed a list of username and modify the permissions for a folder of the same name as the user. From my testing this script will create the new special acl entry for the user for an allow or deny entry however it will not modify the entry if it already exists. I.e. if a user has read access already and I attempt to grant write access it does not change the entry. I am not sure how I would go about modifying the existing permission without completely removing the old permissions.
DirectoryInfo diDirInfo = new DirectoryInfo(FolderName);
DirectorySecurity dsDirSecurity = diDirInfo.GetAccessControl();
//These just interpet the objects for the rights and the allow/deny entries from the command line
FileSystemRights FSR = genFSR();
AccessControlType ACT = genAct();
dsDirSecurity.AddAccessRule(new FileSystemAccessRule(UserName, FSR, ACT));
diDirInfo.SetAccessControl(dsDirSecurity);
I tried ModifyAccessRule and got the same behavior.
FileSystemAccessRule fsaRule = new FileSystemAccessRule(UserName, FSR, ACT);
dsDirSecurity.ModifyAccessRule(AccessControlModification.Add, fsaRule, out modified);
Use ModifyAccessRule instead of AddAccessRule.
See http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.objectsecurity.modifyaccessrule.aspx

How can I remove ACL from folder that owned by non-existing user

I am developing a C# application.
I need to change the ACLs on a folder, to do so I am running my program as elevated administrator, and everything works fine.
The problem is that if the user that owns the folder got deleted from the system, then when I try to take ownership on the folder I get unauthorized exception.
This is the code that fails:
using (new PrivilegeEnabler(Process.GetCurrentProcess(), Privilege.TakeOwnership))
{
var directorySecurity = directoryInfo.GetAccessControl();
directorySecurity.SetOwner(WindowsIdentity.GetCurrent().User);
Directory.SetAccessControl(directoryInfo.FullName, directorySecurity);
}
The exception occurs on the line: directoryInfo.GetAccessControl();
PrivilegeEnabler is a class defined in Process Privileges , and it's used to take ownership on the file.
I found a solution.
You need to set the owner, by creating a new access control (without calling to GetAccessControl) and setting the owner to the current process.
and then you can do whatever you want with the file.
using (new PrivilegeEnabler(Process.GetCurrentProcess(), Privilege.TakeOwnership))
{
//create empty directory security
var directorySecurity = new DirectorySecurity();
//set the directory owner to current user
directorySecurity.SetOwner(WindowsIdentity.GetCurrent().User);
//set the access control
Directory.SetAccessControl(directoryInfo.FullName, directorySecurity);
}

Directory Permission Watcher in c#

I have created the program which is monitoring a directory (e.g. \\server\share\folderXYZ) for changed events (like created, deleted, renamed and permission changes). I also got the notification if anything changed but I can't get exact details what has changed.
For example I have changed the permission for above directory from folder properties (Properties -> Security -> Edit ->Add new user or group or change permission for user and groups). File system watcher give notification if something changed but I can't get other details like:
For which user permission has changed?
Who changed the user permissions?
If any new group has been added(need to get all users in the group if new group added)?
If any new user is added to group and who added and need to get added user details?
If any user or group is removed than removed group or user details?
If any permission is added or changed for user than what permission are added or changed?
If any permission are changed for group than what permission changed?
Example Scenarios:
Action: At 11am, the Admin added User A to Trainees (Existing group)
Expected Result:
Access to \\server\share\folderXYZ changed: User A now has Read access, given by Admin at 11am, because he is now member of Trainees, which has Read Access.
Hope question is clear. I have done lots of search and couldn't find the solution. Please let me know if any API or Service available or any alternatives available?
-Thanks
The way to get the information you want is to use Windows Security Auditing, esp. since you want to know who made a change, not just what the change was.
The following code (and settings), produce output like this:
11-07-2011 17:43:10: 'Fujitsu\Grynn' changed security descriptor on file 'C:\Users\Grynn\Documents\ExcelTools\test.txt' from
'D:AI(A;;0x1200a9;;;BU)(A;ID;FA;;;S-1-5-21-559386011-2179397067-1987725642-1000)(A;ID;FA;;;SY)(A;ID;FA;;;BA)'
to
'D:ARAI(A;ID;FA;;;S-1-5-21-559386011-2179397067-1987725642-1000)(A;ID;FA;;;SY)(A;ID;FA;;;BA)'
using 'C:\Windows\explorer.exe'
12-07-2011 17:55:10: 'Fujitsu\Grynn' changed security descriptor on file 'C:\Users\Grynn\Documents\ExcelTools\test.txt' from
'D:AI(A;ID;FA;;;S-1-5-21-559386011-2179397067-1987725642-1000)(A;ID;FA;;;SY)(A;ID;FA;;;BA)'
to
'D:ARAI(D;;FA;;;S-1-5-21-559386011-2179397067-1987725642-1001)(A;ID;FA;;;S-1-5-21-559386011-2179397067-1987725642-1000)(A;ID;FA;;;SY)(A;ID;FA;;;BA)'
using 'C:\Windows\explorer.exe'
Turning on Auditing has 2 steps:
1. Use gpedit.msc to turn on "Audit Object access"
2. Modify "Auditing" for the folder you want to watch
Now whenever a File System Change event occurs (or via polling) query the security event log.
Code to query 'Security' event log:
var props = new EventLogPropertySelector(new string[] {
"Event/System/TimeCreated/#SystemTime",
"Event/EventData/Data[#Name='SubjectDomainName']",
"Event/EventData/Data[#Name='SubjectUserName']",
"Event/EventData/Data[#Name='ObjectName']",
"Event/EventData/Data[#Name='OldSd']",
"Event/EventData/Data[#Name='NewSd']",
"Event/EventData/Data[#Name='ProcessName']" });
using (var session = new System.Diagnostics.Eventing.Reader.EventLogSession())
{
//4670 == Permissions on an object were changed
var q = new EventLogQuery("Security", PathType.LogName, "*[System[(EventID=4670)]]");
q.Session = session;
EventLogReader rdr = new EventLogReader(q);
for (EventRecord eventInstance = rdr.ReadEvent();
null != eventInstance; eventInstance = rdr.ReadEvent())
{
var elr = ((EventLogRecord)eventInstance);
Console.WriteLine(
"{0}: '{1}\\{2}' changed security descriptor on file '{3}' from \n'{4}' \nto \n'{5}' \nusing '{6}'\n----\n",
elr.GetPropertyValues(props).ToArray());
}
}
From what i know/been reading, FileSystemWatcher can only tell you the file that was affected along with the change type only.
One way to go is for you to maintain a cache of the file attributes you're interested in, an in the presence of an event notifying a change, you query the cache to get the changes made and update it as necessary.

Categories

Resources