coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

coreutils/src/id.c (162 lines, 4.1 KiB) -rw-r--r-- file download

32c7dc0 Jamozed 2020-07-06 22:43:09
0
// id.c, version 0.1.1
8b4f999 Jamozed 2020-06-27 14:00:03
1
// OMKOV coreutils implementation of POSIX id
8b4f999 Jamozed 2020-06-27 14:00:03
2
// Copyright (C) 2020, Jakob Wakeling
e2140ec Jamozed 2022-03-06 15:27:45
3
// MIT Licence
8b4f999 Jamozed 2020-06-27 14:00:03
4
8b4f999 Jamozed 2020-06-27 14:00:03
5
/*
8b4f999 Jamozed 2020-06-27 14:00:03
6
	TODO Fix memory leak when listing supplementary groups (may be unfixable)
8b4f999 Jamozed 2020-06-27 14:00:03
7
*/
8b4f999 Jamozed 2020-06-27 14:00:03
8
b181413 Jamozed 2022-02-05 22:32:00
9
#include "util/error.h"
b181413 Jamozed 2022-02-05 22:32:00
10
#include "util/optget.h"
8b4f999 Jamozed 2020-06-27 14:00:03
11
8b4f999 Jamozed 2020-06-27 14:00:03
12
#include <grp.h>
8b4f999 Jamozed 2020-06-27 14:00:03
13
#include <pwd.h>
8b4f999 Jamozed 2020-06-27 14:00:03
14
#include <sys/types.h>
8b4f999 Jamozed 2020-06-27 14:00:03
15
#include <unistd.h>
8b4f999 Jamozed 2020-06-27 14:00:03
16
8b4f999 Jamozed 2020-06-27 14:00:03
17
#include <stdbool.h>
30cf081 Jamozed 2020-08-28 23:01:02
18
#include <stdio.h>
8b4f999 Jamozed 2020-06-27 14:00:03
19
#include <stdlib.h>
30cf081 Jamozed 2020-08-28 23:01:02
20
#include <string.h>
32c7dc0 Jamozed 2020-07-06 22:43:09
21
32c7dc0 Jamozed 2020-07-06 22:43:09
22
#define VERSION "0.1.1"
8b4f999 Jamozed 2020-06-27 14:00:03
23
8b4f999 Jamozed 2020-06-27 14:00:03
24
typedef struct passwd pwd_t;
8b4f999 Jamozed 2020-06-27 14:00:03
25
typedef struct group  grp_t;
8b4f999 Jamozed 2020-06-27 14:00:03
26
30cf081 Jamozed 2020-08-28 23:01:02
27
static struct lop lops[] = {
30cf081 Jamozed 2020-08-28 23:01:02
28
	{ "help",    ARG_NUL, 256 },
30cf081 Jamozed 2020-08-28 23:01:02
29
	{ "version", ARG_NUL, 257 },
30cf081 Jamozed 2020-08-28 23:01:02
30
	{ NULL, 0, 0 }
30cf081 Jamozed 2020-08-28 23:01:02
31
};
30cf081 Jamozed 2020-08-28 23:01:02
32
8b4f999 Jamozed 2020-06-27 14:00:03
33
static char mode;
8b4f999 Jamozed 2020-06-27 14:00:03
34
static bool nflag;
8b4f999 Jamozed 2020-06-27 14:00:03
35
static bool rflag;
8b4f999 Jamozed 2020-06-27 14:00:03
36
8b4f999 Jamozed 2020-06-27 14:00:03
37
static inline void id(uid_t uid, uid_t euid, gid_t gid, gid_t egid);
8b4f999 Jamozed 2020-06-27 14:00:03
38
static inline void groups(const char *user, gid_t gid, gid_t egid);
8b4f999 Jamozed 2020-06-27 14:00:03
39
30cf081 Jamozed 2020-08-28 23:01:02
40
static void hlp(void);
30cf081 Jamozed 2020-08-28 23:01:02
41
static void ver(void);
8b4f999 Jamozed 2020-06-27 14:00:03
42
32c7dc0 Jamozed 2020-07-06 22:43:09
43
int main(int ac, char *av[]) { A0 = av[0];
30cf081 Jamozed 2020-08-28 23:01:02
44
	struct opt opt = OPTGET_INIT; opt.str = "Ggnru"; opt.lops = lops;
30cf081 Jamozed 2020-08-28 23:01:02
45
	for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) {
8b4f999 Jamozed 2020-06-27 14:00:03
46
	case 'G': case 'g': case 'u': {
32c7dc0 Jamozed 2020-07-06 22:43:09
47
		if (mode) { error(1, "invalid option combination"); }
4fd512b Jamozed 2020-06-28 00:02:14
48
		else { mode = (char)o; } break;
8b4f999 Jamozed 2020-06-27 14:00:03
49
	}
8b4f999 Jamozed 2020-06-27 14:00:03
50
	case 'n': { nflag = true; break; }
8b4f999 Jamozed 2020-06-27 14:00:03
51
	case 'r': { rflag = true; break; }
30cf081 Jamozed 2020-08-28 23:01:02
52
	case 256: { hlp(); return 0; }
30cf081 Jamozed 2020-08-28 23:01:02
53
	case 257: { ver(); return 0; }
8b4f999 Jamozed 2020-06-27 14:00:03
54
	default: { return 1; }
8b4f999 Jamozed 2020-06-27 14:00:03
55
	}
