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 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include <pwd.h> 29 #include <string.h> 30 #include <libintl.h> 31 #include <locale.h> 32 #include <deflt.h> 33 #include <user_attr.h> 34 #include <prof_attr.h> 35 #include <exec_attr.h> 36 #include <auth_attr.h> 37 38 39 #define EXIT_OK 0 40 #define EXIT_FATAL 1 41 #define EXIT_NON_FATAL 2 42 43 #define TMP_BUF_LEN 2048 /* size of temp string buffer */ 44 45 #define PRINT_DEFAULT 0x0000 46 #define PRINT_NAME 0x0010 47 #define PRINT_LONG 0x0020 48 49 #ifndef TEXT_DOMAIN /* Should be defined by cc -D */ 50 #define TEXT_DOMAIN "SYS_TEST" 51 #endif 52 53 static void usage(); 54 static int show_profs(char *, int); 55 static void print_profs_long(execattr_t *); 56 static void print_profile_privs(kva_t *); 57 58 static char *progname = "profiles"; 59 60 int 61 main(int argc, char *argv[]) 62 { 63 extern int optind; 64 int c; 65 int status = EXIT_OK; 66 int print_flag = PRINT_DEFAULT; 67 68 (void) setlocale(LC_ALL, ""); 69 (void) textdomain(TEXT_DOMAIN); 70 71 while ((c = getopt(argc, argv, "l")) != EOF) { 72 switch (c) { 73 case 'l': 74 print_flag |= PRINT_LONG; 75 break; 76 default: 77 usage(); 78 return (EXIT_FATAL); 79 } 80 } 81 argc -= optind; 82 argv += optind; 83 84 if (*argv == NULL) { 85 status = show_profs(NULL, print_flag); 86 } else { 87 do { 88 (void) printf("%s:\n", *argv); 89 status = show_profs((char *)*argv, 90 (print_flag | PRINT_NAME)); 91 if (status == EXIT_FATAL) { 92 break; 93 } 94 if (argv[1] != NULL) { 95 /* seperate users with empty line */ 96 (void) printf("\n"); 97 } 98 } while (*++argv); 99 } 100 status = (status == EXIT_OK) ? status : EXIT_FATAL; 101 102 return (status); 103 } 104 105 static int 106 show_profs_callback(const char *prof, kva_t *pa, void *pflag, void *vcnt) 107 { 108 char *indent = ""; 109 const int *print_flag = pflag; 110 int *pcnt = vcnt; 111 112 (*pcnt)++; 113 114 if ((*print_flag) & PRINT_NAME) { 115 indent = " "; 116 } 117 118 (void) printf("%s%s", indent, prof); 119 print_profile_privs(pa); 120 (void) printf("\n"); 121 122 return (0); 123 } 124 125 static int 126 show_profs(char *username, int print_flag) 127 { 128 int status = EXIT_OK; 129 struct passwd *pw; 130 execattr_t *exec; 131 132 if (username == NULL) { 133 if ((pw = getpwuid(getuid())) == NULL) { 134 status = EXIT_NON_FATAL; 135 (void) fprintf(stderr, "%s: ", progname); 136 (void) fprintf(stderr, gettext("No passwd entry\n")); 137 return (status); 138 } 139 username = pw->pw_name; 140 } else if (getpwnam(username) == NULL) { 141 status = EXIT_NON_FATAL; 142 (void) fprintf(stderr, "%s: %s: ", progname, username); 143 (void) fprintf(stderr, gettext("No such user\n")); 144 return (status); 145 } 146 147 if (print_flag & PRINT_LONG) { 148 exec = getexecuser(username, KV_COMMAND, NULL, 149 GET_ALL|__SEARCH_ALL_POLS); 150 if (exec != NULL) { 151 print_profs_long(exec); 152 free_execattr(exec); 153 } else { 154 status = EXIT_NON_FATAL; 155 } 156 } else { 157 int cnt = 0; 158 (void) _enum_profs(username, show_profs_callback, &print_flag, 159 &cnt); 160 161 if (cnt == 0) 162 status = EXIT_NON_FATAL; 163 } 164 165 if (status == EXIT_NON_FATAL) { 166 (void) fprintf(stderr, "%s: %s: ", progname, username); 167 (void) fprintf(stderr, gettext("No profiles\n")); 168 } 169 170 return (status); 171 } 172 173 /* 174 * print extended profile information. 175 * 176 * output is "pretty printed" like 177 * [6spaces]Profile Name1[ possible profile privileges] 178 * [10spaces ]execname1 [skip to ATTR_COL]exec1 attributes1 179 * [ spaces to ATTR_COL ]exec1 attributes2 180 * [10spaces ]execname2 [skip to ATTR_COL]exec2 attributes1 181 * [ spaces to ATTR_COL ]exec2 attributes2 182 * [6spaces]Profile Name2[ possible profile privileges] 183 * etc 184 */ 185 /* 186 * ATTR_COL is based on 187 * 10 leading spaces + 188 * 25 positions for the executable + 189 * 1 space seperating the execname from the attributes 190 * so attribute printing starts at column 37 (36 whitespaces) 191 * 192 * 25 spaces for the execname seems reasonable since currently 193 * less than 3% of the shipped exec_attr would overflow this 194 */ 195 #define ATTR_COL 37 196 197 static void 198 print_profs_long(execattr_t *exec) 199 { 200 char *curprofile; 201 int len; 202 kv_t *kv_pair; 203 char *key; 204 char *val; 205 int i; 206 207 for (curprofile = ""; exec != NULL; exec = exec->next) { 208 /* print profile name if it is a new one */ 209 if (strcmp(curprofile, exec->name) != 0) { 210 profattr_t *pa; 211 curprofile = exec->name; 212 213 (void) printf(" %s", curprofile); 214 215 pa = getprofnam(curprofile); 216 if (pa != NULL) { 217 print_profile_privs(pa->attr); 218 free_profattr(pa); 219 } 220 (void) printf("\n"); 221 } 222 len = printf(" %s ", exec->id); 223 224 if ((exec->attr == NULL || exec->attr->data == NULL)) { 225 (void) printf("\n"); 226 continue; 227 } 228 229 /* 230 * if printing the name of the executable got us past the 231 * ATTR_COLth column, skip to ATTR_COL on a new line to 232 * print the attribues. 233 * else, just skip to ATTR_COL column. 234 */ 235 if (len >= ATTR_COL) 236 (void) printf("\n%*s", ATTR_COL, " "); 237 else 238 (void) printf("%*s", ATTR_COL-len, " "); 239 len = ATTR_COL; 240 241 /* print all attributes of this profile */ 242 kv_pair = exec->attr->data; 243 for (i = 0; i < exec->attr->length; i++) { 244 key = kv_pair[i].key; 245 val = kv_pair[i].value; 246 if (key == NULL || val == NULL) 247 break; 248 /* align subsequent attributes on the same column */ 249 if (i > 0) 250 (void) printf("%*s", len, " "); 251 (void) printf("%s=%s\n", key, val); 252 } 253 } 254 } 255 256 static void 257 usage() 258 { 259 (void) fprintf(stderr, 260 gettext(" usage: profiles [-l] [user1 user2 ...]\n")); 261 } 262 263 static void 264 print_profile_privs(kva_t *attr) 265 { 266 char *privs; 267 268 if (attr) { 269 privs = kva_match(attr, PROFATTR_PRIVS_KW); 270 if (privs) 271 (void) printf(" privs=%s", privs); 272 } 273 } 274