=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/auth.c,v retrieving revision 1.56.2.3 retrieving revision 1.57 diff -u -r1.56.2.3 -r1.57 --- src/usr.bin/ssh/auth.c 2005/09/02 03:44:59 1.56.2.3 +++ src/usr.bin/ssh/auth.c 2005/01/22 08:17:59 1.57 @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.56.2.3 2005/09/02 03:44:59 brad Exp $"); +RCSID("$OpenBSD: auth.c,v 1.57 2005/01/22 08:17:59 dtucker Exp $"); #include @@ -64,7 +64,7 @@ struct stat st; const char *hostname = NULL, *ipaddr = NULL; char *shell; - u_int i; + int i; /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) @@ -89,8 +89,7 @@ return 0; } - if (options.num_deny_users > 0 || options.num_allow_users > 0 || - options.num_deny_groups > 0 || options.num_allow_groups > 0) { + if (options.num_deny_users > 0 || options.num_allow_users > 0) { hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } @@ -217,41 +216,64 @@ * * This returns a buffer allocated by xmalloc. */ -static char * -expand_authorized_keys(const char *filename, struct passwd *pw) +char * +expand_filename(const char *filename, struct passwd *pw) { - char *file, *ret; + Buffer buffer; + char *file; + const char *cp; - file = percent_expand(filename, "h", pw->pw_dir, - "u", pw->pw_name, (char *)NULL); + /* + * Build the filename string in the buffer by making the appropriate + * substitutions to the given file name. + */ + buffer_init(&buffer); + for (cp = filename; *cp; cp++) { + if (cp[0] == '%' && cp[1] == '%') { + buffer_append(&buffer, "%", 1); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'h') { + buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir)); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'u') { + buffer_append(&buffer, pw->pw_name, + strlen(pw->pw_name)); + cp++; + continue; + } + buffer_append(&buffer, cp, 1); + } + buffer_append(&buffer, "\0", 1); /* * Ensure that filename starts anchored. If not, be backward * compatible and prepend the '%h/' */ - if (*file == '/') - return (file); + file = xmalloc(MAXPATHLEN); + cp = buffer_ptr(&buffer); + if (*cp != '/') + snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp); + else + strlcpy(file, cp, MAXPATHLEN); - ret = xmalloc(MAXPATHLEN); - if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN || - strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN || - strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN) - fatal("expand_authorized_keys: path too long"); - - xfree(file); - return (ret); + buffer_free(&buffer); + return file; } char * authorized_keys_file(struct passwd *pw) { - return expand_authorized_keys(options.authorized_keys_file, pw); + return expand_filename(options.authorized_keys_file, pw); } char * authorized_keys_file2(struct passwd *pw) { - return expand_authorized_keys(options.authorized_keys_file2, pw); + return expand_filename(options.authorized_keys_file2, pw); } /* return ok if key exists in sysfile or userfile */