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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <pwd.h> 32 #include <string.h> 33 #include <libintl.h> 34 #include <locale.h> 35 #include <deflt.h> 36 #include <user_attr.h> 37 #include <prof_attr.h> 38 #include <exec_attr.h> 39 #include <auth_attr.h> 40 41 42 #define EXIT_OK 0 43 #define EXIT_FATAL 1 44 #define EXIT_NON_FATAL 2 45 46 #define MAX_LINE_LEN 80 /* max 80 chars per line of output */ 47 #define TMP_BUF_LEN 2048 /* size of temp string buffer */ 48 49 #define PRINT_DEFAULT 0x0000 50 #define PRINT_NAME 0x0010 51 #define PRINT_LONG 0x0020 52 53 #ifndef TEXT_DOMAIN /* Should be defined by cc -D */ 54 #define TEXT_DOMAIN "SYS_TEST" 55 #endif 56 57 #define PROFLIST_SEP "," 58 59 60 static void usage(); 61 static int show_profs(char *, int); 62 static int list_profs(userattr_t *, int); 63 static void print_profs_long(void *, int); 64 static void print_profs(char **, int, int); 65 static void format_attr(int *, int, char *); 66 static void getProfiles(char *, char **, int *); 67 static void getDefaultProfiles(char *, char **, int *); 68 69 static char *progname = "profiles"; 70 71 int 72 main(int argc, char *argv[]) 73 { 74 extern int optind; 75 int c; 76 int status = EXIT_OK; 77 int print_flag = PRINT_DEFAULT; 78 79 (void) setlocale(LC_ALL, ""); 80 (void) textdomain(TEXT_DOMAIN); 81 82 while ((c = getopt(argc, argv, "l")) != EOF) { 83 switch (c) { 84 case 'l': 85 print_flag |= PRINT_LONG; 86 break; 87 default: 88 usage(); 89 return (EXIT_FATAL); 90 } 91 } 92 argc -= optind; 93 argv += optind; 94 95 if (*argv == NULL) { 96 status = show_profs(NULL, print_flag); 97 } else { 98 do { 99 (void) printf("\n%s :\n", *argv); 100 status = show_profs((char *)*argv, 101 (print_flag | PRINT_NAME)); 102 if (status == EXIT_FATAL) { 103 break; 104 } 105 } while (*++argv); 106 } 107 status = (status == EXIT_OK) ? status : EXIT_FATAL; 108 109 return (status); 110 } 111 112 113 static int 114 show_profs(char *username, int print_flag) 115 { 116 int status = EXIT_OK; 117 struct passwd *pw; 118 userattr_t *user; 119 char *profArray[MAXPROFS]; 120 int profcnt = 0; 121 execattr_t *exec; 122 123 if (username == NULL) { 124 if ((pw = getpwuid(getuid())) == NULL) { 125 status = EXIT_NON_FATAL; 126 (void) fprintf(stderr, "%s: ", progname); 127 (void) fprintf(stderr, gettext("No passwd entry\n")); 128 return (status); 129 } 130 username = pw->pw_name; 131 } else if (getpwnam(username) == NULL) { 132 status = EXIT_NON_FATAL; 133 (void) fprintf(stderr, "%s: %s : ", progname, username); 134 (void) fprintf(stderr, gettext("No such user\n")); 135 return (status); 136 } 137 if (username != NULL) { 138 if ((user = getusernam(username)) != NULL) { 139 status = list_profs(user, print_flag); 140 } else { 141 getDefaultProfiles(username, profArray, &profcnt); 142 if (profcnt == 0) { 143 status = EXIT_NON_FATAL; 144 } else { 145 if (print_flag & PRINT_LONG) { 146 exec = getexecuser(username, KV_COMMAND, 147 NULL, GET_ALL); 148 print_profs_long(exec, print_flag); 149 free_execattr(exec); 150 } else { 151 print_profs(profArray, print_flag, 152 profcnt); 153 } 154 } 155 } 156 } 157 158 if (status == EXIT_NON_FATAL) { 159 (void) fprintf(stderr, "%s: %s : ", progname, username); 160 (void) fprintf(stderr, gettext("No profiles\n")); 161 } 162 163 return (status); 164 } 165 166 167 static int 168 list_profs(userattr_t *user, int print_flag) 169 { 170 int status = EXIT_OK; 171 char *proflist = (char *)NULL; 172 execattr_t *exec = (execattr_t *)NULL; 173 char *profArray[MAXPROFS]; 174 int profcnt = 0; 175 176 if (print_flag & PRINT_LONG) { 177 exec = getexecuser(user->name, KV_COMMAND, NULL, GET_ALL); 178 if (exec == NULL) { 179 status = EXIT_NON_FATAL; 180 } 181 } else { 182 proflist = kva_match(user->attr, USERATTR_PROFILES_KW); 183 if (proflist != NULL) { 184 getProfiles(proflist, profArray, &profcnt); 185 } 186 /* Also get any default profiles */ 187 getDefaultProfiles(user->name, profArray, &profcnt); 188 if (profcnt == 0) { 189 status = EXIT_NON_FATAL; 190 } 191 } 192 if (status == EXIT_OK) { 193 if (print_flag & PRINT_LONG) { 194 print_profs_long(exec, print_flag); 195 free_execattr(exec); 196 } else { 197 print_profs(profArray, print_flag, profcnt); 198 } 199 } 200 free_userattr(user); 201 202 return (status); 203 } 204 205 206 static void 207 print_profs_long(void *data, int print_flag) 208 { 209 210 int i; 211 int len; 212 int outlen; 213 char tmpstr[TMP_BUF_LEN]; 214 char *lastname = ""; 215 char *key; 216 char *val; 217 kv_t *kv_pair; 218 execattr_t *exec; 219 220 if (!(print_flag & PRINT_NAME)) { 221 (void) printf("\n"); 222 } 223 exec = (execattr_t *)data; 224 while (exec != (execattr_t *)NULL) { 225 if (strcmp(exec->name, lastname) != NULL) { 226 (void) snprintf(tmpstr, sizeof (tmpstr), 227 " %s:", exec->name); 228 (void) printf("%s\n", tmpstr); 229 } 230 (void) snprintf(tmpstr, sizeof (tmpstr), 231 " %s ", exec->id); 232 outlen = strlen(tmpstr); 233 len = outlen; 234 (void) printf("%s", tmpstr); 235 if ((exec->attr == NULL) || 236 (kv_pair = exec->attr->data) == NULL) { 237 (void) printf("\n"); 238 lastname = exec->name; 239 exec = exec->next; 240 continue; 241 } 242 for (i = 0; i < exec->attr->length; i++) { 243 key = kv_pair[i].key; 244 val = kv_pair[i].value; 245 if ((key == NULL) || (val == NULL)) { 246 break; 247 } 248 if (i > 0) { 249 (void) strlcpy(tmpstr, ", ", TMP_BUF_LEN); 250 format_attr(&outlen, len, tmpstr); 251 } 252 (void) snprintf(tmpstr, sizeof (tmpstr), "%s=%s", 253 key, val); 254 format_attr(&outlen, len, tmpstr); 255 } 256 (void) printf("\n"); 257 lastname = exec->name; 258 exec = exec->next; 259 } 260 } 261 262 263 static void 264 format_attr(int *outlen, int len, char *str) 265 { 266 int newline = 0; 267 268 if ((MAX_LINE_LEN - *outlen) < strlen(str)) { 269 newline = 1; 270 } 271 if (newline) { 272 (void) printf("\n"); 273 len += strlen(str); 274 (void) printf("%*s", len, str); 275 *outlen = len; 276 } else { 277 *outlen += strlen(str); 278 (void) printf("%s", str); 279 } 280 } 281 282 static void 283 usage() 284 { 285 (void) fprintf(stderr, 286 gettext(" usage: profiles [-l] [user1 user2 ...]\n")); 287 } 288 289 static void 290 getProfiles(char *profiles, char **profArray, int *profcnt) { 291 292 char *prof; 293 char *lasts; 294 295 for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts); 296 prof != NULL; 297 prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) { 298 299 getproflist(prof, profArray, profcnt); 300 301 } 302 } 303 304 static void 305 print_profs(char **profnames, int print_flag, int profcnt) 306 { 307 308 int i; 309 char *indent = ""; 310 311 if (print_flag & PRINT_NAME) { 312 indent = " "; 313 } 314 315 for (i = 0; i < profcnt; i++) { 316 (void) printf("%s%s\n", indent, profnames[i]); 317 } 318 319 free_proflist(profnames, profcnt); 320 } 321 322 /* 323 * Get the list of default profiles from /etc/security/policy.conf 324 */ 325 static void 326 getDefaultProfiles(char *user, char **profArray, int *profcnt) 327 { 328 char *profs = NULL; 329 330 if (_get_user_defs(user, NULL, &profs) == 0) { 331 if (profs != NULL) { 332 getProfiles(profs, profArray, profcnt); 333 _free_user_defs(NULL, profs); 334 } 335 } 336 } 337