mirror of
git://anongit.mindrot.org/openssh.git
synced 2025-02-12 11:56:53 +00:00
upstream: sftp-server(8): add a "users-groups-by-id@openssh.com"
extension request that allows the client to obtain user/group names that correspond to a set of uids/gids. Will be used to make directory listings more useful and consistent in sftp(1). ok markus@ OpenBSD-Commit-ID: 7ebabde0bcb95ef949c4840fe89e697e30df47d3
This commit is contained in:
parent
231a346c0c
commit
74b77f7497
43
PROTOCOL
43
PROTOCOL
@ -635,6 +635,47 @@ This request is identical to the "home-directory" request documented in:
|
||||
|
||||
https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-extensions-00#section-5
|
||||
|
||||
4.12. sftp: Extension request "users-groups-by-id@openssh.com"
|
||||
|
||||
This request asks the server to returns user and/or group names that
|
||||
correspond to one or more IDs (e.g. as returned from a SSH_FXP_STAT
|
||||
request). This may be used by the client to provide usernames in
|
||||
directory listings.
|
||||
|
||||
byte SSH_FXP_EXTENDED
|
||||
uint32 id
|
||||
string "users-groups-by-id@openssh.com"
|
||||
string uids
|
||||
string gids
|
||||
|
||||
Where "uids" and "gids" consists of one or more integer user or group
|
||||
identifiers:
|
||||
|
||||
uint32 id-0
|
||||
...
|
||||
|
||||
The server will reply with a SSH_FXP_EXTENDED_REPLY:
|
||||
|
||||
byte SSH_FXP_EXTENDED_REPLY
|
||||
string usernames
|
||||
string groupnames
|
||||
|
||||
Where "username" and "groupnames" consists of names in identical request
|
||||
order to "uids" and "gids" respectively:
|
||||
|
||||
string name-0
|
||||
...
|
||||
|
||||
If a name cannot be identified for a given user or group ID, an empty
|
||||
string will be returned in its place.
|
||||
|
||||
It is acceptable for either "uids" or "gids" to be an empty set, in
|
||||
which case the respective "usernames" or "groupnames" list will also
|
||||
be empty.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
5. Miscellaneous changes
|
||||
|
||||
5.1 Public key format
|
||||
@ -671,4 +712,4 @@ master instance and later clients.
|
||||
OpenSSH extends the usual agent protocol. These changes are documented
|
||||
in the PROTOCOL.agent file.
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.46 2022/08/12 05:20:28 djm Exp $
|
||||
$OpenBSD: PROTOCOL,v 1.47 2022/09/19 10:40:52 djm Exp $
|
||||
|
@ -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.
|
||||
*
|
||||
@ -37,6 +37,7 @@
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -122,6 +123,7 @@ static void process_extended_limits(u_int32_t id);
|
||||
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 {
|
||||
@ -170,6 +172,8 @@ static const struct sftp_handler extended_handlers[] = {
|
||||
{ "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 }
|
||||
};
|
||||
|
||||
@ -728,6 +732,7 @@ process_init(void)
|
||||
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);
|
||||
@ -1713,6 +1718,61 @@ process_extended_home_directory(u_int32_t id)
|
||||
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
|
||||
process_extended(u_int32_t id)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user