How to manage permissions of a UnixListener

How can I set read/write permissions of a UDS socket?

Inside my rust application, I create the socket with:

let listener = std::os::unix::net::UnixListener::bind(uds_path);

or, most of the time, with tokio:

let listener = tokio_uds::UnixListener::bind(uds_path);

After the creation, I need to change the read/write permissions and/or to change the owner of the socket.
Is there a way to achieve it?

You can use File and permissions methods operating on uds_path directly.

Alternatively, if you're worried about race conditions, you can use to get the file descriptor from the socket, and change permissions through it.

Hi @kornel,
thanks for the hint, but I don't understand how the AsRawFd should be used.
listener.as_raw_fd() returns nothing more than an i32.
Could you point me to any sample code?

Then there's that can make File.

Something like that?

let file = File::from_raw_fd(listener.as_raw_fd())?;
    let mut perms = file.metadata()?.permissions();
let _ = file.into_raw_fd(); // don't close the file

This fd-dance is needed only when you're paranoid that a rogue process on the same machine could hijack the socket before you change the permissions. If you're not worried, then use File::open(uds_path).

Hi @kornel
thanks again!
I think I'll go for the file::open(...) :ok_hand:

Anyway, it's still a mystery to me how File::from_raw_fd(..) can create a File from an i32 :thinking:

That's all a File is - a wrapper around a file descriptor.

I am still not able to make it work...
File::from_raw_fd(...) is an unsafe function which is not an option in my case and returns a "file not found error" which is quite strange since the file is definitely there and the path is definitely correct :thinking:
Can it be caused to the fact that the file is a socket?

I'm using fs::set_permissions on a path shared with UnixListener::bind and it works fine for me.

I confirm that fs::set_permissions works as expected even if returns a "No such device or address" error