[openssh-commits] [openssh] 01/04: upstream: sftp-server(8): add a "users-groups-by-id at openssh.com"

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Sep 19 20:51:27 AEST 2022


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 74b77f7497dba3a58315c8f308883de448078057
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Mon Sep 19 10:40:52 2022 +0000

    upstream: sftp-server(8): add a "users-groups-by-id at 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
---
 PROTOCOL      | 43 ++++++++++++++++++++++++++++++++++++++++-
 sftp-server.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/PROTOCOL b/PROTOCOL
index 28ad9e0b..685f90fa 100644
--- a/PROTOCOL
+++ b/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 at 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 at 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 $
diff --git a/sftp-server.c b/sftp-server.c
index 8f30c181..65547029 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -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 at 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 at openssh.com", "1");
 	compose_extension(msg, "copy-data", "1");
 	compose_extension(msg, "home-directory", "1");
+	compose_extension(msg, "users-groups-by-id at 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)
 {

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list