From 2ab864010e0a93c5dd95116fb5ceaf430e2fc23c Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 9 Aug 2021 23:47:44 +0000 Subject: 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 --- misc.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'misc.c') 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; } /* -- cgit v1.2.1