[openssh-commits] [openssh] 01/05: upstream: refactor tilde_expand_filename() and make it handle ~user

git+noreply at mindrot.org git+noreply at mindrot.org
Sat Jan 8 18:38:58 AEDT 2022


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 961411337719d4cd78f1ab33e4ac549f3fa22f50
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Sat Jan 8 07:32:45 2022 +0000

    upstream: refactor tilde_expand_filename() and make it handle ~user
    
    paths with no trailing slash; feedback/ok markus and jsg
    
    OpenBSD-Commit-ID: a2ab365598a902f0f14ba6a4f8fb2d07a9b5d51d
---
 misc.c | 76 ++++++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 46 insertions(+), 30 deletions(-)

diff --git a/misc.c b/misc.c
index f541055c..c22d7c68 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.171 2021/11/13 21:14:13 deraadt Exp $ */
+/* $OpenBSD: misc.c,v 1.172 2022/01/08 07:32:45 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005-2020 Damien Miller.  All rights reserved.
@@ -1119,53 +1119,69 @@ freeargs(arglist *args)
 int
 tilde_expand(const char *filename, uid_t uid, char **retp)
 {
-	const char *path, *sep;
-	char user[128], *ret;
+	char *ocopy = NULL, *copy, *s = NULL;
+	const char *path = NULL, *user = NULL;
 	struct passwd *pw;
-	u_int len, slash;
+	size_t len;
+	int ret = -1, r, slash;
 
+	*retp = NULL;
 	if (*filename != '~') {
 		*retp = xstrdup(filename);
 		return 0;
 	}
-	filename++;
+	ocopy = copy = xstrdup(filename + 1);
 
-	path = strchr(filename, '/');
-	if (path != NULL && path > filename) {		/* ~user/path */
-		slash = path - filename;
-		if (slash > sizeof(user) - 1) {
-			error_f("~username too long");
-			return -1;
+	if (*copy == '\0')				/* ~ */
+		path = NULL;
+	else if (*copy == '/') {
+		copy += strspn(copy, "/");
+		if (*copy == '\0')
+			path = NULL;			/* ~/ */
+		else
+			path = copy;			/* ~/path */
+	} else {
+		user = copy;
+		if ((path = strchr(copy, '/')) != NULL) {
+			copy[path - copy] = '\0';
+			path++;
+			path += strspn(path, "/");
+			if (*path == '\0')		/* ~user/ */
+				path = NULL;
+			/* else				 ~user/path */
 		}
-		memcpy(user, filename, slash);
-		user[slash] = '\0';
+		/* else					~user */
+	}
+	if (user != NULL) {
 		if ((pw = getpwnam(user)) == NULL) {
 			error_f("No such user %s", user);
-			return -1;
+			goto out;
 		}
-	} else if ((pw = getpwuid(uid)) == NULL) {	/* ~/path */
+	} else if ((pw = getpwuid(uid)) == NULL) {
 		error_f("No such uid %ld", (long)uid);
-		return -1;
+		goto out;
 	}
 
 	/* Make sure directory has a trailing '/' */
-	len = strlen(pw->pw_dir);
-	if (len == 0 || pw->pw_dir[len - 1] != '/')
-		sep = "/";
-	else
-		sep = "";
+	slash = (len = strlen(pw->pw_dir)) == 0 || pw->pw_dir[len - 1] != '/';
 
-	/* Skip leading '/' from specified path */
-	if (path != NULL)
-		filename = path + 1;
-
-	if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) {
+	if ((r = xasprintf(&s, "%s%s%s", pw->pw_dir,
+	    slash ? "/" : "", path != NULL ? path : "")) <= 0) {
+		error_f("xasprintf failed");
+		goto out;
+	}
+	if (r >= PATH_MAX) {
 		error_f("Path too long");
-		return -1;
+		goto out;
 	}
-
-	*retp = ret;
-	return 0;
+	/* success */
+	ret = 0;
+	*retp = s;
+	s = NULL;
+ out:
+	free(s);
+	free(ocopy);
+	return ret;
 }
 
 char *

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list