summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2021-08-09 23:47:44 +0000
committerDamien Miller <djm@mindrot.org>2021-08-10 12:47:46 +1000
commit2ab864010e0a93c5dd95116fb5ceaf430e2fc23c (patch)
tree2851434ba4912fd244aa2e327580b606e86b159e /misc.c
parent41b019ac067f1d1f7d99914d0ffee4d2a547c3d8 (diff)
downloadopenssh-git-2ab864010e0a93c5dd95116fb5ceaf430e2fc23c.tar.gz
upstream: SFTP protocol extension to allow the server to expand
~-prefixed paths, in particular ~user ones. Allows scp in sftp mode to accept these paths, like scp in rcp mode does. prompted by and much discussion deraadt@ ok markus@ OpenBSD-Commit-ID: 7d794def9e4de348e1e777f6030fc9bafdfff392
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/misc.c b/misc.c
index adfe9033..b8d1040d 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.168 2021/07/12 06:22:57 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.169 2021/08/09 23:47:44 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
@@ -1115,29 +1115,37 @@ freeargs(arglist *args)
* Expands tildes in the file name. Returns data allocated by xmalloc.
* Warning: this calls getpw*.
*/
-char *
-tilde_expand_filename(const char *filename, uid_t uid)
+int
+tilde_expand(const char *filename, uid_t uid, char **retp)
{
const char *path, *sep;
char user[128], *ret;
struct passwd *pw;
u_int len, slash;
- if (*filename != '~')
- return (xstrdup(filename));
+ if (*filename != '~') {
+ *retp = xstrdup(filename);
+ return 0;
+ }
filename++;
path = strchr(filename, '/');
if (path != NULL && path > filename) { /* ~user/path */
slash = path - filename;
- if (slash > sizeof(user) - 1)
- fatal("tilde_expand_filename: ~username too long");
+ if (slash > sizeof(user) - 1) {
+ error_f("~username too long");
+ return -1;
+ }
memcpy(user, filename, slash);
user[slash] = '\0';
- if ((pw = getpwnam(user)) == NULL)
- fatal("tilde_expand_filename: No such user %s", user);
- } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
- fatal("tilde_expand_filename: No such uid %ld", (long)uid);
+ if ((pw = getpwnam(user)) == NULL) {
+ error_f("No such user %s", user);
+ return -1;
+ }
+ } else if ((pw = getpwuid(uid)) == NULL) { /* ~/path */
+ error_f("No such uid %ld", (long)uid);
+ return -1;
+ }
/* Make sure directory has a trailing '/' */
len = strlen(pw->pw_dir);
@@ -1150,10 +1158,23 @@ tilde_expand_filename(const char *filename, uid_t uid)
if (path != NULL)
filename = path + 1;
- if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
- fatal("tilde_expand_filename: Path too long");
+ if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) {
+ error_f("Path too long");
+ return -1;
+ }
+
+ *retp = ret;
+ return 0;
+}
- return (ret);
+char *
+tilde_expand_filename(const char *filename, uid_t uid)
+{
+ char *ret;
+
+ if (tilde_expand(filename, uid, &ret) != 0)
+ cleanup_exit(255);
+ return ret;
}
/*