1*f875b4ebSrica /*
2*f875b4ebSrica * CDDL HEADER START
3*f875b4ebSrica *
4*f875b4ebSrica * The contents of this file are subject to the terms of the
5*f875b4ebSrica * Common Development and Distribution License (the "License").
6*f875b4ebSrica * You may not use this file except in compliance with the License.
7*f875b4ebSrica *
8*f875b4ebSrica * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*f875b4ebSrica * or http://www.opensolaris.org/os/licensing.
10*f875b4ebSrica * See the License for the specific language governing permissions
11*f875b4ebSrica * and limitations under the License.
12*f875b4ebSrica *
13*f875b4ebSrica * When distributing Covered Code, include this CDDL HEADER in each
14*f875b4ebSrica * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*f875b4ebSrica * If applicable, add the following below this CDDL HEADER, with the
16*f875b4ebSrica * fields enclosed by brackets "[]" replaced with your own identifying
17*f875b4ebSrica * information: Portions Copyright [yyyy] [name of copyright owner]
18*f875b4ebSrica *
19*f875b4ebSrica * CDDL HEADER END
20*f875b4ebSrica */
21*f875b4ebSrica
22*f875b4ebSrica /*
23*f875b4ebSrica * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24*f875b4ebSrica * Use is subject to license terms.
25*f875b4ebSrica */
26*f875b4ebSrica
27*f875b4ebSrica #pragma ident "%Z%%M% %I% %E% SMI"
28*f875b4ebSrica
29*f875b4ebSrica /*
30*f875b4ebSrica * plabel - gets process label.
31*f875b4ebSrica */
32*f875b4ebSrica #include <stdio.h>
33*f875b4ebSrica #include <stdlib.h>
34*f875b4ebSrica #include <errno.h>
35*f875b4ebSrica #include <unistd.h>
36*f875b4ebSrica #include <fcntl.h>
37*f875b4ebSrica #include <string.h>
38*f875b4ebSrica #include <locale.h>
39*f875b4ebSrica #include <procfs.h>
40*f875b4ebSrica #include <sys/proc.h>
41*f875b4ebSrica #include <zone.h>
42*f875b4ebSrica
43*f875b4ebSrica #include <sys/tsol/label_macro.h>
44*f875b4ebSrica
45*f875b4ebSrica #include <tsol/label.h>
46*f875b4ebSrica
47*f875b4ebSrica #define s_flag 0x04
48*f875b4ebSrica #define S_flag 0x08
49*f875b4ebSrica
50*f875b4ebSrica #define INIT_ALLOC_LEN 1024
51*f875b4ebSrica #define MAX_ALLOC_NUM 11
52*f875b4ebSrica
53*f875b4ebSrica static int look(char *);
54*f875b4ebSrica static int perr(char *);
55*f875b4ebSrica static void usage(void);
56*f875b4ebSrica
57*f875b4ebSrica static char procname[64];
58*f875b4ebSrica
59*f875b4ebSrica static unsigned int opt_flag = 0;
60*f875b4ebSrica static char *cmd = NULL;
61*f875b4ebSrica
62*f875b4ebSrica int
main(int argc,char ** argv)63*f875b4ebSrica main(int argc, char **argv)
64*f875b4ebSrica {
65*f875b4ebSrica int err, rc = 0;
66*f875b4ebSrica int opt;
67*f875b4ebSrica
68*f875b4ebSrica (void) setlocale(LC_ALL, "");
69*f875b4ebSrica #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
70*f875b4ebSrica #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
71*f875b4ebSrica #endif
72*f875b4ebSrica (void) textdomain(TEXT_DOMAIN);
73*f875b4ebSrica
74*f875b4ebSrica if ((cmd = strrchr(argv[0], '/')) == NULL)
75*f875b4ebSrica cmd = argv[0];
76*f875b4ebSrica else
77*f875b4ebSrica cmd++;
78*f875b4ebSrica
79*f875b4ebSrica /* Error if labeling is not active. */
80*f875b4ebSrica if (!is_system_labeled()) {
81*f875b4ebSrica (void) fprintf(stderr,
82*f875b4ebSrica gettext("%s: Trusted Extensions must be enabled\n"), cmd);
83*f875b4ebSrica return (1);
84*f875b4ebSrica }
85*f875b4ebSrica
86*f875b4ebSrica while ((opt = getopt(argc, argv, "sS")) != EOF) {
87*f875b4ebSrica switch (opt) {
88*f875b4ebSrica case 's':
89*f875b4ebSrica if (opt_flag & (s_flag | S_flag)) {
90*f875b4ebSrica usage();
91*f875b4ebSrica return (1);
92*f875b4ebSrica }
93*f875b4ebSrica opt_flag |= s_flag;
94*f875b4ebSrica break;
95*f875b4ebSrica
96*f875b4ebSrica case 'S':
97*f875b4ebSrica if (opt_flag & (s_flag | S_flag)) {
98*f875b4ebSrica usage();
99*f875b4ebSrica return (1);
100*f875b4ebSrica }
101*f875b4ebSrica opt_flag |= S_flag;
102*f875b4ebSrica break;
103*f875b4ebSrica default:
104*f875b4ebSrica usage();
105*f875b4ebSrica return (1);
106*f875b4ebSrica }
107*f875b4ebSrica }
108*f875b4ebSrica
109*f875b4ebSrica argc -= optind;
110*f875b4ebSrica argv += optind;
111*f875b4ebSrica if (argc == 0) {
112*f875b4ebSrica char pid[11]; /* 32 bit pids go to 4294967295 plus a NUL */
113*f875b4ebSrica
114*f875b4ebSrica (void) sprintf(pid, "%d", (int)getpid());
115*f875b4ebSrica rc = look(pid);
116*f875b4ebSrica } else {
117*f875b4ebSrica while (argc-- > 0) {
118*f875b4ebSrica err = look(*argv++);
119*f875b4ebSrica if (rc == 0)
120*f875b4ebSrica rc = err;
121*f875b4ebSrica }
122*f875b4ebSrica }
123*f875b4ebSrica return (rc);
124*f875b4ebSrica }
125*f875b4ebSrica
126*f875b4ebSrica static int
look(char * arg)127*f875b4ebSrica look(char *arg)
128*f875b4ebSrica {
129*f875b4ebSrica int fd;
130*f875b4ebSrica m_label_t *plabel;
131*f875b4ebSrica psinfo_t info; /* process information from /proc */
132*f875b4ebSrica char *str;
133*f875b4ebSrica int wordlen = DEF_NAMES;
134*f875b4ebSrica
135*f875b4ebSrica if (opt_flag == S_flag)
136*f875b4ebSrica wordlen = LONG_NAMES;
137*f875b4ebSrica else if (opt_flag == s_flag)
138*f875b4ebSrica wordlen = SHORT_NAMES;
139*f875b4ebSrica
140*f875b4ebSrica if (strchr(arg, '/') != NULL)
141*f875b4ebSrica (void) strncpy(procname, arg, sizeof (procname));
142*f875b4ebSrica else {
143*f875b4ebSrica (void) strcpy(procname, "/proc/");
144*f875b4ebSrica (void) strncat(procname, arg,
145*f875b4ebSrica sizeof (procname) - strlen(procname));
146*f875b4ebSrica }
147*f875b4ebSrica (void) strlcat(procname, "/psinfo", sizeof (procname)
148*f875b4ebSrica - strlen(procname));
149*f875b4ebSrica
150*f875b4ebSrica /*
151*f875b4ebSrica * Open the process to be examined.
152*f875b4ebSrica */
153*f875b4ebSrica retry:
154*f875b4ebSrica if ((fd = open(procname, O_RDONLY)) < 0) {
155*f875b4ebSrica /*
156*f875b4ebSrica * Make clean message for non-existent process.
157*f875b4ebSrica */
158*f875b4ebSrica if (errno == ENOENT) {
159*f875b4ebSrica errno = ESRCH;
160*f875b4ebSrica perror(arg);
161*f875b4ebSrica return (1);
162*f875b4ebSrica }
163*f875b4ebSrica return (perr(NULL));
164*f875b4ebSrica }
165*f875b4ebSrica
166*f875b4ebSrica
167*f875b4ebSrica /*
168*f875b4ebSrica * Get the info structure for the process and close quickly.
169*f875b4ebSrica */
170*f875b4ebSrica if (read(fd, &info, sizeof (info)) < 0) {
171*f875b4ebSrica int saverr = errno;
172*f875b4ebSrica
173*f875b4ebSrica (void) close(fd);
174*f875b4ebSrica if (saverr == EAGAIN)
175*f875b4ebSrica goto retry;
176*f875b4ebSrica if (saverr != ENOENT)
177*f875b4ebSrica perror(arg);
178*f875b4ebSrica return (1);
179*f875b4ebSrica }
180*f875b4ebSrica (void) close(fd);
181*f875b4ebSrica
182*f875b4ebSrica if (info.pr_lwp.pr_state == 0) /* can't happen? */
183*f875b4ebSrica return (1);
184*f875b4ebSrica
185*f875b4ebSrica if ((plabel = getzonelabelbyid(info.pr_zoneid)) == NULL) {
186*f875b4ebSrica return (1);
187*f875b4ebSrica }
188*f875b4ebSrica
189*f875b4ebSrica /*
190*f875b4ebSrica * The process label for global zone is admin_high
191*f875b4ebSrica */
192*f875b4ebSrica if (info.pr_zoneid == GLOBAL_ZONEID) {
193*f875b4ebSrica _BSLHIGH(plabel);
194*f875b4ebSrica }
195*f875b4ebSrica
196*f875b4ebSrica if (label_to_str(plabel, &str, M_LABEL, wordlen) != 0) {
197*f875b4ebSrica perror(arg);
198*f875b4ebSrica return (2);
199*f875b4ebSrica }
200*f875b4ebSrica (void) printf("%s\n", str);
201*f875b4ebSrica m_label_free(plabel);
202*f875b4ebSrica free(str);
203*f875b4ebSrica return (0);
204*f875b4ebSrica }
205*f875b4ebSrica
206*f875b4ebSrica
207*f875b4ebSrica /*
208*f875b4ebSrica * usage()
209*f875b4ebSrica *
210*f875b4ebSrica * This routine is called whenever there is a usage type of error has
211*f875b4ebSrica * occured. For example, when a invalid option has has been specified.
212*f875b4ebSrica *
213*f875b4ebSrica */
214*f875b4ebSrica static void
usage(void)215*f875b4ebSrica usage(void)
216*f875b4ebSrica {
217*f875b4ebSrica
218*f875b4ebSrica (void) fprintf(stderr, "Usage: \n");
219*f875b4ebSrica (void) fprintf(stderr,
220*f875b4ebSrica gettext(" %s [pid ...] \n"), cmd);
221*f875b4ebSrica (void) fprintf(stderr,
222*f875b4ebSrica gettext(" %s -s [pid ...] \n"), cmd);
223*f875b4ebSrica (void) fprintf(stderr,
224*f875b4ebSrica gettext(" %s -S [pid ...] \n"), cmd);
225*f875b4ebSrica }
226*f875b4ebSrica
227*f875b4ebSrica static int
perr(char * s)228*f875b4ebSrica perr(char *s) {
229*f875b4ebSrica
230*f875b4ebSrica if (s)
231*f875b4ebSrica (void) fprintf(stderr, "%s: ", procname);
232*f875b4ebSrica else
233*f875b4ebSrica s = procname;
234*f875b4ebSrica perror(s);
235*f875b4ebSrica return (1);
236*f875b4ebSrica }
237