xref: /illumos-gate/usr/src/cmd/tsol/plabel/plabel.c (revision 2a8bcb4e)
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 /*
28*f875b4ebSrica  *	plabel - gets process label.
29*f875b4ebSrica  */
30*f875b4ebSrica #include <stdio.h>
31*f875b4ebSrica #include <stdlib.h>
32*f875b4ebSrica #include <errno.h>
33*f875b4ebSrica #include <unistd.h>
34*f875b4ebSrica #include <fcntl.h>
35*f875b4ebSrica #include <string.h>
36*f875b4ebSrica #include <locale.h>
37*f875b4ebSrica #include <procfs.h>
38*f875b4ebSrica #include <sys/proc.h>
39*f875b4ebSrica #include <zone.h>
40*f875b4ebSrica 
41*f875b4ebSrica #include <sys/tsol/label_macro.h>
42*f875b4ebSrica 
43*f875b4ebSrica #include <tsol/label.h>
44*f875b4ebSrica 
45*f875b4ebSrica #define	s_flag	0x04
46*f875b4ebSrica #define	S_flag	0x08
47*f875b4ebSrica 
48*f875b4ebSrica #define	INIT_ALLOC_LEN	1024
49*f875b4ebSrica #define	MAX_ALLOC_NUM	11
50*f875b4ebSrica 
51*f875b4ebSrica static int look(char *);
52*f875b4ebSrica static int perr(char *);
53*f875b4ebSrica static void usage(void);
54*f875b4ebSrica 
55*f875b4ebSrica static char procname[64];
56*f875b4ebSrica 
57*f875b4ebSrica static unsigned int opt_flag = 0;
58*f875b4ebSrica static char *cmd = NULL;
59*f875b4ebSrica 
60*f875b4ebSrica int
main(int argc,char ** argv)61*f875b4ebSrica main(int argc, char **argv)
62*f875b4ebSrica {
63*f875b4ebSrica 	int err, rc = 0;
64*f875b4ebSrica 	int opt;
65*f875b4ebSrica 
66*f875b4ebSrica 	(void) setlocale(LC_ALL, "");
67*f875b4ebSrica #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
68*f875b4ebSrica #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
69*f875b4ebSrica #endif
70*f875b4ebSrica 	(void) textdomain(TEXT_DOMAIN);
71*f875b4ebSrica 
72*f875b4ebSrica 	if ((cmd = strrchr(argv[0], '/')) == NULL)
73*f875b4ebSrica 		cmd = argv[0];
74*f875b4ebSrica 	else
75*f875b4ebSrica 		cmd++;
76*f875b4ebSrica 
77*f875b4ebSrica 	/* Error if labeling is not active. */
78*f875b4ebSrica 	if (!is_system_labeled()) {
79*f875b4ebSrica 		(void) fprintf(stderr,
80*f875b4ebSrica 		    gettext("%s: Trusted Extensions must be enabled\n"), cmd);
81*f875b4ebSrica 		return (1);
82*f875b4ebSrica 	}
83*f875b4ebSrica 
84*f875b4ebSrica 	while ((opt = getopt(argc, argv, "sS")) != EOF) {
85*f875b4ebSrica 		switch (opt) {
86*f875b4ebSrica 		case 's':
87*f875b4ebSrica 			if (opt_flag & (s_flag | S_flag)) {
88*f875b4ebSrica 				usage();
89*f875b4ebSrica 				return (1);
90*f875b4ebSrica 			}
91*f875b4ebSrica 			opt_flag |= s_flag;
92*f875b4ebSrica 			break;
93*f875b4ebSrica 
94*f875b4ebSrica 		case 'S':
95*f875b4ebSrica 			if (opt_flag & (s_flag | S_flag)) {
96*f875b4ebSrica 				usage();
97*f875b4ebSrica 				return (1);
98*f875b4ebSrica 			}
99*f875b4ebSrica 			opt_flag |= S_flag;
100*f875b4ebSrica 			break;
101*f875b4ebSrica 		default:
102*f875b4ebSrica 			usage();
103*f875b4ebSrica 			return (1);
104*f875b4ebSrica 		}
105*f875b4ebSrica 	}
106*f875b4ebSrica 
107*f875b4ebSrica 	argc -= optind;
108*f875b4ebSrica 	argv += optind;
109*f875b4ebSrica 	if (argc == 0) {
110*f875b4ebSrica 		char pid[11]; /* 32 bit pids go to 4294967295 plus a NUL */
111*f875b4ebSrica 
112*f875b4ebSrica 		(void) sprintf(pid, "%d", (int)getpid());
113*f875b4ebSrica 		rc = look(pid);
114*f875b4ebSrica 	} else {
115*f875b4ebSrica 		while (argc-- > 0) {
116*f875b4ebSrica 			err = look(*argv++);
117*f875b4ebSrica 			if (rc == 0)
118*f875b4ebSrica 				rc = err;
119*f875b4ebSrica 		}
120*f875b4ebSrica 	}
121*f875b4ebSrica 	return (rc);
122*f875b4ebSrica }
123*f875b4ebSrica 
124*f875b4ebSrica static int
look(char * arg)125*f875b4ebSrica look(char *arg)
126*f875b4ebSrica {
127*f875b4ebSrica 	int fd;
128*f875b4ebSrica 	m_label_t *plabel;
129*f875b4ebSrica 	psinfo_t info;		/* process information from /proc */
130*f875b4ebSrica 	char *str;
131*f875b4ebSrica 	int wordlen = DEF_NAMES;
132*f875b4ebSrica 
133*f875b4ebSrica 	if (opt_flag == S_flag)
134*f875b4ebSrica 		wordlen = LONG_NAMES;
135*f875b4ebSrica 	else if (opt_flag == s_flag)
136*f875b4ebSrica 		wordlen = SHORT_NAMES;
137*f875b4ebSrica 
138*f875b4ebSrica 	if (strchr(arg, '/') != NULL)
139*f875b4ebSrica 		(void) strncpy(procname, arg, sizeof (procname));
140*f875b4ebSrica 	else {
141*f875b4ebSrica 		(void) strcpy(procname, "/proc/");
142*f875b4ebSrica 		(void) strncat(procname, arg,
143*f875b4ebSrica 		    sizeof (procname) - strlen(procname));
144*f875b4ebSrica 	}
145*f875b4ebSrica 	(void) strlcat(procname, "/psinfo", sizeof (procname)
146*f875b4ebSrica 	    - strlen(procname));
147*f875b4ebSrica 
148*f875b4ebSrica 	/*
149*f875b4ebSrica 	 * Open the process to be examined.
150*f875b4ebSrica 	 */
151*f875b4ebSrica retry:
152*f875b4ebSrica 	if ((fd = open(procname, O_RDONLY)) < 0) {
153*f875b4ebSrica 		/*
154*f875b4ebSrica 		 * Make clean message for non-existent process.
155*f875b4ebSrica 		 */
156*f875b4ebSrica 		if (errno == ENOENT) {
157*f875b4ebSrica 			errno = ESRCH;
158*f875b4ebSrica 			perror(arg);
159*f875b4ebSrica 			return (1);
160*f875b4ebSrica 		}
161*f875b4ebSrica 		return (perr(NULL));
162*f875b4ebSrica 	}
163*f875b4ebSrica 
164*f875b4ebSrica 
165*f875b4ebSrica 	/*
166*f875b4ebSrica 	 * Get the info structure for the process and close quickly.
167*f875b4ebSrica 	 */
168*f875b4ebSrica 	if (read(fd, &info, sizeof (info)) < 0) {
169*f875b4ebSrica 		int	saverr = errno;
170*f875b4ebSrica 
171*f875b4ebSrica 		(void) close(fd);
172*f875b4ebSrica 		if (saverr == EAGAIN)
173*f875b4ebSrica 			goto retry;
174*f875b4ebSrica 		if (saverr != ENOENT)
175*f875b4ebSrica 			perror(arg);
176*f875b4ebSrica 		return (1);
177*f875b4ebSrica 	}
178*f875b4ebSrica 	(void) close(fd);
179*f875b4ebSrica 
180*f875b4ebSrica 	if (info.pr_lwp.pr_state == 0)  /* can't happen? */
181*f875b4ebSrica 		return (1);
182*f875b4ebSrica 
183*f875b4ebSrica 	if ((plabel = getzonelabelbyid(info.pr_zoneid)) == NULL) {
184*f875b4ebSrica 		return (1);
185*f875b4ebSrica 	}
186*f875b4ebSrica 
187*f875b4ebSrica 	/*
188*f875b4ebSrica 	 * The process label for global zone is admin_high
189*f875b4ebSrica 	 */
190*f875b4ebSrica 	if (info.pr_zoneid == GLOBAL_ZONEID) {
191*f875b4ebSrica 		_BSLHIGH(plabel);
192*f875b4ebSrica 	}
193*f875b4ebSrica 
194*f875b4ebSrica 	if (label_to_str(plabel, &str, M_LABEL, wordlen) != 0) {
195*f875b4ebSrica 		perror(arg);
196*f875b4ebSrica 		return (2);
197*f875b4ebSrica 	}
198*f875b4ebSrica 	(void) printf("%s\n", str);
199*f875b4ebSrica 	m_label_free(plabel);
200*f875b4ebSrica 	free(str);
201*f875b4ebSrica 	return (0);
202*f875b4ebSrica }
203*f875b4ebSrica 
204*f875b4ebSrica 
205*f875b4ebSrica /*
206*f875b4ebSrica  * usage()
207*f875b4ebSrica  *
208*f875b4ebSrica  * This routine is called whenever there is a usage type of error has
209*f875b4ebSrica  * occured.  For example, when a invalid option has has been specified.
210*f875b4ebSrica  *
211*f875b4ebSrica  */
212*f875b4ebSrica static void
usage(void)213*f875b4ebSrica usage(void)
214*f875b4ebSrica {
215*f875b4ebSrica 
216*f875b4ebSrica 	(void) fprintf(stderr, "Usage: \n");
217*f875b4ebSrica 	(void) fprintf(stderr,
218*f875b4ebSrica 	    gettext("	%s [pid ...]    \n"), cmd);
219*f875b4ebSrica 	(void) fprintf(stderr,
220*f875b4ebSrica 	    gettext("	%s -s  [pid ...] \n"), cmd);
221*f875b4ebSrica 	(void) fprintf(stderr,
222*f875b4ebSrica 	    gettext("	%s -S  [pid ...] \n"), cmd);
223*f875b4ebSrica }
224*f875b4ebSrica 
225*f875b4ebSrica static int
perr(char * s)226*f875b4ebSrica perr(char *s) {
227*f875b4ebSrica 
228*f875b4ebSrica 	if (s)
229*f875b4ebSrica 		(void) fprintf(stderr, "%s: ", procname);
230*f875b4ebSrica 	else
231*f875b4ebSrica 		s = procname;
232*f875b4ebSrica 	perror(s);
233*f875b4ebSrica 	return (1);
234*f875b4ebSrica }
235