简体   繁体   中英

Change file owner on linux with .NET Core

To get file owner using

new System.Security.AccessControl.FileSecurity(filename, AccessControlSections.Owner);

gives

System.PlatformNotSupportedException: Access Control List (ACL) APIs are part of resource management on Windows and are not supported on this platform

So changing cannot be done this way too.

Add package

Mono.Posix.NETStandard

And use wrapper for chown(3) .

Notice: chown fail with EPERM if called not as root , because all linux restrictions are effective).

using Mono.Unix.Native;
...

var passwd = Syscall.getpwnam("nobody");
if (passwd == null)
{
    var errno = Syscall.GetLastError();   
    switch (errno)
    {
        case Errno.ENOENT:
            throw new KeyNotFoundException("No user corresponding to uid.");
        case Errno.ESRCH:
            throw new IOException("ESRCH");
        case Errno.EBADF:
            throw new IOException("EBADF");
        case Errno.EPERM:
            throw new UnauthorizedAccessException("The effective user ID does not match the owner of the file, or the calling process does not have appropriate privileges and _POSIX_CHOWN_RESTRICTED indicates that such privilege is required.");
        case Errno.EIO:
            throw new IOException("An I/O error occurred while reading or writing to the file system.");
        case Errno.EMFILE:
            throw new IOException("The maximum number (OPEN_MAX) of files was open already in the calling process.");
        case Errno.ENFILE:
            throw new KeyNotFoundException("The maximum number of files was open already in the system.");
        case Errno.ENOMEM:
            throw new InsufficientMemoryException("Insufficient memory to allocate passwd structure.");
        case Errno.ERANGE:
            throw new Exception("Insufficient buffer space supplied.");
        case Errno.EINTR:
            throw new IOException("The getpwnam() function was interrupted by a signal which was caught.");
        default:
            throw new Exception($"Unknown exception during chown, errno: {errno}.");
    }
}
if (0 != Syscall.chown(fileInfo.FullName, passwd.pw_uid, passwd.pw_gid))
{
    var errno = Syscall.GetLastError();
    switch (errno)
    {
        case Errno.EACCES:
            throw new UnauthorizedAccessException("Search permission is denied on a component of the path prefix.");
        case Errno.ELOOP:
            throw new IOException("A loop exists in symbolic links encountered during resolution of the path argument. More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the path argument.");
        case Errno.ENAMETOOLONG:
            throw new PathTooLongException("The length of the path argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}. As a result of encountering a symbolic link in resolution of the path argument, the length of the substituted pathname string exceeded {PATH_MAX}.");
        case Errno.ENOTDIR:
            throw new DirectoryNotFoundException("A component of the path prefix is not a directory.");
        case Errno.ENOENT:
            throw new FileNotFoundException("A component of path does not name an existing file or path is an empty string.");
        case Errno.EPERM:
            throw new UnauthorizedAccessException("The effective user ID does not match the owner of the file, or the calling process does not have appropriate privileges and _POSIX_CHOWN_RESTRICTED indicates that such privilege is required.");
        case Errno.EROFS:
            throw new IOException("The named file resides on a read-only file system.");
        case Errno.EIO:
            throw new IOException("An I/O error occurred while reading or writing to the file system.");
        case Errno.EINTR:
            throw new IOException("The chown() function was interrupted by a signal which was caught.");
        case Errno.EINVAL:
            throw new NotSupportedException("The owner or group ID supplied is not a value supported by the implementation.");
        default:
            throw new Exception($"Unknown exception during getpwnam, errno: {errno}.");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM