[openssh-commits] [openssh] 03/04: upstream: sftp client library support for

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Sep 19 20:51:29 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 8ff680368b0bccf88ae85d4c99de69387fbad7a6
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Mon Sep 19 10:43:12 2022 +0000

    upstream: sftp client library support for
    
    users-groups-by-id at openssh.com; ok markus@
    
    OpenBSD-Commit-ID: ddb2f33a2da6349a9a89a8b5bcb9ca7c999394de
---
 sftp-client.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 sftp-client.h |  11 ++++-
 2 files changed, 140 insertions(+), 11 deletions(-)

diff --git a/sftp-client.c b/sftp-client.c
index 310d44e5..35be53d6 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.164 2022/05/15 23:47:21 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.165 2022/09/19 10:43:12 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm at openbsd.org>
  *
@@ -95,15 +95,16 @@ struct sftp_conn {
 	u_int num_requests;
 	u_int version;
 	u_int msg_id;
-#define SFTP_EXT_POSIX_RENAME	0x00000001
-#define SFTP_EXT_STATVFS	0x00000002
-#define SFTP_EXT_FSTATVFS	0x00000004
-#define SFTP_EXT_HARDLINK	0x00000008
-#define SFTP_EXT_FSYNC		0x00000010
-#define SFTP_EXT_LSETSTAT	0x00000020
-#define SFTP_EXT_LIMITS		0x00000040
-#define SFTP_EXT_PATH_EXPAND	0x00000080
-#define SFTP_EXT_COPY_DATA	0x00000100
+#define SFTP_EXT_POSIX_RENAME		0x00000001
+#define SFTP_EXT_STATVFS		0x00000002
+#define SFTP_EXT_FSTATVFS		0x00000004
+#define SFTP_EXT_HARDLINK		0x00000008
+#define SFTP_EXT_FSYNC			0x00000010
+#define SFTP_EXT_LSETSTAT		0x00000020
+#define SFTP_EXT_LIMITS			0x00000040
+#define SFTP_EXT_PATH_EXPAND		0x00000080
+#define SFTP_EXT_COPY_DATA		0x00000100
+#define SFTP_EXT_GETUSERSGROUPS_BY_ID	0x00000200
 	u_int exts;
 	u_int64_t limit_kbps;
 	struct bwlimit bwlimit_in, bwlimit_out;
@@ -539,6 +540,11 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
 		    strcmp((char *)value, "1") == 0) {
 			ret->exts |= SFTP_EXT_COPY_DATA;
 			known = 1;
+		} else if (strcmp(name,
+		    "users-groups-by-id at openssh.com") == 0 &&
+		    strcmp((char *)value, "1") == 0) {
+			ret->exts |= SFTP_EXT_GETUSERSGROUPS_BY_ID;
+			known = 1;
 		}
 		if (known) {
 			debug2("Server supports extension \"%s\" revision %s",
@@ -2752,6 +2758,120 @@ crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
 	return ret;
 }
 
+int
+can_get_users_groups_by_id(struct sftp_conn *conn)
+{
+	return (conn->exts & SFTP_EXT_GETUSERSGROUPS_BY_ID) != 0;
+}
+
+int
+do_get_users_groups_by_id(struct sftp_conn *conn,
+    const u_int *uids, u_int nuids,
+    const u_int *gids, u_int ngids,
+    char ***usernamesp, char ***groupnamesp)
+{
+	struct sshbuf *msg, *uidbuf, *gidbuf;
+	u_int i, expected_id, id;
+	char *name, **usernames = NULL, **groupnames = NULL;
+	u_char type;
+	int r;
+
+	*usernamesp = *groupnamesp = NULL;
+	if (!can_get_users_groups_by_id(conn))
+		return SSH_ERR_FEATURE_UNSUPPORTED;
+
+	if ((msg = sshbuf_new()) == NULL ||
+	    (uidbuf = sshbuf_new()) == NULL ||
+	    (gidbuf = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new failed");
+	expected_id = id = conn->msg_id++;
+	debug2("Sending SSH2_FXP_EXTENDED(users-groups-by-id at openssh.com)");
+	for (i = 0; i < nuids; i++) {
+		if ((r = sshbuf_put_u32(uidbuf, uids[i])) != 0)
+			fatal_fr(r, "compose uids");
+	}
+	for (i = 0; i < ngids; i++) {
+		if ((r = sshbuf_put_u32(gidbuf, gids[i])) != 0)
+			fatal_fr(r, "compose gids");
+	}
+	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
+	    (r = sshbuf_put_u32(msg, id)) != 0 ||
+	    (r = sshbuf_put_cstring(msg,
+	    "users-groups-by-id at openssh.com")) != 0 ||
+	    (r = sshbuf_put_stringb(msg, uidbuf)) != 0 ||
+	    (r = sshbuf_put_stringb(msg, gidbuf)) != 0)
+		fatal_fr(r, "compose");
+	send_msg(conn, msg);
+	get_msg(conn, msg);
+	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+	    (r = sshbuf_get_u32(msg, &id)) != 0)
+		fatal_fr(r, "parse");
+	if (id != expected_id)
+		fatal("ID mismatch (%u != %u)", id, expected_id);
+	if (type == SSH2_FXP_STATUS) {
+		u_int status;
+		char *errmsg;
+
+		if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
+		    (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
+			fatal_fr(r, "parse status");
+		error("users-groups-by-id %s",
+		    *errmsg == '\0' ? fx2txt(status) : errmsg);
+		free(errmsg);
+		sshbuf_free(msg);
+		sshbuf_free(uidbuf);
+		sshbuf_free(gidbuf);
+		return -1;
+	} else if (type != SSH2_FXP_EXTENDED_REPLY)
+		fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
+		    SSH2_FXP_EXTENDED_REPLY, type);
+
+	/* reuse */
+	sshbuf_free(uidbuf);
+	sshbuf_free(gidbuf);
+	uidbuf = gidbuf = NULL;
+	if ((r = sshbuf_froms(msg, &uidbuf)) != 0 ||
+	    (r = sshbuf_froms(msg, &gidbuf)) != 0)
+		fatal_fr(r, "parse response");
+	if (nuids > 0) {
+		usernames = xcalloc(nuids, sizeof(*usernames));
+		for (i = 0; i < nuids; i++) {
+			if ((r = sshbuf_get_cstring(uidbuf, &name, NULL)) != 0)
+				fatal_fr(r, "parse user name");
+			/* Handle unresolved names */
+			if (*name == '\0') {
+				free(name);
+				name = NULL;
+			}
+			usernames[i] = name;
+		}
+	}
+	if (ngids > 0) {
+		groupnames = xcalloc(ngids, sizeof(*groupnames));
+		for (i = 0; i < ngids; i++) {
+			if ((r = sshbuf_get_cstring(gidbuf, &name, NULL)) != 0)
+				fatal_fr(r, "parse user name");
+			/* Handle unresolved names */
+			if (*name == '\0') {
+				free(name);
+				name = NULL;
+			}
+			groupnames[i] = name;
+		}
+	}
+	if (sshbuf_len(uidbuf) != 0)
+		fatal_f("unexpected extra username data");
+	if (sshbuf_len(gidbuf) != 0)
+		fatal_f("unexpected extra groupname data");
+	sshbuf_free(uidbuf);
+	sshbuf_free(gidbuf);
+	sshbuf_free(msg);
+	/* success */
+	*usernamesp = usernames;
+	*groupnamesp = groupnames;
+	return 0;
+}
+
 char *
 path_append(const char *p1, const char *p2)
 {
diff --git a/sftp-client.h b/sftp-client.h
index 7ca6e8ad..d7deab17 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.h,v 1.37 2022/05/13 06:31:50 djm Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.38 2022/09/19 10:43:12 djm Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm at openbsd.org>
@@ -183,6 +183,15 @@ int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
     Attrib *dirattrib, int preserve_flag, int print_flag,
     int follow_link_flag);
 
+/*
+ * User/group ID to name translation.
+ */
+int can_get_users_groups_by_id(struct sftp_conn *conn);
+int do_get_users_groups_by_id(struct sftp_conn *conn,
+    const u_int *uids, u_int nuids,
+    const u_int *gids, u_int ngids,
+    char ***usernamesp, char ***groupnamesp);
+
 /* Concatenate paths, taking care of slashes. Caller must free result. */
 char *path_append(const char *, const char *);
 

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


More information about the openssh-commits mailing list