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