0

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?

PKCS12
  • 407
  • 15
  • 41
  • Do you have the directory path that you need to look at? or do you need to resolve the home directory of users? – Martin Ullrich Apr 09 '19 at 08:29
  • What *exactly* do you mean by "for a specific username"? If you know the path, why would the output differ for different users? Or is the path relative (to the home directory of said user)? – Lasse V. Karlsen Apr 09 '19 at 08:53
  • Sorry! Added some useful info. hopefully. – PKCS12 Apr 09 '19 at 09:08
  • *Is there some third part library or some other way please?* No, it's all built-in .net-core, you shouldn't need any third party libraries. – Justin Lessard Apr 11 '19 at 16:31
  • It's unclear what you're asking. Do you have trouble finding/listing content of a directory? Or do you have problem with filesystem permission? What exactly is your issue? – Justin Lessard Apr 11 '19 at 16:31
  • Sorry, sorry, sorry. My question but be really unclear :( I've added further to it! – PKCS12 Apr 11 '19 at 16:53

2 Answers2

1

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;
}
Justin Lessard
  • 10,804
  • 5
  • 49
  • 61
  • Hi Justin, that's a brilliant find and suggestion. Thank you. Unfortunately, I've been restricted from doing it this way and need to achieve the results through using Process() - I need to go investigate this now. Thanks again for your answer though, hopefully it is helpful to someone else still. Will award in a bit. Any ideas how to use Process() to do "sudo su username" and do a "ls" in meantime? :) – PKCS12 Apr 12 '19 at 13:08
  • @Rollhard Still not sure what is your end goal here. `ls` will always return all files, even if the user doesn't have read permission. – Justin Lessard Apr 12 '19 at 13:38
  • I found an alternative approach! That is to start a new Process() running as a different user and I can run whatever commands I need from there. – PKCS12 Apr 12 '19 at 16:23
0

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);
}
Amir Hajiha
  • 836
  • 8
  • 20