misc: Cache user home directory in session

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Pavol Žáčik <pzacik@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Jakub Jelen
2026-01-27 16:07:25 +01:00
parent a7cf4bb37b
commit 31ceec02fe
5 changed files with 30 additions and 6 deletions

View File

@@ -43,7 +43,7 @@ extern "C" {
/* in misc.c */ /* in misc.c */
/* gets the user home dir. */ /* gets the user home dir. */
char *ssh_get_user_home_dir(void); char *ssh_get_user_home_dir(ssh_session session);
char *ssh_get_local_username(void); char *ssh_get_local_username(void);
int ssh_file_readaccess_ok(const char *file); int ssh_file_readaccess_ok(const char *file);
int ssh_dir_writeable(const char *path); int ssh_dir_writeable(const char *path);

View File

@@ -253,6 +253,7 @@ struct ssh_session_struct {
char *username; char *username;
char *host; char *host;
char *bindaddr; /* bind the client to an ip addr */ char *bindaddr; /* bind the client to an ip addr */
char *homedir;
char *sshdir; char *sshdir;
char *knownhosts; char *knownhosts;
char *global_knownhosts; char *global_knownhosts;

View File

@@ -108,7 +108,7 @@
*/ */
#ifdef _WIN32 #ifdef _WIN32
char *ssh_get_user_home_dir(void) static char *ssh_get_user_home_dir_internal(void)
{ {
char tmp[PATH_MAX] = {0}; char tmp[PATH_MAX] = {0};
char *szPath = NULL; char *szPath = NULL;
@@ -298,7 +298,7 @@ int ssh_is_ipaddr(const char *str)
#define NSS_BUFLEN_PASSWD 4096 #define NSS_BUFLEN_PASSWD 4096
#endif /* NSS_BUFLEN_PASSWD */ #endif /* NSS_BUFLEN_PASSWD */
char *ssh_get_user_home_dir(void) static char *ssh_get_user_home_dir_internal(void)
{ {
char *szPath = NULL; char *szPath = NULL;
struct passwd pwd; struct passwd pwd;
@@ -313,7 +313,6 @@ char *ssh_get_user_home_dir(void)
return NULL; return NULL;
} }
snprintf(buf, sizeof(buf), "%s", szPath); snprintf(buf, sizeof(buf), "%s", szPath);
return strdup(buf); return strdup(buf);
} }
@@ -428,6 +427,29 @@ int ssh_is_ipaddr(const char *str)
#endif /* _WIN32 */ #endif /* _WIN32 */
char *ssh_get_user_home_dir(ssh_session session)
{
char *szPath = NULL;
/* If used previously, reuse cached value */
if (session != NULL && session->opts.homedir != NULL) {
return strdup(session->opts.homedir);
}
szPath = ssh_get_user_home_dir_internal();
if (szPath == NULL) {
return NULL;
}
if (session != NULL) {
/* cache it:
* failure is not fatal -- at worst we will just not cache it */
session->opts.homedir = strdup(szPath);
}
return szPath;
}
char *ssh_lowercase(const char* str) char *ssh_lowercase(const char* str)
{ {
char *new = NULL, *p = NULL; char *new = NULL, *p = NULL;
@@ -1189,7 +1211,7 @@ char *ssh_path_expand_tilde(const char *d)
} else { } else {
ld = strlen(d); ld = strlen(d);
p = (char *) d; p = (char *) d;
h = ssh_get_user_home_dir(); h = ssh_get_user_home_dir(NULL);
} }
if (h == NULL) { if (h == NULL) {
return NULL; return NULL;

View File

@@ -405,6 +405,7 @@ void ssh_free(ssh_session session)
SAFE_FREE(session->opts.bindaddr); SAFE_FREE(session->opts.bindaddr);
SAFE_FREE(session->opts.username); SAFE_FREE(session->opts.username);
SAFE_FREE(session->opts.host); SAFE_FREE(session->opts.host);
SAFE_FREE(session->opts.homedir);
SAFE_FREE(session->opts.sshdir); SAFE_FREE(session->opts.sshdir);
SAFE_FREE(session->opts.knownhosts); SAFE_FREE(session->opts.knownhosts);
SAFE_FREE(session->opts.global_knownhosts); SAFE_FREE(session->opts.global_knownhosts);

View File

@@ -52,7 +52,7 @@ static void torture_get_user_home_dir(void **state) {
(void) state; (void) state;
user = ssh_get_user_home_dir(); user = ssh_get_user_home_dir(NULL);
assert_non_null(user); assert_non_null(user);
#ifndef _WIN32 #ifndef _WIN32
assert_string_equal(user, pwd->pw_dir); assert_string_equal(user, pwd->pw_dir);