8b4f999 Jamozed 2020-06-27 14:00:03
56
	
8b4f999 Jamozed 2020-06-27 14:00:03
57
	if (!mode && (nflag || rflag)) {
32c7dc0 Jamozed 2020-07-06 22:43:09
58
		error(1, "options 'n' and 'r' require 'G', 'g', or 'u'");
8b4f999 Jamozed 2020-06-27 14:00:03
59
	}
8b4f999 Jamozed 2020-06-27 14:00:03
60
	
8b4f999 Jamozed 2020-06-27 14:00:03
61
	uid_t uid, euid; gid_t gid, egid;
8b4f999 Jamozed 2020-06-27 14:00:03
62
	
32c7dc0 Jamozed 2020-07-06 22:43:09
63
	if (opt.ind == ac) {
8b4f999 Jamozed 2020-06-27 14:00:03
64
		uid = getuid(); euid = geteuid();
8b4f999 Jamozed 2020-06-27 14:00:03
65
		gid = getgid(); egid = getegid();
8b4f999 Jamozed 2020-06-27 14:00:03
66
		id (uid, euid, gid, egid);
8b4f999 Jamozed 2020-06-27 14:00:03
67
	}
32c7dc0 Jamozed 2020-07-06 22:43:09
68
	else for (char **p = &av[opt.ind]; *p; ++p) {
8b4f999 Jamozed 2020-06-27 14:00:03
69
		pwd_t *pwd;
8b4f999 Jamozed 2020-06-27 14:00:03
70
		
32c7dc0 Jamozed 2020-07-06 22:43:09
71
		if (!(pwd = getpwnam(*p))) { error(1, "%s: invalid user", *p); }
8b4f999 Jamozed 2020-06-27 14:00:03
72
		
8b4f999 Jamozed 2020-06-27 14:00:03
73
		uid = euid = pwd->pw_uid;
8b4f999 Jamozed 2020-06-27 14:00:03
74
		gid = egid = pwd->pw_gid;
8b4f999 Jamozed 2020-06-27 14:00:03
75
		id (uid, euid, gid, egid);
8b4f999 Jamozed 2020-06-27 14:00:03
76
	}
8b4f999 Jamozed 2020-06-27 14:00:03
77
	
8b4f999 Jamozed 2020-06-27 14:00:03
78
	return 0;
8b4f999 Jamozed 2020-06-27 14:00:03
79
}
8b4f999 Jamozed 2020-06-27 14:00:03
80
8b4f999 Jamozed 2020-06-27 14:00:03
81
static inline void id(uid_t uid, uid_t euid, gid_t gid, gid_t egid) {
8b4f999 Jamozed 2020-06-27 14:00:03
82
	pwd_t *pwd; grp_t *grp;
8b4f999 Jamozed 2020-06-27 14:00:03
83
	
8b4f999 Jamozed 2020-06-27 14:00:03
84
	if (mode == 'G') {
8b4f999 Jamozed 2020-06-27 14:00:03
85
		pwd = getpwuid(uid);
8b4f999 Jamozed 2020-06-27 14:00:03
86
		groups(pwd->pw_name, gid, egid);
8b4f999 Jamozed 2020-06-27 14:00:03
87
	}
8b4f999 Jamozed 2020-06-27 14:00:03
88
	else if (mode == 'g') {
8b4f999 Jamozed 2020-06-27 14:00:03
89
		grp = getgrgid(rflag ? gid : egid);
8b4f999 Jamozed 2020-06-27 14:00:03
90
		nflag ? fputs(grp->gr_name, stdout) : printf("%u", grp->gr_gid);
8b4f999 Jamozed 2020-06-27 14:00:03
91
	}
8b4f999 Jamozed 2020-06-27 14:00:03
92
	else if (mode == 'u') {
8b4f999 Jamozed 2020-06-27 14:00:03
93
		pwd = getpwuid(rflag ? uid : euid);
8b4f999 Jamozed 2020-06-27 14:00:03
94
		nflag ? fputs(pwd->pw_name, stdout) : printf("%u", pwd->pw_uid);
8b4f999 Jamozed 2020-06-27 14:00:03
95
	}
8b4f999 Jamozed 2020-06-27 14:00:03
96
	else {
8b4f999 Jamozed 2020-06-27 14:00:03
97
		pwd = getpwuid(uid); grp = getgrgid(gid);
8b4f999 Jamozed 2020-06-27 14:00:03
98
		printf("uid=%u(%s) gid=%u(%s) ", uid, pwd->pw_name, gid, grp->gr_name);
8b4f999 Jamozed 2020-06-27 14:00:03
99
		if (uid != euid) {
8b4f999 Jamozed 2020-06-27 14:00:03
100
			pwd = getpwuid(euid);
8b4f999 Jamozed 2020-06-27 14:00:03
101
			printf("euid=%u(%s) ", euid, pwd->pw_name);
8b4f999 Jamozed 2020-06-27 14:00:03
102
			pwd = getpwuid(uid);
8b4f999 Jamozed 2020-06-27 14:00:03
103
		}
8b4f999 Jamozed 2020-06-27 14:00:03
104
		if (gid != egid) {
8b4f999 Jamozed 2020-06-27 14:00:03
105
			grp = getgrgid(egid);
8b4f999 Jamozed 2020-06-27 14:00:03
106
			printf("egid=%u(%s) ", egid, grp->gr_name);
8b4f999 Jamozed 2020-06-27 14:00:03
107
		}
8b4f999 Jamozed 2020-06-27 14:00:03
108
		fputs("groups=", stdout);
8b4f999 Jamozed 2020-06-27 14:00:03
109
		groups(pwd->pw_name, gid, egid);
8b4f999 Jamozed 2020-06-27 14:00:03
110
	}
8b4f999 Jamozed 2020-06-27 14:00:03
111
	fputc('\n', stdout);
8b4f999 Jamozed 2020-06-27 14:00:03
112
	
8b4f999 Jamozed 2020-06-27 14:00:03
113
	return;
8b4f999 Jamozed 2020-06-27 14:00:03
114
}
8b4f999 Jamozed 2020-06-27 14:00:03
115
8b4f999 Jamozed 2020-06-27 14:00:03
116
static inline void groups(const char *user, gid_t gid, gid_t egid) {
8b4f999 Jamozed 2020-06-27 14:00:03
117
	grp_t *grp = getgrgid(gid);
8b4f999 Jamozed 2020-06-27 14:00:03
118
	if (mode) { nflag ? fputs(grp->gr_name, stdout) : printf("%u", gid); }
8b4f999 Jamozed 2020-06-27 14:00:03
119
	else { printf("%u(%s)", gid, grp->gr_name); }
8b4f999 Jamozed 2020-06-27 14:00:03
120
	
8b4f999 Jamozed 2020-06-27 14:00:03
121
	if (gid != egid) {
8b4f999 Jamozed 2020-06-27 14:00:03
122
		grp = getgrgid(egid);
8b4f999 Jamozed 2020-06-27 14:00:03
123
		if (mode) { nflag ? printf(" %s", grp->gr_name) : printf(" %u", egid); }
8b4f999 Jamozed 2020-06-27 14:00:03
124
		else { printf(",%u(%s)", egid, grp->gr_name); }
8b4f999 Jamozed 2020-06-27 14:00:03
125
	}
8b4f999 Jamozed 2020-06-27 14:00:03
126
	
8b4f999 Jamozed 2020-06-27 14:00:03
127
	setgrent();
8b4f999 Jamozed 2020-06-27 14:00:03
128
	while ((grp = getgrent()) != NULL) {
8b4f999 Jamozed 2020-06-27 14:00:03
129
		if (grp->gr_gid == gid || grp->gr_gid == egid) { continue; }
8b4f999 Jamozed 2020-06-27 14:00:03
130
		for (int i = 0; grp->gr_mem[i]; ++i) {
8b4f999 Jamozed 2020-06-27 14:00:03
131
			if (strcmp(grp->gr_mem[i], user) == 0) {
8b4f999 Jamozed 2020-06-27 14:00:03
132
				if (mode) { nflag ? printf(" %s", grp->gr_name) :
8b4f999 Jamozed 2020-06-27 14:00:03
133
					printf(" %u", grp->gr_gid); }
8b4f999 Jamozed 2020-06-27 14:00:03
134
				else { printf(",%u(%s)", grp->gr_gid, grp->gr_name); }
8b4f999 Jamozed 2020-06-27 14:00:03
135
			}
8b4f999 Jamozed 2020-06-27 14:00:03
136
		}
8b4f999 Jamozed 2020-06-27 14:00:03
137
	}
8b4f999 Jamozed 2020-06-27 14:00:03
138
	endgrent();
8b4f999 Jamozed 2020-06-27 14:00:03
139
	
8b4f999 Jamozed 2020-06-27 14:00:03
140
	return;
8b4f999 Jamozed 2020-06-27 14:00:03
141
}
8b4f999 Jamozed 2020-06-27 14:00:03
142
30cf081 Jamozed 2020-08-28 23:01:02
143
static void hlp(void) {
8b4f999 Jamozed 2020-06-27 14:00:03
144
	puts("id - return user identity\n");
8b4f999 Jamozed 2020-06-27 14:00:03
145
	puts("usage: id [-G|-g|-u] [-nr] [user...]\n");
8b4f999 Jamozed 2020-06-27 14:00:03
146
	puts("options:");
8b4f999 Jamozed 2020-06-27 14:00:03
147
	puts("  -G         Output all group IDs");
8b4f999 Jamozed 2020-06-27 14:00:03
148
	puts("  -g         Output only the effective group ID");
8b4f999 Jamozed 2020-06-27 14:00:03
149
	puts("  -n         Output names of groups and users instead of their IDs");
8b4f999 Jamozed 2020-06-27 14:00:03
150
	puts("  -r         Output the real ID instead of the effective ID");
8b4f999 Jamozed 2020-06-27 14:00:03
151
	puts("  -u         Output only the effective user ID");
8b4f999 Jamozed 2020-06-27 14:00:03
152
	puts("  --help     Display help information");
8b4f999 Jamozed 2020-06-27 14:00:03
153
	puts("  --version  Display version information");
8b4f999 Jamozed 2020-06-27 14:00:03
154
}
8b4f999 Jamozed 2020-06-27 14:00:03
155
30cf081 Jamozed 2020-08-28 23:01:02
156
static void ver(void) {
32c7dc0 Jamozed 2020-07-06 22:43:09
157
	puts("OMKOV coreutils id, version " VERSION);
8b4f999 Jamozed 2020-06-27 14:00:03
158
	puts("Copyright (C) 2020, Jakob Wakeling");
e2140ec Jamozed 2022-03-06 15:27:45
159
	puts("MIT Licence (https://opensource.org/licenses/MIT)");
8b4f999 Jamozed 2020-06-27 14:00:03
160
}
161