On Thu 2016-10-06 00:57:02 -0400, Jim Knoble wrote: > I'm not familiar enough with the syntax of RemoteForward to know which is the local socket and which the remote one, but if it's the remote end's directory that doesn't exist, that can be harder. Edge cases like: > > - The containing file system usually exists, but is not mounted at the time of login. > - There is an error in expansion of the value (for example, the user's home directory was inadvertently reset in /etc/passwd, or the service that backs it gave a bad answer). > - The directory exists, but cannot be stat()ed due to permissions (e.g., /var/run/user is mode 0111). > > Should sshd attempt to create the containing directory in those cases? Currently, i think sshd tries to create the socket (as the non-priv user), and if that fails it gives up. I think sshd could first try to create the containing directory (as the non-priv user, of course), and ignore any failures. It would then proceed as it currently does. In Andre's case, systemd's PAM session hooks create /run/user/<uid>, but he wants to forward a socket to /run/user/<uid>/gnupg/S.gpg-agent. Arguably, the most "correct" fix would be to recursively try to create every directory component in the tree, but Andre's case would be handled just by creating one level of directory. For example, consider this simple (but untested) patch: diff --git a/misc.c b/misc.c index 9421b4d..a85caca 100644 --- a/misc.c +++ b/misc.c @@ -1153,6 +1153,7 @@ unix_listener(const char *path, int backlog, int unlink_first) { struct sockaddr_un sunaddr; int saved_errno, sock; + const char *parentdir; memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; @@ -1174,6 +1175,9 @@ unix_listener(const char *path, int backlog, int unlink_first) if (unlink(path) != 0 && errno != ENOENT) error("unlink(%s): %.100s", path, strerror(errno)); } + parentdir = basename(path); + if (mkdir(parentdir, 0700) != 0 && errno != EEXIST) + error("mkdir(%s): %.100s", parentdir, strerror(errno)); if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { saved_errno = errno; error("bind: %.100s", strerror(errno)); > Perhaps a better approach would be to find a way to use PAM or login > scripts to create the needed directory where appropriate? i don't think login scripts would do the trick; users might forward sockets without initiating a login session, right? So it'd have to be PAM if you take this route. But having to twiddle your pam stack for each new sub-directory you want seems like not a great process. --dkg
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev