git: 299eb4333692 - stable/14 - id: revert to historical and documented behavior for `id`

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Thu, 30 Oct 2025 10:38:48 UTC
The branch stable/14 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=299eb433369202502ba7ceccb3fd2b3f6fdb1afe

commit 299eb433369202502ba7ceccb3fd2b3f6fdb1afe
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-08-04 23:09:58 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-10-30 10:38:19 +0000

    id: revert to historical and documented behavior for `id`
    
    The manpage claims that we display the credentials for the calling
    process if no user/flags are specified, but this has not been true since
    r145628 / 68b9b81e792a9108d.  Currently, we display:
    
     - uid from the calling process
     - gid from /etc/passwd
     - egid from the calling process, if different from that gid
     - supplementary groups from the calling process
    
    This doesn't really match the description in the manpage, and it doesn't
    match other implementations.  Fix it to use the current process
    credentials for the gid as well.
    
    Drop the extra arguments to id_print(), since these facts can be derived
    from whether we're displaying live data (`pw == NULL`) or not.
    
    Reviewed by:    olce
    Differential Revision:  https://reviews.freebsd.org/D51689
    
    (cherry picked from commit 90b315233a3362b7427e2d2649eaa8acf0da197a)
---
 usr.bin/id/id.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/usr.bin/id/id.c b/usr.bin/id/id.c
index 772558191306..2cc4a00e4d48 100644
--- a/usr.bin/id/id.c
+++ b/usr.bin/id/id.c
@@ -52,13 +52,14 @@ static char sccsid[] = "@(#)id.c	8.2 (Berkeley) 2/16/94";
 #include <errno.h>
 #include <grp.h>
 #include <pwd.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-static void	id_print(struct passwd *, int, int, int);
+static void	id_print(struct passwd *);
 static void	pline(struct passwd *);
 static void	pretty(struct passwd *);
 #ifdef USE_BSM_AUDIT
@@ -214,14 +215,7 @@ main(int argc, char *argv[])
 		exit(0);
 	}
 
-	if (pw) {
-		id_print(pw, 1, 0, 0);
-	}
-	else {
-		id = getuid();
-		pw = getpwuid(id);
-		id_print(pw, 0, 1, 1);
-	}
+	id_print(pw);
 	exit(0);
 }
 
@@ -266,7 +260,7 @@ pretty(struct passwd *pw)
 }
 
 static void
-id_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid)
+id_print(struct passwd *pw)
 {
 	struct group *gr;
 	gid_t gid, egid, lastgid;
@@ -275,21 +269,24 @@ id_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid)
 	long ngroups_max;
 	gid_t *groups;
 	const char *fmt;
+	bool print_dbinfo;
 
-	if (pw != NULL) {
+	print_dbinfo = pw != NULL;
+	if (print_dbinfo) {
 		uid = pw->pw_uid;
 		gid = pw->pw_gid;
 	}
 	else {
 		uid = getuid();
 		gid = getgid();
+		pw = getpwuid(uid);
 	}
 
 	ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
 	if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL)
 		err(1, "malloc");
 
-	if (use_ggl && pw != NULL) {
+	if (print_dbinfo) {
 		ngroups = ngroups_max;
 		getgrouplist(pw->pw_name, gid, groups, &ngroups);
 	}
@@ -297,19 +294,23 @@ id_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid)
 		ngroups = getgroups(ngroups_max, groups);
 	}
 
+	/*
+	 * We always resolve uids and gids where we can to a name, even if we
+	 * are printing the running process credentials, to be nice.
+	 */
 	if (pw != NULL)
 		printf("uid=%u(%s)", uid, pw->pw_name);
-	else 
-		printf("uid=%u", getuid());
+	else
+		printf("uid=%u", uid);
 	printf(" gid=%u", gid);
 	if ((gr = getgrgid(gid)))
 		(void)printf("(%s)", gr->gr_name);
-	if (p_euid && (euid = geteuid()) != uid) {
+	if (!print_dbinfo && (euid = geteuid()) != uid) {
 		(void)printf(" euid=%u", euid);
 		if ((pw = getpwuid(euid)))
 			(void)printf("(%s)", pw->pw_name);
 	}
-	if (p_egid && (egid = getegid()) != gid) {
+	if (!print_dbinfo && (egid = getegid()) != gid) {
 		(void)printf(" egid=%u", egid);
 		if ((gr = getgrgid(egid)))
 			(void)printf("(%s)", gr->gr_name);