17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 514839a76Sbubbva * Common Development and Distribution License (the "License"). 614839a76Sbubbva * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*b4820df8SJoep Vesseur * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 277c478bd9Sstevel@tonic-gate #include <stdlib.h> 287c478bd9Sstevel@tonic-gate #include <unistd.h> 297c478bd9Sstevel@tonic-gate #include <pwd.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <libintl.h> 327c478bd9Sstevel@tonic-gate #include <locale.h> 337c478bd9Sstevel@tonic-gate #include <deflt.h> 347c478bd9Sstevel@tonic-gate #include <user_attr.h> 357c478bd9Sstevel@tonic-gate #include <prof_attr.h> 367c478bd9Sstevel@tonic-gate #include <exec_attr.h> 377c478bd9Sstevel@tonic-gate #include <auth_attr.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #define EXIT_OK 0 417c478bd9Sstevel@tonic-gate #define EXIT_FATAL 1 427c478bd9Sstevel@tonic-gate #define EXIT_NON_FATAL 2 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #define TMP_BUF_LEN 2048 /* size of temp string buffer */ 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #define PRINT_DEFAULT 0x0000 477c478bd9Sstevel@tonic-gate #define PRINT_NAME 0x0010 487c478bd9Sstevel@tonic-gate #define PRINT_LONG 0x0020 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN /* Should be defined by cc -D */ 517c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 527c478bd9Sstevel@tonic-gate #endif 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #define PROFLIST_SEP "," 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static void usage(); 587c478bd9Sstevel@tonic-gate static int show_profs(char *, int); 597c478bd9Sstevel@tonic-gate static int list_profs(userattr_t *, int); 60*b4820df8SJoep Vesseur static void print_profs_long(execattr_t *); 6158d1a73cSgww static void print_profs(char **, int, int); 627c478bd9Sstevel@tonic-gate static void getProfiles(char *, char **, int *); 63499fd601Sgww static void getDefaultProfiles(char *, char **, int *); 64*b4820df8SJoep Vesseur static void print_profile_privs(const char *); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate static char *progname = "profiles"; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate int 697c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 707c478bd9Sstevel@tonic-gate { 717c478bd9Sstevel@tonic-gate extern int optind; 7258d1a73cSgww int c; 7358d1a73cSgww int status = EXIT_OK; 747c478bd9Sstevel@tonic-gate int print_flag = PRINT_DEFAULT; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 777c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "l")) != EOF) { 807c478bd9Sstevel@tonic-gate switch (c) { 817c478bd9Sstevel@tonic-gate case 'l': 827c478bd9Sstevel@tonic-gate print_flag |= PRINT_LONG; 837c478bd9Sstevel@tonic-gate break; 847c478bd9Sstevel@tonic-gate default: 857c478bd9Sstevel@tonic-gate usage(); 867c478bd9Sstevel@tonic-gate return (EXIT_FATAL); 877c478bd9Sstevel@tonic-gate } 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate argc -= optind; 907c478bd9Sstevel@tonic-gate argv += optind; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate if (*argv == NULL) { 93499fd601Sgww status = show_profs(NULL, print_flag); 947c478bd9Sstevel@tonic-gate } else { 957c478bd9Sstevel@tonic-gate do { 96*b4820df8SJoep Vesseur (void) printf("%s:\n", *argv); 9758d1a73cSgww status = show_profs((char *)*argv, 9858d1a73cSgww (print_flag | PRINT_NAME)); 997c478bd9Sstevel@tonic-gate if (status == EXIT_FATAL) { 1007c478bd9Sstevel@tonic-gate break; 1017c478bd9Sstevel@tonic-gate } 102*b4820df8SJoep Vesseur if (argv[1] != NULL) { 103*b4820df8SJoep Vesseur /* seperate users with empty line */ 104*b4820df8SJoep Vesseur (void) printf("\n"); 105*b4820df8SJoep Vesseur } 1067c478bd9Sstevel@tonic-gate } while (*++argv); 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate status = (status == EXIT_OK) ? status : EXIT_FATAL; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate return (status); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate static int 1157c478bd9Sstevel@tonic-gate show_profs(char *username, int print_flag) 1167c478bd9Sstevel@tonic-gate { 11758d1a73cSgww int status = EXIT_OK; 11858d1a73cSgww struct passwd *pw; 11958d1a73cSgww userattr_t *user; 1207c478bd9Sstevel@tonic-gate char *profArray[MAXPROFS]; 1217c478bd9Sstevel@tonic-gate int profcnt = 0; 1227c478bd9Sstevel@tonic-gate execattr_t *exec; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate if (username == NULL) { 1257c478bd9Sstevel@tonic-gate if ((pw = getpwuid(getuid())) == NULL) { 1267c478bd9Sstevel@tonic-gate status = EXIT_NON_FATAL; 1277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", progname); 1287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("No passwd entry\n")); 1297c478bd9Sstevel@tonic-gate return (status); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate username = pw->pw_name; 13214839a76Sbubbva } else if (getpwnam(username) == NULL) { 1337c478bd9Sstevel@tonic-gate status = EXIT_NON_FATAL; 1347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: ", progname, username); 1357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("No such user\n")); 1367c478bd9Sstevel@tonic-gate return (status); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate if (username != NULL) { 1397c478bd9Sstevel@tonic-gate if ((user = getusernam(username)) != NULL) { 1407c478bd9Sstevel@tonic-gate status = list_profs(user, print_flag); 1417c478bd9Sstevel@tonic-gate } else { 142499fd601Sgww getDefaultProfiles(username, profArray, &profcnt); 1437c478bd9Sstevel@tonic-gate if (profcnt == 0) { 1447c478bd9Sstevel@tonic-gate status = EXIT_NON_FATAL; 1457c478bd9Sstevel@tonic-gate } else { 1467c478bd9Sstevel@tonic-gate if (print_flag & PRINT_LONG) { 1477c478bd9Sstevel@tonic-gate exec = getexecuser(username, KV_COMMAND, 1487c478bd9Sstevel@tonic-gate NULL, GET_ALL); 149*b4820df8SJoep Vesseur print_profs_long(exec); 1507c478bd9Sstevel@tonic-gate free_execattr(exec); 1517c478bd9Sstevel@tonic-gate } else { 15258d1a73cSgww print_profs(profArray, print_flag, 15358d1a73cSgww profcnt); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if (status == EXIT_NON_FATAL) { 1607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: ", progname, username); 1617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("No profiles\n")); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate return (status); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate static int 1697c478bd9Sstevel@tonic-gate list_profs(userattr_t *user, int print_flag) 1707c478bd9Sstevel@tonic-gate { 17158d1a73cSgww int status = EXIT_OK; 1727c478bd9Sstevel@tonic-gate char *proflist = (char *)NULL; 1737c478bd9Sstevel@tonic-gate execattr_t *exec = (execattr_t *)NULL; 1747c478bd9Sstevel@tonic-gate char *profArray[MAXPROFS]; 1757c478bd9Sstevel@tonic-gate int profcnt = 0; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if (print_flag & PRINT_LONG) { 1787c478bd9Sstevel@tonic-gate exec = getexecuser(user->name, KV_COMMAND, NULL, GET_ALL); 1797c478bd9Sstevel@tonic-gate if (exec == NULL) { 1807c478bd9Sstevel@tonic-gate status = EXIT_NON_FATAL; 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate } else { 1837c478bd9Sstevel@tonic-gate proflist = kva_match(user->attr, USERATTR_PROFILES_KW); 1847c478bd9Sstevel@tonic-gate if (proflist != NULL) { 1857c478bd9Sstevel@tonic-gate getProfiles(proflist, profArray, &profcnt); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate /* Also get any default profiles */ 188499fd601Sgww getDefaultProfiles(user->name, profArray, &profcnt); 1897c478bd9Sstevel@tonic-gate if (profcnt == 0) { 1907c478bd9Sstevel@tonic-gate status = EXIT_NON_FATAL; 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate if (status == EXIT_OK) { 1947c478bd9Sstevel@tonic-gate if (print_flag & PRINT_LONG) { 195*b4820df8SJoep Vesseur print_profs_long(exec); 1967c478bd9Sstevel@tonic-gate free_execattr(exec); 1977c478bd9Sstevel@tonic-gate } else { 19858d1a73cSgww print_profs(profArray, print_flag, profcnt); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate free_userattr(user); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate return (status); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate 207*b4820df8SJoep Vesseur /* 208*b4820df8SJoep Vesseur * print extended profile information. 209*b4820df8SJoep Vesseur * 210*b4820df8SJoep Vesseur * output is "pretty printed" like 211*b4820df8SJoep Vesseur * [6spaces]Profile Name1[ possible profile privileges] 212*b4820df8SJoep Vesseur * [10spaces ]execname1 [skip to ATTR_COL]exec1 attributes1 213*b4820df8SJoep Vesseur * [ spaces to ATTR_COL ]exec1 attributes2 214*b4820df8SJoep Vesseur * [10spaces ]execname2 [skip to ATTR_COL]exec2 attributes1 215*b4820df8SJoep Vesseur * [ spaces to ATTR_COL ]exec2 attributes2 216*b4820df8SJoep Vesseur * [6spaces]Profile Name2[ possible profile privileges] 217*b4820df8SJoep Vesseur * etc 218*b4820df8SJoep Vesseur */ 219*b4820df8SJoep Vesseur /* 220*b4820df8SJoep Vesseur * ATTR_COL is based on 221*b4820df8SJoep Vesseur * 10 leading spaces + 222*b4820df8SJoep Vesseur * 25 positions for the executable + 223*b4820df8SJoep Vesseur * 1 space seperating the execname from the attributes 224*b4820df8SJoep Vesseur * so attribute printing starts at column 37 (36 whitespaces) 225*b4820df8SJoep Vesseur * 226*b4820df8SJoep Vesseur * 25 spaces for the execname seems reasonable since currently 227*b4820df8SJoep Vesseur * less than 3% of the shipped exec_attr would overflow this 228*b4820df8SJoep Vesseur */ 229*b4820df8SJoep Vesseur #define ATTR_COL 37 2307c478bd9Sstevel@tonic-gate 231*b4820df8SJoep Vesseur static void 232*b4820df8SJoep Vesseur print_profs_long(execattr_t *exec) 233*b4820df8SJoep Vesseur { 234*b4820df8SJoep Vesseur char *curprofile; 23558d1a73cSgww int len; 236*b4820df8SJoep Vesseur kv_t *kv_pair; 23758d1a73cSgww char *key; 23858d1a73cSgww char *val; 239*b4820df8SJoep Vesseur int i; 2407c478bd9Sstevel@tonic-gate 241*b4820df8SJoep Vesseur for (curprofile = ""; exec != NULL; exec = exec->next) { 242*b4820df8SJoep Vesseur /* print profile name if it is a new one */ 243*b4820df8SJoep Vesseur if (strcmp(curprofile, exec->name) != 0) { 244*b4820df8SJoep Vesseur curprofile = exec->name; 245*b4820df8SJoep Vesseur (void) printf(" %s", curprofile); 246*b4820df8SJoep Vesseur print_profile_privs(curprofile); 2477c478bd9Sstevel@tonic-gate (void) printf("\n"); 24858d1a73cSgww } 249*b4820df8SJoep Vesseur len = printf(" %s ", exec->id); 250*b4820df8SJoep Vesseur 251*b4820df8SJoep Vesseur if ((exec->attr == NULL || exec->attr->data == NULL)) { 2527c478bd9Sstevel@tonic-gate (void) printf("\n"); 2537c478bd9Sstevel@tonic-gate continue; 2547c478bd9Sstevel@tonic-gate } 255*b4820df8SJoep Vesseur 256*b4820df8SJoep Vesseur /* 257*b4820df8SJoep Vesseur * if printing the name of the executable got us past the 258*b4820df8SJoep Vesseur * ATTR_COLth column, skip to ATTR_COL on a new line to 259*b4820df8SJoep Vesseur * print the attribues. 260*b4820df8SJoep Vesseur * else, just skip to ATTR_COL column. 261*b4820df8SJoep Vesseur */ 262*b4820df8SJoep Vesseur if (len >= ATTR_COL) 263*b4820df8SJoep Vesseur (void) printf("\n%*s", ATTR_COL, " "); 264*b4820df8SJoep Vesseur else 265*b4820df8SJoep Vesseur (void) printf("%*s", ATTR_COL-len, " "); 266*b4820df8SJoep Vesseur len = ATTR_COL; 267*b4820df8SJoep Vesseur 268*b4820df8SJoep Vesseur /* print all attributes of this profile */ 269*b4820df8SJoep Vesseur kv_pair = exec->attr->data; 2707c478bd9Sstevel@tonic-gate for (i = 0; i < exec->attr->length; i++) { 2717c478bd9Sstevel@tonic-gate key = kv_pair[i].key; 2727c478bd9Sstevel@tonic-gate val = kv_pair[i].value; 273*b4820df8SJoep Vesseur if (key == NULL || val == NULL) 2747c478bd9Sstevel@tonic-gate break; 275*b4820df8SJoep Vesseur /* align subsequent attributes on the same column */ 276*b4820df8SJoep Vesseur if (i > 0) 277*b4820df8SJoep Vesseur (void) printf("%*s", len, " "); 278*b4820df8SJoep Vesseur (void) printf("%s=%s\n", key, val); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate static void 2847c478bd9Sstevel@tonic-gate usage() 2857c478bd9Sstevel@tonic-gate { 2867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2877c478bd9Sstevel@tonic-gate gettext(" usage: profiles [-l] [user1 user2 ...]\n")); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate static void 2917c478bd9Sstevel@tonic-gate getProfiles(char *profiles, char **profArray, int *profcnt) { 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate char *prof; 2947c478bd9Sstevel@tonic-gate char *lasts; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts); 2977c478bd9Sstevel@tonic-gate prof != NULL; 2987c478bd9Sstevel@tonic-gate prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) { 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate getproflist(prof, profArray, profcnt); 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate static void 306*b4820df8SJoep Vesseur print_profile_privs(const char *profile) 307*b4820df8SJoep Vesseur { 308*b4820df8SJoep Vesseur profattr_t *prof_entry = getprofnam(profile); 309*b4820df8SJoep Vesseur char *privs; 310*b4820df8SJoep Vesseur 311*b4820df8SJoep Vesseur if (prof_entry) { 312*b4820df8SJoep Vesseur privs = kva_match(prof_entry->attr, PROFATTR_PRIVS_KW); 313*b4820df8SJoep Vesseur if (privs) 314*b4820df8SJoep Vesseur (void) printf(" privs=%s", privs); 315*b4820df8SJoep Vesseur free_profattr(prof_entry); 316*b4820df8SJoep Vesseur } 317*b4820df8SJoep Vesseur } 318*b4820df8SJoep Vesseur 319*b4820df8SJoep Vesseur static void 32058d1a73cSgww print_profs(char **profnames, int print_flag, int profcnt) 3217c478bd9Sstevel@tonic-gate { 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate int i; 32458d1a73cSgww char *indent = ""; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate if (print_flag & PRINT_NAME) { 32758d1a73cSgww indent = " "; 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate for (i = 0; i < profcnt; i++) { 331*b4820df8SJoep Vesseur (void) printf("%s%s", indent, profnames[i]); 332*b4820df8SJoep Vesseur print_profile_privs(profnames[i]); 333*b4820df8SJoep Vesseur (void) printf("\n"); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate free_proflist(profnames, profcnt); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* 3407c478bd9Sstevel@tonic-gate * Get the list of default profiles from /etc/security/policy.conf 3417c478bd9Sstevel@tonic-gate */ 3427c478bd9Sstevel@tonic-gate static void 343499fd601Sgww getDefaultProfiles(char *user, char **profArray, int *profcnt) 3447c478bd9Sstevel@tonic-gate { 3457c478bd9Sstevel@tonic-gate char *profs = NULL; 3467c478bd9Sstevel@tonic-gate 347499fd601Sgww if (_get_user_defs(user, NULL, &profs) == 0) { 3487c478bd9Sstevel@tonic-gate if (profs != NULL) { 3497c478bd9Sstevel@tonic-gate getProfiles(profs, profArray, profcnt); 350499fd601Sgww _free_user_defs(NULL, profs); 3517c478bd9Sstevel@tonic-gate } 352499fd601Sgww } 3537c478bd9Sstevel@tonic-gate } 354