0

I'm automating file transfer via SFTP and got stuck when changing file ownership in the remote host. The problem is that SFTP's chown and chgrp commands only accept numeric uids/gids, which are not known beforehand. The expected scenario for my automation is for the user to inform files destinations and string usernames and groupnames.

Is there a way to query the numeric uid/gid from the string user/groupname in the remote host through the SFTP session?

An easy workaround would be to open an additional SSH session and use regular shell's chown and chgrp commands. But the company I work in uses timed tokens for authentication and, in short, an additional session means additional 30 seconds per host, a non-starter for batch installations.
A harder one would be to ls -l directories, maybe files, to find one with the needed credentials, then ls -n to get the numeric version. But this has the risks of taking too long, findind no suitable directories/files or even getting stuck if a directory has too much files for ls to work...

2 Answers2

2

It's not possible.

At least not with the widely used SFTP version 3.

1

An easy workaround would be to open an additional SSH session and use regular shell's chown and chgrp commands. But the company I work in uses timed tokens for authentication and, in short, an additional session means additional 30 seconds per host, a non-starter for batch installations.

With -o ControlMaster= and -o ControlPath= you can share multiple sessions over a single network connection (see man 5 ssh_config). Short options for ssh are -M and -S respectively (see man 1 ssh). This approach requires you to authenticate once. sftp from OpenSSH supports -o and can share a connection with ssh.

The procedure:

  1. ssh -Nf -o ControlMaster=yes -o ControlPath=… user@server. The master connection. Here you authenticate before the connection goes to the background.

  2. ssh -o ControlPath=… … and/or sftp -o ControlPath=… … and/or even sshfs (see below). As long as you stick to the chosen control socket (ControlPath) and the master connection works, these commands will use it. Have fun.

    E.g. you can run uid="$(ssh … "id -u someuser")" and use $uid later in your script.

  3. Finally ssh -o ControlPath=… -O exit … to terminate the master connection.

My other answers that may be useful: