comparison toys/id.c @ 543:60b97ba66a70

Extensive semi-gratuitous refactoring: factor out common code, handle euid!=uid and egid!=gid cases. (Note: test suite requires root access, possibly container support.)
author Rob Landley <rob@landley.net>
date Mon, 12 Mar 2012 23:00:28 -0500
parents 06763d1a2f9d
children
comparison
equal deleted inserted replaced
542:06763d1a2f9d 543:60b97ba66a70
31 #define FLAG_G (1<<3) 31 #define FLAG_G (1<<3)
32 #define FLAG_g (1<<2) 32 #define FLAG_g (1<<2)
33 #define FLAG_r (1<<1) 33 #define FLAG_r (1<<1)
34 #define FLAG_u 1 34 #define FLAG_u 1
35 35
36 void pretty_print(struct passwd *pw, struct group *grp, struct group **grps, 36 static void s_or_u(char *s, unsigned u, int done)
37 int n)
38 { 37 {
39 int i = 0; 38 if (toys.optflags & FLAG_n) printf("%s", s);
39 else printf("%u", u);
40 if (done) {
41 xputc('\n');
42 exit(0);
43 }
44 }
40 45
41 printf("uid=%u(%s) gid=%u(%s)", pw->pw_uid, pw->pw_name, 46 static void showid(char *header, unsigned u, char *s)
42 grp->gr_gid, grp->gr_name); 47 {
43 if (n) printf(" groups="); 48 printf("%s%u(%s)", header, u, s);
44 while (i < n) { 49 }
45 printf("%d(%s)", grps[i]->gr_gid, grps[i]->gr_name); 50
46 if (++i<n) xputc(','); 51 struct passwd *xgetpwuid(uid_t uid)
47 } 52 {
48 xputc('\n'); 53 struct passwd *pwd = getpwuid(uid);
54 if (!pwd) error_exit(NULL);
55 return pwd;
56 }
57
58 struct group *xgetgrgid(gid_t gid)
59 {
60 struct group *group = getgrgid(gid);
61 if (!group) error_exit(NULL);
62 return group;
49 } 63 }
50 64
51 void id_main(void) 65 void id_main(void)
52 { 66 {
53 int flags = toys.optflags, i, ngroups; 67 int flags = toys.optflags, i, ngroups;
54 struct passwd *pw; 68 struct passwd *pw;
55 struct group *grp, **grps; 69 struct group *grp;
56 uid_t uid; 70 uid_t uid = getuid(), euid = geteuid();
57 gid_t gid, *groups; 71 gid_t gid = getgid(), egid = getegid(), *groups;
58 72
59 /* check if a username is given */ 73 /* check if a username is given */
60 if (*toys.optargs) { 74 if (*toys.optargs) {
61 if (!(pw = getpwnam(*toys.optargs))) 75 if (!(pw = getpwnam(*toys.optargs)))
62 error_exit("no such user '%s'", *toys.optargs); 76 error_exit("no such user '%s'", *toys.optargs);
63 uid = pw->pw_uid; 77 uid = euid = pw->pw_uid;
64 gid = pw->pw_gid; 78 gid = egid = pw->pw_gid;
65 } else {
66 /* show effective, unless user specifies real */
67 if (flags & FLAG_r) {
68 uid = getuid();
69 gid = getgid();
70 } else {
71 uid = geteuid();
72 gid = getegid();
73 }
74 } 79 }
75 80
76 if (!(pw = getpwuid(uid)) || !(grp = getgrgid(gid))) 81 i = toys.optflags & FLAG_r;
77 perror_exit(0); 82 pw = xgetpwuid(i ? uid : euid);
78 83 if (flags & FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
79 if (flags & FLAG_u) { 84
80 if (flags & FLAG_n) xputs(pw->pw_name); 85 grp = xgetgrgid(i ? gid : egid);
81 else printf("%d\n", pw->pw_uid); 86 if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
82 return; 87
88 if (!(flags & FLAG_G)) {
89 showid("uid=", pw->pw_uid, pw->pw_name);
90 showid(" gid=", grp->gr_gid, grp->gr_name);
91
92 if (!i) {
93 if (uid != euid) {
94 pw = xgetpwuid(euid);
95 showid(" euid=", pw->pw_uid, pw->pw_name);
96 }
97 if (gid != egid) {
98 grp = xgetgrgid(egid);
99 showid(" egid=", grp->gr_gid, grp->gr_name);
100 }
101 }
102
103 showid(" groups=", grp->gr_gid, grp->gr_name);
83 } 104 }
84 if (flags & FLAG_g) { 105
85 if (flags & FLAG_n) xputs(grp->gr_name); 106
86 else printf("%d\n", grp->gr_gid); 107 groups = (gid_t *)toybuf;
87 return; 108 if (0 >= (ngroups = getgroups(sizeof(toybuf)/sizeof(gid_t), groups)))
88 }
89
90 ngroups = sysconf(_SC_NGROUPS_MAX);
91 if (ngroups<1) ngroups = 32;
92 groups = xmalloc(ngroups * sizeof(gid_t));
93 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) < 0)
94 perror_exit(0); 109 perror_exit(0);
95 110
96 grps = xmalloc(ngroups * sizeof(struct group *));
97 for (i = 0; i < ngroups; i++) { 111 for (i = 0; i < ngroups; i++) {
98 struct group *tmp; 112 xputc(' ');
99 grps[i] = xmalloc(sizeof(struct group)); 113 if (!(grp = getgrgid(groups[i]))) perror_msg(0);
100 size_t f = sysconf(_SC_GETGR_R_SIZE_MAX); 114 else if (flags & FLAG_G)
101 char *buf = xmalloc(f); 115 s_or_u(grp->gr_name, grp->gr_gid, 0);
102 if (getgrgid_r(groups[i], grps[i], buf, f, &tmp) < 0 || !tmp) { 116 else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
103 perror_msg(0);
104 continue;
105 }
106 } 117 }
107 118 xputc('\n');
108 if (flags & FLAG_G) {
109 for (i = 0; i < ngroups; i++) {
110 if (i) xputc(' ');
111 if (flags & FLAG_n) printf("%s", grps[i]->gr_name);
112 else printf("%d", grps[i]->gr_gid);
113 }
114 printf("\n");
115 return;
116 }
117
118 pretty_print(pw, grp, grps, ngroups);
119 for (i=0; i < ngroups; i++)
120 free(grps[i]);
121
122 } 119 }