=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sftp-server.c,v retrieving revision 1.142 retrieving revision 1.143 diff -u -r1.142 -r1.143 --- src/usr.bin/ssh/sftp-server.c 2022/09/16 06:55:37 1.142 +++ src/usr.bin/ssh/sftp-server.c 2022/09/19 10:40:52 1.143 @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.142 2022/09/16 06:55:37 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.143 2022/09/19 10:40:52 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -112,6 +113,7 @@ static void process_extended_expand(u_int32_t id); static void process_extended_copy_data(u_int32_t id); static void process_extended_home_directory(u_int32_t id); +static void process_extended_get_users_groups_by_id(u_int32_t id); static void process_extended(u_int32_t id); struct sftp_handler { @@ -160,6 +162,8 @@ { "copy-data", "copy-data", 0, process_extended_copy_data, 1 }, { "home-directory", "home-directory", 0, process_extended_home_directory, 0 }, + { "users-groups-by-id", "users-groups-by-id@openssh.com", 0, + process_extended_get_users_groups_by_id, 0 }, { NULL, NULL, 0, NULL, 0 } }; @@ -718,6 +722,7 @@ compose_extension(msg, "expand-path@openssh.com", "1"); compose_extension(msg, "copy-data", "1"); compose_extension(msg, "home-directory", "1"); + compose_extension(msg, "users-groups-by-id@openssh.com", "1"); send_msg(msg); sshbuf_free(msg); @@ -1678,6 +1683,61 @@ send_names(id, 1, &s); out: free(username); +} + +static void +process_extended_get_users_groups_by_id(u_int32_t id) +{ + struct passwd *user_pw; + struct group *gr; + struct sshbuf *uids, *gids, *usernames, *groupnames, *msg; + int r; + u_int n, nusers = 0, ngroups = 0; + const char *name; + + if ((usernames = sshbuf_new()) == NULL || + (groupnames = sshbuf_new()) == NULL || + (msg = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_froms(iqueue, &uids)) != 0 || + (r = sshbuf_froms(iqueue, &gids)) != 0) + fatal_fr(r, "parse"); + debug_f("uids len = %zu, gids len = %zu", + sshbuf_len(uids), sshbuf_len(gids)); + while (sshbuf_len(uids) != 0) { + if ((r = sshbuf_get_u32(uids, &n)) != 0) + fatal_fr(r, "parse inner uid"); + user_pw = getpwuid((uid_t)n); + name = user_pw == NULL ? "" : user_pw->pw_name; + debug3_f("uid %u => \"%s\"", n, name); + if ((r = sshbuf_put_cstring(usernames, name)) != 0) + fatal_fr(r, "assemble gid reply"); + nusers++; + } + while (sshbuf_len(gids) != 0) { + if ((r = sshbuf_get_u32(gids, &n)) != 0) + fatal_fr(r, "parse inner gid"); + gr = getgrgid((gid_t)n); + name = gr == NULL ? "" : gr->gr_name; + debug3_f("gid %u => \"%s\"", n, name); + if ((r = sshbuf_put_cstring(groupnames, name)) != 0) + fatal_fr(r, "assemble gid reply"); + nusers++; + } + verbose("users-groups-by-id: %u users, %u groups", nusers, ngroups); + + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_stringb(msg, usernames)) != 0 || + (r = sshbuf_put_stringb(msg, groupnames)) != 0) + fatal_fr(r, "compose"); + send_msg(msg); + + sshbuf_free(uids); + sshbuf_free(gids); + sshbuf_free(usernames); + sshbuf_free(groupnames); + sshbuf_free(msg); } static void