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 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 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 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 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