Re: Socket forwarding with non existent remote directories

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



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

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux