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