4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <stdio_ext.h>
36 #include <sys/types.h>
41 extern int _getgroupsbymember(const char *, gid_t
[], int, int);
43 static int look(char *);
44 static int perr(char *);
46 static void usage(void);
47 static void initcred(void);
50 static char *procname
;
57 static boolean_t all
= B_FALSE
;
58 static boolean_t doset
= B_FALSE
;
61 static long ngroups_max
;
63 static uid_t uid
= (uid_t
)-1;
64 static gid_t gid
= (gid_t
)-1;
67 main(int argc
, char **argv
)
73 if ((command
= strrchr(argv
[0], '/')) != NULL
)
78 if ((ngroups_max
= sysconf(_SC_NGROUPS_MAX
)) < 0)
79 return (perr("sysconf(_SC_NGROUPS_MAX)"));
83 while ((c
= getopt(argc
, argv
, "au:g:l:G:")) != EOF
) {
109 if (login
!= NULL
&& (user
!= NULL
|| group
!= NULL
|| grplst
!= NULL
))
125 * Make sure we'll have enough file descriptors to handle a target
126 * that has many many mappings.
128 if (getrlimit(RLIMIT_NOFILE
, &rlim
) == 0) {
129 rlim
.rlim_cur
= rlim
.rlim_max
;
130 (void) setrlimit(RLIMIT_NOFILE
, &rlim
);
131 (void) enable_extended_FILE_stdio(-1, -1);
137 return (rc
> 255 ? 255 : rc
);
141 credupdate(prcred_t
*pcr
)
143 if (uid
!= (uid_t
)-1)
144 pcr
->pr_euid
= pcr
->pr_ruid
= pcr
->pr_suid
= uid
;
145 if (gid
!= (gid_t
)-1)
146 pcr
->pr_egid
= pcr
->pr_rgid
= pcr
->pr_sgid
= gid
;
149 pcr
->pr_ngroups
= ngrp
;
151 (void) memcpy(pcr
->pr_groups
, groups
, ngrp
* sizeof (gid_t
));
158 struct ps_prochandle
*Pr
;
159 static prcred_t
*prcred
= NULL
;
162 procname
= arg
; /* for perr() */
164 if (prcred
== NULL
) {
165 prcred
= malloc(sizeof (prcred_t
) +
166 (ngroups_max
- 1) * sizeof (gid_t
));
167 if (prcred
== NULL
) {
168 (void) perr("malloc");
173 if ((Pr
= proc_arg_grab(arg
, doset
? PR_ARG_PIDS
: PR_ARG_ANY
,
174 PGRAB_RETAIN
| PGRAB_FORCE
| (doset
? 0 : PGRAB_RDONLY
) |
175 PGRAB_NOSTOP
, &gcode
)) == NULL
) {
176 (void) fprintf(stderr
, "%s: cannot examine %s: %s\n",
177 command
, arg
, Pgrab_error(gcode
));
181 if (Pcred(Pr
, prcred
, ngroups_max
) == -1) {
182 (void) perr("getcred");
189 if (Psetcred(Pr
, prcred
) != 0) {
190 (void) perr("setcred");
198 if (Pstate(Pr
) == PS_DEAD
)
199 (void) printf("core of %d:\t", (int)Pstatus(Pr
)->pr_pid
);
201 (void) printf("%d:\t", (int)Pstatus(Pr
)->pr_pid
);
204 prcred
->pr_euid
== prcred
->pr_ruid
&&
205 prcred
->pr_ruid
== prcred
->pr_suid
)
206 (void) printf("e/r/suid=%u ", prcred
->pr_euid
);
208 (void) printf("euid=%u ruid=%u suid=%u ",
209 prcred
->pr_euid
, prcred
->pr_ruid
, prcred
->pr_suid
);
212 prcred
->pr_egid
== prcred
->pr_rgid
&&
213 prcred
->pr_rgid
== prcred
->pr_sgid
)
214 (void) printf("e/r/sgid=%u\n", prcred
->pr_egid
);
216 (void) printf("egid=%u rgid=%u sgid=%u\n",
217 prcred
->pr_egid
, prcred
->pr_rgid
, prcred
->pr_sgid
);
219 if (prcred
->pr_ngroups
!= 0 &&
220 (all
|| prcred
->pr_ngroups
!= 1 ||
221 prcred
->pr_groups
[0] != prcred
->pr_rgid
)) {
224 (void) printf("\tgroups:");
225 for (i
= 0; i
< prcred
->pr_ngroups
; i
++)
226 (void) printf(" %u", prcred
->pr_groups
[i
]);
238 (void) fprintf(stderr
, "%s: ", procname
);
248 (void) fprintf(stderr
, "usage:\t%s [-a] { pid | core } ...\n"
249 "\t%s [-u user] [-g group] [-G groups] pid ...\n"
250 "\t%s -l login pid ...\n"
251 " (report or modify process credentials)\n",
252 command
, command
, command
);
258 str2id(const char *str
)
264 res
= strtoul(str
, &p
, 0);
265 if (p
== str
|| *p
!= '\0' || errno
!= 0)
266 return ((uint32_t)-1);
268 return ((uint32_t)res
);
272 str2gid(const char *grnam
)
274 struct group
*grp
= getgrnam(grnam
);
278 res
= (gid_t
)str2id(grnam
);
279 if (res
== (gid_t
)-1) {
280 (void) fprintf(stderr
, "%s: %s: unknown group"
296 if ((groups
= malloc(ngroups_max
* sizeof (gid_t
))) == NULL
) {
297 (void) perr("malloc");
302 pwd
= getpwnam(login
);
305 (void) fprintf(stderr
, "%s: %s: unknown user\n",
314 ngrp
= _getgroupsbymember(login
, groups
, (int)ngroups_max
, 1);
318 pwd
= getpwnam(user
);
320 uid
= (uid_t
)str2id(user
);
321 if (uid
== (uid_t
)-1) {
322 (void) fprintf(stderr
, "%s: %s: unknown user"
333 gid
= str2gid(group
);
335 if (grplst
!= NULL
) {
340 while ((cgrp
= strtok(grplst
, ",")) != NULL
) {
342 if (ngrp
>= ngroups_max
) {
343 (void) fprintf(stderr
, "%s: Too many groups\n",
347 groups
[ngrp
++] = str2gid(cgrp
);
349 /* For iterations of strtok */