diff options
author | Damien Miller <djm@mindrot.org> | 2005-05-26 12:02:14 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-05-26 12:02:14 +1000 |
commit | 5fd38c0ed985d7d699e6be1ff5d211cac130b71e (patch) | |
tree | aa80a3f2b1e522b6f83805ab582645df2049f6ab /misc.c | |
parent | 1b0de9a04127eeec9a5352abd16113bb8faa494c (diff) | |
download | openssh-git-5fd38c0ed985d7d699e6be1ff5d211cac130b71e.tar.gz |
- djm@cvs.openbsd.org 2005/04/09 04:32:54
[misc.c misc.h tildexpand.c Makefile.in]
replace tilde_expand_filename with a simpler implementation, ahead of
more whacking; ok deraadt@
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 47 |
1 files changed, 46 insertions, 1 deletions
@@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.29 2005/03/10 22:01:05 deraadt Exp $"); +RCSID("$OpenBSD: misc.c,v 1.30 2005/04/09 04:32:54 djm Exp $"); #include "misc.h" #include "log.h" @@ -376,6 +376,51 @@ addargs(arglist *args, char *fmt, ...) } /* + * 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) +{ + const char *path; + char user[128], ret[MAXPATHLEN]; + struct passwd *pw; + int len; + + if (*filename != '~') + return (xstrdup(filename)); + filename++; + + path = strchr(filename, '/'); + if (path != NULL && path > filename) { /* ~user/path */ + if (path - filename > sizeof(user) - 1) + fatal("tilde_expand_filename: ~username too long"); + memcpy(user, filename, path - filename); + user[path - filename] = '\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 %d", uid); + + if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + + /* Make sure directory has a trailing '/' */ + len = strlen(pw->pw_dir); + if ((len == 0 || pw->pw_dir[len - 1] != '/') && + strlcat(ret, "/", sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + + /* Skip leading '/' from specified path */ + if (path != NULL) + filename = path + 1; + if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + + return (xstrdup(ret)); +} + +/* * Read an entire line from a public key file into a static buffer, discarding * lines that exceed the buffer size. Returns 0 on success, -1 on failure. */ |