summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorCasper H.S. Dik <Casper.Dik@Sun.COM>2010-04-28 10:01:37 +0200
committerCasper H.S. Dik <Casper.Dik@Sun.COM>2010-04-28 10:01:37 +0200
commit134a1f4e3289b54e0f980e9cf05352e419a60bee (patch)
tree792d1e39f7d9299df1f67c1681a02daa1b734878 /usr/src/cmd
parent2e98bdabdfa935eb368c090f1cecbba5619c88ee (diff)
downloadillumos-joyent-134a1f4e3289b54e0f980e9cf05352e419a60bee.tar.gz
PSARC 2009/377 In-kernel pfexec implementation.
PSARC 2009/378 Basic File Privileges PSARC 2010/072 RBAC update: user attrs from profiles 4912090 pfzsh(1) should exist 4912093 pfbash(1) should exist 4912096 pftcsh(1) should exist 6440298 Expand the basic privilege set in order to restrict file access 6859862 Move pfexec into the kernel 6919171 cred_t sidesteps kmem_debug; we need to be able to detect bad hold/free when they occur 6923721 The new SYS_SMB privilege is not backward compatible 6937562 autofs doesn't remove its door when the zone shuts down 6937727 Zones stuck on deathrow; netstack_zone keeps a credential reference to the zone 6940159 Implement PSARC 2010/072
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/Makefile1
-rw-r--r--usr/src/cmd/auditrecord/audit_record_attr.txt11
-rw-r--r--usr/src/cmd/auths/auths.c314
-rw-r--r--usr/src/cmd/csh/i386/Makefile28
-rw-r--r--usr/src/cmd/csh/sh.c94
-rw-r--r--usr/src/cmd/csh/sh.exec.c37
-rw-r--r--usr/src/cmd/csh/sparc/Makefile26
-rw-r--r--usr/src/cmd/fs.d/ufs/newfs/newfs.c5
-rw-r--r--usr/src/cmd/ksh/Makefile10
-rw-r--r--usr/src/cmd/ksh/Makefile.com5
-rw-r--r--usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm8
-rw-r--r--usr/src/cmd/pfexec/Makefile24
-rw-r--r--usr/src/cmd/pfexec/pfexec.c637
-rw-r--r--usr/src/cmd/pfexecd/Makefile62
-rw-r--r--usr/src/cmd/pfexecd/pfexecd.c525
-rw-r--r--usr/src/cmd/pfexecd/pfexecd.xml86
-rw-r--r--usr/src/cmd/profiles/profiles.c173
-rw-r--r--usr/src/cmd/ptools/ppriv/ppriv.c21
-rw-r--r--usr/src/cmd/sh/Makefile9
-rw-r--r--usr/src/cmd/sh/main.c34
-rw-r--r--usr/src/cmd/sh/service.c40
-rw-r--r--usr/src/cmd/sh/sh_policy.c198
-rw-r--r--usr/src/cmd/sh/sh_policy.h65
-rw-r--r--usr/src/cmd/svc/configd/rc_node.c128
-rw-r--r--usr/src/cmd/truss/actions.c5
-rw-r--r--usr/src/cmd/truss/main.c48
-rw-r--r--usr/src/cmd/truss/print.c4
-rw-r--r--usr/src/cmd/truss/proto.h5
-rw-r--r--usr/src/cmd/truss/ramdata.c4
-rw-r--r--usr/src/cmd/truss/ramdata.h4
30 files changed, 1113 insertions, 1498 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 333c49f8e4..23dbcf9156 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -292,6 +292,7 @@ COMMON_SUBDIRS= \
pcidr \
pcitool \
pfexec \
+ pfexecd \
pgrep \
picl \
plimit \
diff --git a/usr/src/cmd/auditrecord/audit_record_attr.txt b/usr/src/cmd/auditrecord/audit_record_attr.txt
index c9fd667ba2..24dd6b5791 100644
--- a/usr/src/cmd/auditrecord/audit_record_attr.txt
+++ b/usr/src/cmd/auditrecord/audit_record_attr.txt
@@ -2,8 +2,7 @@
# Two "#" are comments that are copied to audit_record_attr
# other comments are removed.
##
-## Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-## Use is subject to license terms.
+## Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
##
## CDDL HEADER START
##
@@ -705,6 +704,14 @@ label=AUE_EXECVE
# return,failure: No such file or directory,-1
# trailer,86
+label=AUE_PFEXEC
+ format=path1:path2:[privileges]3:[privileges]3:[proc]4:exec_args:[exec_env]5
+ comment=pathname of the executable:
+ comment=pathname of working directory:
+ comment=privileges if the limit or inheritable set are changed:
+ comment=process if ruid, euid, rgid or egid is changed:
+ comment=output if arge policy is set
+
label=AUE_EXIT
format=arg1:[text]2
comment=1, exit status, "exit status":
diff --git a/usr/src/cmd/auths/auths.c b/usr/src/cmd/auths/auths.c
index 82416e0017..98141feb88 100644
--- a/usr/src/cmd/auths/auths.c
+++ b/usr/src/cmd/auths/auths.c
@@ -19,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -37,10 +34,6 @@
#include <prof_attr.h>
#include <auth_attr.h>
-
-#define ALL_AUTHS "All"
-#define ALL_SUN_AUTHS "solaris.*"
-
#define EXIT_OK 0
#define EXIT_FATAL 1
#define EXIT_NON_FATAL 2
@@ -49,71 +42,57 @@
#define TEXT_DOMAIN "SYS_TEST"
#endif
-#define PROFLIST_SEP ","
-#define AUTH_SEP ","
-#define MAXAUTHS 4096
+#define INCRAUTHS 512
+typedef struct cbs {
+ int auth_cnt;
+ int auth_max;
+ char **auths;
+} cbs_t;
-static int show_auths(char *, char **, int, int);
-static int list_auths(userattr_t *, char **, int *);
-static void get_default_auths(char *, char **, int *);
-static void getProfiles(char *, char **, int *, char **, int *);
-static void add_auths(char *, char **, int *);
-static void free_auths(char **, int *);
+static int show_auths(char *, int);
+static int add_auth(const char *, void *, void *);
+static void free_auths(cbs_t *);
+static void simplify(cbs_t *);
static char *progname = "auths";
-
int
main(int argc, char *argv[])
{
int status = EXIT_OK;
- char *defauths[MAXAUTHS];
- int defauth_cnt = 0;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
switch (argc) {
case 1:
- get_default_auths(NULL, defauths, &defauth_cnt);
- status = show_auths(NULL, defauths, defauth_cnt, 0);
+ status = show_auths(NULL, 0);
break;
case 2:
- get_default_auths(argv[argc-1], defauths, &defauth_cnt);
- status = show_auths(argv[argc-1], defauths, defauth_cnt, 0);
+ status = show_auths(argv[argc-1], 0);
break;
default:
while (*++argv) {
- get_default_auths(*argv, defauths, &defauth_cnt);
- status = show_auths(*argv, defauths, defauth_cnt, 1);
+ status = show_auths(*argv, 1);
if (status == EXIT_FATAL) {
break;
}
- /* free memory allocated for default authorizations */
- free_auths(defauths, &defauth_cnt);
- (void) printf("\n");
}
break;
}
- /* free memory allocated for default authorizations */
- free_auths(defauths, &defauth_cnt);
status = (status == EXIT_OK) ? status : EXIT_FATAL;
-
return (status);
}
-
static int
-show_auths(char *username, char **defauths, int defauth_cnt, int print_name)
+show_auths(char *username, int print_name)
{
int status = EXIT_OK;
struct passwd *pw;
- userattr_t *user;
- char *userauths[MAXAUTHS];
- int userauth_cnt = 0, old_userauth_cnt;
- int i, j, have_allauths, duplicate;
+ int i;
+ cbs_t cbs = { 0, 0, NULL };
if (username == NULL) {
if ((pw = getpwuid(getuid())) == NULL) {
@@ -130,221 +109,120 @@ show_auths(char *username, char **defauths, int defauth_cnt, int print_name)
return (status);
}
- have_allauths = 0;
- if (username != NULL) {
- /* if ALL_AUTHS is default, don't need to look at other auths */
- for (i = 0; i < defauth_cnt; i++) {
- if (strcmp(defauths[i], ALL_AUTHS) == 0) {
- have_allauths = 1;
- break;
- }
- }
- if (have_allauths) {
- status = EXIT_OK;
- } else if ((user = getusernam(username)) != NULL) {
- status = list_auths(user, userauths, &userauth_cnt);
- /* check if any profiles have ALL_AUTHS */
- for (i = 0; i < userauth_cnt; i++) {
- if (strcmp(userauths[i], ALL_AUTHS) == 0) {
- have_allauths = 1;
- break;
- }
- }
- }
- if ((defauth_cnt + userauth_cnt) == 0) {
- status = EXIT_NON_FATAL;
- }
- }
+ (void) _enum_auths(username, add_auth, NULL, &cbs);
+
+ if (cbs.auth_cnt == 0)
+ status = EXIT_NON_FATAL;
+
if (status == EXIT_NON_FATAL) {
- (void) fprintf(stderr, "%s: %s : ", progname, username);
+ (void) fprintf(stderr, "%s: %s: ", progname, username);
(void) fprintf(stderr, gettext("No authorizations\n"));
} else {
- if (print_name) {
- (void) printf("%s : ", username);
- }
-
- if (have_allauths) {
- (void) printf("%s\n", ALL_SUN_AUTHS);
- } else {
- /*
- * combine the user auths and default auths,
- * and eliminate duplicates from the two
- */
- old_userauth_cnt = userauth_cnt;
- for (i = 0; i < defauth_cnt; i++) {
- duplicate = 0;
- for (j = 0; j < old_userauth_cnt; j++) {
- if (strcmp(userauths[j], defauths[i]) ==
- 0) {
- duplicate = 1;
- break;
- }
- }
- if (!duplicate) {
- userauths[userauth_cnt] =
- strdup(defauths[i]);
- userauth_cnt++;
- }
- }
-
- /* print out the auths */
- for (i = 0; i < (userauth_cnt - 1); i++) {
- (void) printf("%s,", userauths[i]);
- }
-
- /* print out the last entry, without the comma */
- (void) printf("%s\n", userauths[userauth_cnt - 1]);
- }
- }
+ simplify(&cbs);
- /* free memory allocated for authorizations */
- free_auths(userauths, &userauth_cnt);
+ if (print_name)
+ (void) printf("%s: ", username);
- return (status);
-}
+ /* print out the auths */
+ for (i = 0; i < cbs.auth_cnt - 1; i++)
+ (void) printf("%s,", cbs.auths[i]);
+ /* print out the last entry, without the comma */
+ (void) printf("%s\n", cbs.auths[cbs.auth_cnt - 1]);
-static int
-list_auths(userattr_t *user, char **authArray, int *authcnt)
-{
- int status = EXIT_OK;
- char *authlist = NULL;
- char *proflist = NULL;
- char *profArray[MAXPROFS];
- int profcnt = 0;
-
- authlist = kva_match(user->attr, USERATTR_AUTHS_KW);
- if (authlist != NULL) {
- add_auths(authlist, authArray, authcnt);
- }
- if ((proflist = kva_match(user->attr, USERATTR_PROFILES_KW)) == NULL) {
- if (authcnt == 0) {
- status = EXIT_NON_FATAL;
- }
- } else {
- getProfiles(proflist, profArray, &profcnt,
- authArray, authcnt);
- free_proflist(profArray, profcnt);
+ /* free memory allocated for authorizations */
+ free_auths(&cbs);
}
- if (authcnt == 0) {
- status = EXIT_NON_FATAL;
- }
- free_userattr(user);
return (status);
}
-
-static void
-get_default_auths(char *user, char **authArray, int *authcnt)
+/*ARGSUSED*/
+static int
+add_auth(const char *authname, void *ctxt, void *res)
{
- char *auths = NULL;
- char *profs = NULL;
- char *profArray[MAXPROFS];
- int profcnt = 0;
+ cbs_t *cbs = res;
- if (user == NULL) {
- struct passwd *pw;
+ if (cbs->auth_cnt >= cbs->auth_max) {
+ cbs->auth_max += INCRAUTHS;
+ cbs->auths = realloc(cbs->auths,
+ cbs->auth_max * sizeof (char *));
- if ((pw = getpwuid(getuid())) != NULL) {
- user = pw->pw_name;
+ if (cbs->auths == NULL) {
+ (void) fprintf(stderr, "%s: ", progname);
+ (void) fprintf(stderr, gettext("Out of memory\n"));
+ exit(1);
}
}
- if (_get_user_defs(user, &auths, &profs) == 0) {
- if (auths != NULL) {
- add_auths(auths, authArray, authcnt);
- }
+ cbs->auths[cbs->auth_cnt] = strdup(authname);
+ cbs->auth_cnt++;
- /* get authorizations from default profiles */
- if (profs != NULL) {
- getProfiles(profs, profArray, &profcnt,
- authArray, authcnt);
- free_proflist(profArray, profcnt);
- }
- _free_user_defs(auths, profs);
- }
+ return (0);
}
-void
-add_auths(char *auths, char **authArray, int *authcnt)
+static void
+free_auths(cbs_t *cbs)
{
- char *authname, *lasts, *real_authname;
- int i;
+ int i;
- for (authname = (char *)strtok_r(auths, AUTH_SEP, &lasts);
- authname != NULL;
- authname = (char *)strtok_r(NULL, AUTH_SEP, &lasts)) {
+ for (i = 0; i < cbs->auth_cnt; i++)
+ free(cbs->auths[i]);
- if ((strcmp(authname, KV_WILDCARD) == 0) ||
- (strcmp(authname, ALL_SUN_AUTHS) == 0)) {
- real_authname = ALL_AUTHS;
- } else {
- real_authname = authname;
- }
+ free(cbs->auths);
+}
- /* check to see if authorization is already in list */
- for (i = 0; i < *authcnt; i++) {
- if (strcmp(real_authname, authArray[i]) == 0) {
- break; /* already in list */
- }
- }
+/* We have always ignored .grant in auths(1) */
+static boolean_t
+auth_match(const char *pattern, const char *auth)
+{
+ size_t len = strlen(pattern);
- /* not in list, add it in */
- if (i == *authcnt) {
- authArray[i] = strdup(real_authname);
- *authcnt = i + 1;
- }
- }
+ if (pattern[len - 1] != KV_WILDCHAR)
+ return (B_FALSE);
+ return (strncmp(pattern, auth, len - 1) == 0);
}
-static void
-free_auths(char *auths[], int *auth_cnt)
+static int
+mstrptr(const void *a, const void *b)
{
- int i;
+ char *const *ap = a;
+ char *const *bp = b;
- for (i = 0; i < *auth_cnt; i++) {
- free(auths[i]);
- }
- *auth_cnt = 0;
+ return (strcmp(*ap, *bp));
}
+/*
+ * Simplify the returned authorizations: sort and match wildcards;
+ * we're using here that "*" sorts before any other character.
+ */
static void
-getProfiles(char *profiles, char **profArray, int *profcnt,
- char **authArray, int *authcnt)
+simplify(cbs_t *cbs)
{
-
- char *prof;
- char *lasts;
- profattr_t *pa;
- char *auths;
- int i;
-
- for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts);
- prof != NULL;
- prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) {
-
- getproflist(prof, profArray, profcnt);
- }
-
- /* get authorizations from list of profiles */
- for (i = 0; i < *profcnt; i++) {
-
- if ((pa = getprofnam(profArray[i])) == NULL) {
- /*
- * this should never happen.
- * unless the database has an undefined profile
- */
- continue;
- }
-
- /* get auths this profile */
- auths = kva_match(pa->attr, PROFATTR_AUTHS_KW);
- if (auths != NULL) {
- add_auths(auths, authArray, authcnt);
+ int rem, i;
+
+ /* First we sort */
+ qsort(cbs->auths, cbs->auth_cnt, sizeof (cbs->auths[0]), mstrptr);
+
+ /*
+ * Then we remove the entries which match a later entry.
+ * We walk the list, with "i + rem + 1" the cursor for the possible
+ * candidate for removal. With "rem" we count the removed entries
+ * and we copy while we're looking for duplicate/superfluous entries.
+ */
+ for (i = 0, rem = 0; i < cbs->auth_cnt - rem - 1; ) {
+ if (strcmp(cbs->auths[i], cbs->auths[i + rem + 1]) == 0 ||
+ strchr(cbs->auths[i], KV_WILDCHAR) != NULL &&
+ auth_match(cbs->auths[i], cbs->auths[i + rem + 1])) {
+ free(cbs->auths[i + rem + 1]);
+ rem++;
+ } else {
+ i++;
+ if (rem > 0)
+ cbs->auths[i] = cbs->auths[i + rem];
}
-
- free_profattr(pa);
}
+
+ cbs->auth_cnt -= rem;
}
diff --git a/usr/src/cmd/csh/i386/Makefile b/usr/src/cmd/csh/i386/Makefile
index c580f9f0b4..36ee788fc0 100644
--- a/usr/src/cmd/csh/i386/Makefile
+++ b/usr/src/cmd/csh/i386/Makefile
@@ -1,5 +1,4 @@
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
#
# Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
# All Rights Reserved
@@ -8,8 +7,6 @@
# All rights reserved. The Berkeley Software License Agreement
# specifies the terms and conditions for redistribution.
-# ident "%Z%%M% %I% %E% SMI"
-
#
# C Shell with process control; VM/UNIX VAX Makefile
# Bill Joy UC Berkeley; Jim Kulp IIASA, Austria
@@ -17,8 +14,6 @@
CSH_PROG = csh
PROG = $(CSH_PROG)
-PFCSH_PROG= pfcsh
-ROOTPFCSH= $(ROOTBIN)/$(PFCSH_PROG)
include ../../Makefile.cmd
@@ -27,13 +22,11 @@ DEFS = -DVFORK -DFILEC -DBSD_COMP -DFIVE # No TELL when MBCHAR
CPPFLAGS= -I. $(DEFS) $(MBCHAR) $(CPPFLAGS.master)
CPPFLAGS += -I../../sh
CPPFLAGS += -D_FILE_OFFSET_BITS=64
-LDLIBS += -lcurses -lsecdb
+LDLIBS += -lcurses
MAPFILES = ../mapfile-intf $(MAPFILE.NGB)
LDFLAGS += $(MAPFILES:%=-M%)
-PFOBJS = sh_policy.o
-
HDDEP = sh.o sh.dir.o sh.dol.o sh.err.o sh.exec.o sh.exp.o sh.file.o \
sh.func.o sh.glob.o sh.hist.o sh.init.o sh.lex.o sh.misc.o \
sh.parse.o sh.proc.o sh.sem.o sh.set.o sh.time.o
@@ -42,12 +35,11 @@ COMMONOBJS= printf.o sh.char.o sh.dir.o sh.dol.o sh.err.o \
sh.exec.o sh.exp.o sh.file.o sh.func.o sh.glob.o sh.hist.o sh.init.o \
sh.lex.o sh.misc.o sh.parse.o sh.print.o sh.proc.o sh.sem.o sh.set.o \
sh.time.o sh.tchar.o sh.tconst.o sh.o \
- wait3.o
+ wait3.o
LOCALOBJS= signal.o
COMMONSRCS= $(COMMONOBJS:%.o=../%.c)
-PFSRCS= $(PFOBJS:%=pfcsh_objs/%)
.KEEP_STATE:
@@ -64,23 +56,19 @@ all: $(PROG)
$(COMPILE.c) $<
$(POST_PROCESS_O)
-$(CSH_PROG): $(COMMONOBJS) $(PFOBJS) $(LOCALOBJS) $(MAPFILES)
- $(LINK.c) $(COMMONOBJS) $(PFOBJS) $(LOCALOBJS) -o $@ $(LDLIBS)
+$(CSH_PROG): $(COMMONOBJS) $(LOCALOBJS) $(MAPFILES)
+ $(LINK.c) $(COMMONOBJS) $(LOCALOBJS) -o $@ $(LDLIBS)
$(POST_PROCESS)
-$(ROOTPFCSH): $(ROOTPROG)
- $(RM) $@
- $(LN) $(ROOTPROG) $@
-
$(HDDEP): ../sh.tconst.h
-install: all $(ROOTBINPROG) $(ROOTPROG) $(ROOTPFCSH)
+install: all $(ROOTBINPROG) $(ROOTPROG)
lint: ../sh.tconst.h
- $(LINT.c) $(COMMONSRCS) $(PFSRCS) signal.c
+ $(LINT.c) $(COMMONSRCS) signal.c $(LDLIBS)
clean:
- $(RM) $(LOCALOBJS) $(COMMONOBJS) $(PFOBJS)
+ $(RM) $(LOCALOBJS) $(COMMONOBJS)
clobber: clean
$(RM) $(PROG)
diff --git a/usr/src/cmd/csh/sh.c b/usr/src/cmd/csh/sh.c
index da000b4c14..631a75d39d 100644
--- a/usr/src/cmd/csh/sh.c
+++ b/usr/src/cmd/csh/sh.c
@@ -1,6 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -12,8 +11,6 @@
* specifies the terms and conditions for redistribution.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <locale.h>
#include "sh.h"
/* #include <sys/ioctl.h> */
@@ -22,7 +19,6 @@
#include "sh.tconst.h"
#include <pwd.h>
#include <stdlib.h>
-#include "sh_policy.h" /* for pfcsh */
#ifdef TRACE
#include <stdio.h>
#endif
@@ -38,7 +34,8 @@
tchar *pathlist[] = { S_usrbin /* "/usr/bin" */, S_DOT /* "." */, 0 };
tchar *dumphist[] = { S_history /* "history" */, S_h /* "-h" */, 0, 0 };
-tchar *loadhist[] = { S_source /* "source" */, S_h /* "-h" */, S_NDOThistory /* "~/.history" */, 0 };
+tchar *loadhist[] = { S_source /* "source" */, S_h /* "-h" */,
+ S_NDOThistory /* "~/.history" */, 0 };
tchar HIST = '!';
tchar HISTSUB = '^';
int nofile;
@@ -76,7 +73,6 @@ void initdesc(int, char *[]);
void initdesc_x(int, char *[], int);
void closem(void);
void unsetfd(int);
-void secpolicy_print(int, const char *);
void phup(void);
#ifdef TRACE
@@ -119,7 +115,7 @@ tprintf(fmt, a, b, c, d, e, f, g, h, i, j)
int
main(int c, char **av)
{
- tchar **v, *cp, *p, *q, *r;
+ tchar **v, *cp, *r;
int f;
struct sigvec osv;
struct sigaction sa;
@@ -127,8 +123,6 @@ main(int c, char **av)
char *c_max_var_len;
int c_max_var_len_size;
- pfcshflag = 0;
-
/*
* set up the error exit, if there is an error before
* this is done, it will core dump, and we don't
@@ -153,29 +147,6 @@ main(int c, char **av)
#endif
(void) textdomain(TEXT_DOMAIN);
- /*
- * This is a profile shell if the simple name of argv[0] is
- * pfcsh or -pfcsh
- */
- p = strtots(NOSTR, "pfcsh");
- r = strtots(NOSTR, "-pfcsh");
- if ((p != NOSTR) && (r != NOSTR) &&
- ((q = strtots(NOSTR, *av)) != NOSTR)) {
- if (c > 0 && (eq(p, simple(q)) || eq(r, simple(q)))) {
- pfcshflag = 1;
- }
- xfree(q);
- }
-
- if (p != NOSTR)
- xfree(p);
- if (r != NOSTR)
- xfree(r);
-
- if (pfcshflag == 1) {
- secpolicy_init();
- }
-
/* Copy arguments */
v = strblktotsblk(av, c);
@@ -250,8 +221,7 @@ main(int c, char **av)
if (pw != NULL) {
set(S_user, strtots((tchar *)0, pw->pw_name));
local_setenv(S_USER, strtots((tchar *)0, pw->pw_name));
- }
- else if (loginsh) { /* Give up setting USER variable. */
+ } else if (loginsh) { /* Give up setting USER variable. */
printf("Warning: USER environment variable could not be set.\n");
}
}
@@ -428,7 +398,8 @@ main(int c, char **av)
*/
if (prompt) {
gethostname_(s_prompt, MAXHOSTNAMELEN);
- strcat_(s_prompt, uid == 0 ? S_SHARPSP /* "# " */ : S_PERSENTSP /* "% " */);
+ strcat_(s_prompt,
+ uid == 0 ? S_SHARPSP /* "# " */ : S_PERSENTSP /* "% " */);
set(S_prompt /* "prompt" */, s_prompt);
}
@@ -478,7 +449,8 @@ retry:
if (ioctl(f, TIOCGPGRP, (char *)&tpgrp) == 0 &&
tpgrp != -1) {
if (tpgrp != shpgrp) {
- void (*old)() = (void (*)())signal(SIGTTIN, SIG_DFL);
+ void (*old)() = (void (*)())
+ signal(SIGTTIN, SIG_DFL);
(void) kill(0, SIGTTIN);
(void) signal(SIGTTIN, old);
goto retry;
@@ -530,7 +502,8 @@ printf("Warning: no access to tty; thus no job control in this shell...\n");
}
/* Will have value("home") here because set fast if don't */
- srccat(value(S_home /* "home" */), S_SLADOTcshrc /* "/.cshrc" */);
+ srccat(value(S_home /* "home" */),
+ S_SLADOTcshrc /* "/.cshrc" */);
/* Hash path */
if (!fast && !arginp && !onelflg && !havhash)
@@ -543,7 +516,8 @@ printf("Warning: no access to tty; thus no job control in this shell...\n");
*/
dosource(loadhist);
if (loginsh) {
- srccat_inlogin(value(S_home /* "home" */), S_SLADOTlogin /* "/.login" */);
+ srccat_inlogin(value(S_home /* "home" */),
+ S_SLADOTlogin /* "/.login" */);
}
/*
@@ -726,7 +700,7 @@ srcunit(int unit, bool onlyown, bool hflg)
reenter++;
if (reenter == 1) {
/* Setup the new values of the state stuff saved above */
- copy((char *)&saveB, (char *)&B, sizeof saveB);
+ copy((char *)&saveB, (char *)&B, sizeof (saveB));
fbuf = (tchar **) 0;
fseekp = feobp = fblocks = 0;
oSHIN = SHIN, SHIN = unit, arginp = 0, onelflg = 0;
@@ -758,7 +732,7 @@ srcunit(int unit, bool onlyown, bool hflg)
xfree((char *)fbuf);
/* Reset input arena */
- copy((char *)&B, (char *)&saveB, sizeof B);
+ copy((char *)&B, (char *)&saveB, sizeof (B));
(void) close(SHIN), SHIN = oSHIN;
unsetfd(SHIN);
@@ -819,7 +793,8 @@ goodbye(void)
(void) signal(SIGTERM, SIG_IGN);
setintr = 0; /* No interrupts after "logout" */
if (adrof(S_home /* "home" */))
- srccat(value(S_home /* "home" */), S_SLADOTlogout /* "/.logout" */);
+ srccat(value(S_home /* "home" */),
+ S_SLADOTlogout /* "/.logout" */);
}
rechist();
exitstat();
@@ -1215,7 +1190,7 @@ tchar **
strblktotsblk(char **v, int num)
{
tchar **newv =
- (tchar **)xcalloc((unsigned)(num+ 1), sizeof (tchar **));
+ (tchar **)xcalloc((unsigned)(num+ 1), sizeof (tchar **));
tchar **onewv = newv;
while (*v && num--)
@@ -1332,15 +1307,15 @@ initdesc_x(int argc, char *argv[], int is_reinit)
* in the form /dev/fd/X.
*/
if (argc >= 3)
- if (sscanf(argv[2], "/dev/fd/%d", &script_fd) != 1)
- script_fd = -1;
- else
- fcntl(script_fd, F_SETFD, 1); /* Make sure to close
- * this file on exec.
- */
+ if (sscanf(argv[2], "/dev/fd/%d", &script_fd) != 1)
+ script_fd = -1;
+ else
+ /* Make sure to close this file on exec. */
+ fcntl(script_fd, F_SETFD, 1);
if (fdinuse == NULL) {
- nbytesused = sizeof (int) * howmany(NoFile, sizeof (int) * NBBY);
+ nbytesused = sizeof (int) *
+ howmany(NoFile, sizeof (int) * NBBY);
fdinuse = (int *)xalloc(nbytesused);
}
@@ -1474,22 +1449,3 @@ unsetfd(int fd)
max_fd = 0;
}
}
-
-/*
- * A generic call back routine to output error messages from the
- * policy backing functions called by pfcsh.
- */
-void
-secpolicy_print(int level, const char *msg)
-{
- switch (level) {
- case SECPOLICY_WARN:
- default:
- haderr = 1;
- printf("%s: ", msg); /* printf() does gettext() */
- break;
- case SECPOLICY_ERROR:
- bferr((char *)msg); /* bferr() does gettext() */
- break;
- }
-}
diff --git a/usr/src/cmd/csh/sh.exec.c b/usr/src/cmd/csh/sh.exec.c
index e80bfec8dc..eee2d16440 100644
--- a/usr/src/cmd/csh/sh.exec.c
+++ b/usr/src/cmd/csh/sh.exec.c
@@ -1,6 +1,5 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -12,13 +11,10 @@
* specifies the terms and conditions for redistribution.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "sh.h"
#include <dirent.h>
#include <string.h>
#include "sh.tconst.h"
-#include "sh_policy.h"
/*
@@ -123,7 +119,8 @@ doexec(struct command *t)
pv = justabs;
else
pv = v->vec;
- sav = strspl(S_SLASH /* "/" */, *av); /* / command name for postpending */
+ /* / command name for postpending */
+ sav = strspl(S_SLASH /* "/" */, *av);
#ifdef VFORK
Vsav = sav;
#endif
@@ -140,7 +137,8 @@ doexec(struct command *t)
goto cont;
}
- if (pv[0][0] == 0 || eq(pv[0], S_DOT /* "." */)) { /* don't make ./xxx */
+ /* don't make ./xxx */
+ if (pv[0][0] == 0 || eq(pv[0], S_DOT /* "." */)) {
texec(t, *av, av);
} else {
dp = strspl(*pv, sav);
@@ -193,7 +191,6 @@ pexerr(void)
void
texec(struct command *cmd, tchar *f, tchar **t)
{
- int pfstatus = 0;
struct varent *v;
tchar **vp;
tchar *lastsh[2];
@@ -204,16 +201,7 @@ texec(struct command *cmd, tchar *f, tchar **t)
/* convert cfname and cargs from tchar to char */
tconvert(cmd, f, t);
- if (pfcshflag == 1) {
- pfstatus = secpolicy_pfexec((const char *)(cmd->cfname),
- cmd->cargs, (const char **)NULL);
- if (pfstatus != NOATTRS) {
- errno = pfstatus;
- }
- }
- if ((pfcshflag == 0) || (pfstatus == NOATTRS)) {
- execv(cmd->cfname, cmd->cargs);
- }
+ execv(cmd->cfname, cmd->cargs);
/*
* exec returned, free up allocations from above
@@ -257,7 +245,9 @@ texec(struct command *cmd, tchar *f, tchar **t)
#endif
vp = lastsh;
- vp[0] = adrof(S_shell /* "shell" */) ? value(S_shell /* "shell" */) : S_SHELLPATH /* SHELLPATH */;
+ vp[0] = adrof(S_shell /* "shell" */) ?
+ value(S_shell /* "shell" */) :
+ S_SHELLPATH /* SHELLPATH */;
vp[1] = (tchar *) NULL;
#ifdef OTHERSH
if (ff != -1 && read_(ff, ch, 1) == 1 && ch[0] != '#')
@@ -314,7 +304,7 @@ tconvert(struct command *cmd, tchar *fname, tchar **list)
len = blklen(list);
rc = cmd->cargs = (char **)
- xcalloc((uint_t)(len + 1), sizeof (char **));
+ xcalloc((uint_t)(len + 1), sizeof (char **));
while (len--)
*rc++ = tstostr(NULL, *list++);
*rc = NULL;
@@ -399,9 +389,7 @@ dohash(char cachearray[])
for (cnt = 0; cnt < (HSHSIZ / 8); cnt++)
cachearray[cnt] = 0;
if (v == 0)
- {
return;
- }
for (pv = v->vec; *pv; pv++, i++) {
if (pv[0][0] != '/')
continue;
@@ -420,7 +408,8 @@ dohash(char cachearray[])
(dp->d_name[1] == '\0' ||
dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
continue;
- hashval = hash(hashname(strtots(curdir_, dp->d_name)), i);
+ hashval = hash(hashname(strtots(curdir_, dp->d_name)),
+ i);
bis(cachearray, hashval);
}
unsetfd(dirp->dd_fd);
@@ -449,7 +438,7 @@ hashstat(void)
if (hits+misses)
printf("%d hits, %d misses, %d%%\n",
- hits, misses, 100 * hits / (hits + misses));
+ hits, misses, 100 * hits / (hits + misses));
}
#endif
diff --git a/usr/src/cmd/csh/sparc/Makefile b/usr/src/cmd/csh/sparc/Makefile
index 8a5bf81e4c..37c536f83e 100644
--- a/usr/src/cmd/csh/sparc/Makefile
+++ b/usr/src/cmd/csh/sparc/Makefile
@@ -1,5 +1,4 @@
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
# All Rights Reserved
@@ -8,8 +7,6 @@
# All rights reserved. The Berkeley Software License Agreement
# specifies the terms and conditions for redistribution.
-# ident "%Z%%M% %I% %E% SMI"
-
#
# C Shell with process control; VM/UNIX VAX Makefile
# Bill Joy UC Berkeley; Jim Kulp IIASA, Austria
@@ -17,8 +14,6 @@
CSH_PROG = csh
PROG = $(CSH_PROG)
-PFCSH_PROG= pfcsh
-ROOTPFCSH= $(ROOTBIN)/$(PFCSH_PROG)
include ../../Makefile.cmd
@@ -27,7 +22,7 @@ DEFS = -DVFORK -DFILEC -DBSD_COMP -DFIVE # No TELL when MBCHAR
CPPFLAGS= -I. $(DEFS) $(MBCHAR) $(CPPFLAGS.master)
CPPFLAGS += -I../../sh
CPPFLAGS += -D_FILE_OFFSET_BITS=64
-LDLIBS += -lcurses -lsecdb
+LDLIBS += -lcurses
MAPFILES = ../mapfile-intf $(MAPFILE.NGB)
LDFLAGS += $(MAPFILES:%=-M%)
@@ -42,12 +37,11 @@ COMMONOBJS= printf.o sh.char.o sh.dir.o sh.dol.o sh.err.o \
sh.exec.o sh.exp.o sh.file.o sh.func.o sh.glob.o sh.hist.o sh.init.o \
sh.lex.o sh.misc.o sh.parse.o sh.print.o sh.proc.o sh.sem.o sh.set.o \
sh.time.o sh.tchar.o sh.tconst.o sh.o \
- wait3.o
+ wait3.o
LOCALOBJS= signal.o
COMMONSRCS= $(COMMONOBJS:%.o=../%.c)
-PFSRCS= ../../sh/sh_policy.c
.KEEP_STATE:
@@ -64,23 +58,19 @@ all: $(PROG)
$(COMPILE.c) $<
$(POST_PROCESS_O)
-$(CSH_PROG): $(COMMONOBJS) $(PFOBJS) $(LOCALOBJS) $(MAPFILES)
- $(LINK.c) $(COMMONOBJS) $(PFOBJS) $(LOCALOBJS) -o $@ $(LDLIBS)
+$(CSH_PROG): $(COMMONOBJS) $(LOCALOBJS) $(MAPFILES)
+ $(LINK.c) $(COMMONOBJS) $(LOCALOBJS) -o $@ $(LDLIBS)
$(POST_PROCESS)
-$(ROOTPFCSH): $(ROOTPROG)
- $(RM) $@
- $(LN) $(ROOTPROG) $@
-
$(HDDEP): ../sh.tconst.h
-install: all $(ROOTBINPROG) $(ROOTPROG) $(ROOTPFCSH)
+install: all $(ROOTBINPROG) $(ROOTPROG)
lint: ../sh.tconst.h
- $(LINT.c) $(COMMONSRCS) $(PFSRCS) signal.c $(LDLIBS)
+ $(LINT.c) $(COMMONSRCS) signal.c $(LDLIBS)
clean:
- $(RM) $(LOCALOBJS) $(COMMONOBJS) $(PFOBJS)
+ $(RM) $(LOCALOBJS) $(COMMONOBJS)
clobber: clean
$(RM) $(PROG)
diff --git a/usr/src/cmd/fs.d/ufs/newfs/newfs.c b/usr/src/cmd/fs.d/ufs/newfs/newfs.c
index d517971873..a59b8584f1 100644
--- a/usr/src/cmd/fs.d/ufs/newfs/newfs.c
+++ b/usr/src/cmd/fs.d/ufs/newfs/newfs.c
@@ -22,8 +22,7 @@
/*
* newfs: friendly front end to mkfs
*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/param.h>
@@ -622,7 +621,7 @@ main(int argc, char *argv[])
* If alternates-per-cylinder is ever implemented:
* need to get apc from dp->d_apc if no -a switch???
*/
- (void) snprintf(cmd, sizeof (cmd), "pfexec mkfs -F ufs "
+ (void) snprintf(cmd, sizeof (cmd), "mkfs -F ufs "
"%s%s%s%s %lld %d %d %d %d %d %d %d %d %s %d %d %d %d %s",
Nflag ? "-o N " : "", binary_sb ? "-o calcbinsb " : "",
text_sb ? "-o calcsb " : "", special,
diff --git a/usr/src/cmd/ksh/Makefile b/usr/src/cmd/ksh/Makefile
index bc4e80bd43..a2eb19cde9 100644
--- a/usr/src/cmd/ksh/Makefile
+++ b/usr/src/cmd/ksh/Makefile
@@ -20,16 +20,14 @@
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
SHELL=/usr/bin/ksh93
PROG= ksh
-USRKSH_ALIAS_LIST=ksh ksh93 rksh rksh93 pfksh pfksh93 pfrksh pfrksh93
-
+USRKSH_ALIAS_LIST=ksh ksh93 rksh rksh93
include ../Makefile.cmd
@@ -82,10 +80,6 @@ install: $(ISAEXEC) $(SUBDIRS)
$(SYMLINK) ../usr/bin/ksh93 $(ROOTSBIN)/jsh
$(RM) $(ROOTBIN)/jsh
$(SYMLINK) ksh93 $(ROOTBIN)/jsh
- $(RM) $(ROOTSBIN)/pfsh
- $(SYMLINK) ../usr/bin/ksh93 $(ROOTSBIN)/pfsh
- $(RM) $(ROOTBIN)/pfsh
- $(SYMLINK) ksh93 $(ROOTBIN)/pfsh
$(RM) $(ROOTBIN)/sh
$(SYMLINK) $(ARCH32)/ksh93 $(ROOTBIN)/sh
$(RM) $(ROOTLIB)/rsh
diff --git a/usr/src/cmd/ksh/Makefile.com b/usr/src/cmd/ksh/Makefile.com
index 519ce850fd..75685dfa18 100644
--- a/usr/src/cmd/ksh/Makefile.com
+++ b/usr/src/cmd/ksh/Makefile.com
@@ -20,15 +20,14 @@
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
SHELL=/usr/bin/ksh93
PROG= ksh
-USRKSH_ALIAS_LIST=ksh ksh93 rksh rksh93 pfksh pfksh93 pfrksh pfrksh93
+USRKSH_ALIAS_LIST=ksh ksh93 rksh rksh93
OBJECTS= \
pmain.o
diff --git a/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm b/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm
index 10c6cd02b4..0965ef925e 100644
--- a/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm
+++ b/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm
@@ -19,8 +19,7 @@
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -33,14 +32,15 @@ use warnings;
package Sun::Solaris::Privilege;
-our $VERSION = '1.3';
+our $VERSION = '1.4';
use XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);
our (@EXPORT_OK, %EXPORT_TAGS);
my @constants = qw(PRIV_STR_SHORT PRIV_STR_LIT PRIV_STR_PORT PRIV_ON PRIV_OFF
- PRIV_SET PRIV_AWARE PRIV_AWARE_RESET PRIV_DEBUG);
+ PRIV_SET PRIV_AWARE PRIV_AWARE_RESET PRIV_DEBUG PRIV_PFEXEC
+ PRIV_XPOLICY NET_MAC_AWARE NET_MAC_AWARE_INHERIT __PROC_PROTECT);
my @syscalls = qw(setppriv getppriv setpflags getpflags);
my @libcalls = qw(priv_addset priv_copyset priv_delset
priv_emptyset priv_fillset priv_intersect priv_inverse priv_ineffect
diff --git a/usr/src/cmd/pfexec/Makefile b/usr/src/cmd/pfexec/Makefile
index 4f60f15ddd..08bfd04df6 100644
--- a/usr/src/cmd/pfexec/Makefile
+++ b/usr/src/cmd/pfexec/Makefile
@@ -19,30 +19,38 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
#
PROG= pfexec
SRCS= $(PROG:%=%.c)
PFEXEC= pfexec
+BINSHELLS = bash csh ksh ksh93 rksh rksh93 sh tcsh zsh
+
include ../Makefile.cmd
-FILEMODE = 04555
+FILEMODE = 0555
ROOTBINPFEXEC = $(PFEXEC:%=$(ROOTBIN)/%)
.KEEP_STATE:
-CPPFLAGS += -D_REENTRANT
-LDLIBS += -lsecdb -lbsm
-
all: $(PROG)
install: all $(ROOTBINPFEXEC)
+ for s in $(BINSHELLS); do \
+ $(RM) $(ROOTBIN)/pf$$s; \
+ $(LN) $(ROOTBIN)/pfexec $(ROOTBIN)/pf$$s; \
+ done
+ $(RM) $(ROOTXPG4BIN)/pfsh
+ $(LN) $(ROOTBIN)/pfexec $(ROOTXPG4BIN)/pfsh
+ $(RM) $(ROOTSBIN)/pfsh
+ $(SYMLINK) ../usr/bin/pfexec $(ROOTSBIN)/pfsh
+ $(RM) $(ROOTHASBIN)/pfsh
+ $(LN) $(ROOTBIN)/pfexec $(ROOTHASBIN)/pfsh
+ $(RM) $(ROOTHASBIN)/pfksh
+ $(LN) $(ROOTBIN)/pfexec $(ROOTHASBIN)/pfksh
clean:
diff --git a/usr/src/cmd/pfexec/pfexec.c b/usr/src/cmd/pfexec/pfexec.c
index 206055d431..a0025d26a7 100644
--- a/usr/src/cmd/pfexec/pfexec.c
+++ b/usr/src/cmd/pfexec/pfexec.c
@@ -19,397 +19,68 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
+/*
+ * New implementation of pfexec(1) and all of the profile shells.
+ *
+ * The algorithm is as follows:
+ * first try to derive the shell's path from getexecname();
+ * note that this requires a *hard* link to the program, so
+ * if we find that we are actually executing pfexec, we start
+ * looking at argv[0].
+ * argv[0] is also our fallback in case getexecname doesn't find it.
+ */
+#include <sys/param.h>
+#include <alloca.h>
#include <errno.h>
-#include <deflt.h>
#include <locale.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
+#include <priv.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <grp.h>
#include <string.h>
-#include <exec_attr.h>
-#include <user_attr.h>
-#include <auth_attr.h>
-#include <prof_attr.h>
-#include <errno.h>
-#include <priv.h>
-
-#include <bsm/adt.h>
-#include <bsm/adt_event.h>
+#include <unistd.h>
-#ifndef TEXT_DOMAIN /* Should be defined by cc -D */
+#define PFEXEC "pfexec"
+#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SYS_TEST"
#endif
-extern int cannot_audit(int);
-
-static char *pathsearch(char *);
-static int getrealpath(const char *, char *);
-static int checkattrs(char *, int, char *[]);
-static void sanitize_environ();
-static uid_t get_uid(char *);
-static gid_t get_gid(char *);
-static priv_set_t *get_privset(const char *);
-static priv_set_t *get_granted_privs(uid_t);
-static void get_default_privs(const char *, priv_set_t *);
-static void get_profile_privs(char *, char **, int *, priv_set_t *);
-
-static int isnumber(char *);
-static void usage(void);
-
-extern char **environ;
-
-#define PROFLIST_SEP ","
-
-int
-main(int argc, char *argv[])
-{
- char *cmd;
- char **cmdargs;
- char cmd_realpath[MAXPATHLEN];
- int c;
- char *pset = NULL;
-
- (void) setlocale(LC_ALL, "");
- (void) textdomain(TEXT_DOMAIN);
-
- while ((c = getopt(argc, argv, "P:")) != EOF) {
- switch (c) {
- case 'P':
- if (pset == NULL) {
- pset = optarg;
- break;
- }
- /* FALLTHROUGH */
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc < 1)
- usage();
-
- cmd = argv[0];
- cmdargs = &argv[0];
-
- if (pset != NULL) {
- uid_t uid = getuid();
- priv_set_t *wanted = get_privset(pset);
- priv_set_t *granted;
-
- adt_session_data_t *ah; /* audit session handle */
- adt_event_data_t *event; /* event to be generated */
- char cwd[MAXPATHLEN];
-
- granted = get_granted_privs(uid);
-
- /* Audit use */
- if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
- perror("pfexec: adt_start_session");
- exit(EXIT_FAILURE);
- }
- if ((event = adt_alloc_event(ah, ADT_prof_cmd)) == NULL) {
- perror("pfexec: adt_alloc_event");
- exit(EXIT_FAILURE);
- }
- if ((event->adt_prof_cmd.cwdpath =
- getcwd(cwd, sizeof (cwd))) == NULL) {
- (void) fprintf(stderr,
- gettext("pfexec: can't add cwd path\n"));
- exit(EXIT_FAILURE);
- }
-
- event->adt_prof_cmd.cmdpath = cmd;
- event->adt_prof_cmd.argc = argc - 1;
- event->adt_prof_cmd.argv = &argv[1];
- event->adt_prof_cmd.envp = environ;
-
- if (granted != NULL) {
- priv_intersect(granted, wanted);
- event->adt_prof_cmd.inherit_set = wanted;
- if (adt_put_event(event, ADT_SUCCESS,
- ADT_SUCCESS) != 0) {
- perror("pfexec: adt_put_event");
- exit(EXIT_FAILURE);
- }
- if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) {
- (void) fprintf(stderr,
- gettext("setppriv(): %s\n"),
- strerror(errno));
- exit(EXIT_FAILURE);
- }
- /* Trick exec into thinking we're not suid */
- (void) setppriv(PRIV_ON, PRIV_PERMITTED, wanted);
- priv_freeset(event->adt_prof_cmd.inherit_set);
- } else {
- if (adt_put_event(event, ADT_SUCCESS,
- ADT_SUCCESS) != 0) {
- perror("pfexec: adt_put_event");
- exit(EXIT_FAILURE);
- }
- }
- adt_free_event(event);
- (void) adt_end_session(ah);
- (void) setreuid(uid, uid);
- (void) execvp(cmd, cmdargs);
- (void) fprintf(stderr,
- gettext("pfexec: can't execute %s: %s\n"),
- cmd, strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- if ((cmd = pathsearch(cmd)) == NULL)
- exit(EXIT_FAILURE);
-
- if (getrealpath(cmd, cmd_realpath) == 0)
- exit(EXIT_FAILURE);
-
- if (checkattrs(cmd_realpath, argc, argv) == 0)
- exit(EXIT_FAILURE);
-
- (void) execv(cmd, cmdargs);
- /*
- * We'd be here only if execv fails.
- */
- (void) fprintf(stderr, gettext("pfexec: can't execute %s: %s\n"),
- cmd, strerror(errno));
- exit(EXIT_FAILURE);
-/* LINTED */
-}
-
-
-/*
- * gets realpath for cmd.
- * return 1 on success, 0 on failure.
- */
-static int
-getrealpath(const char *cmd, char *cmd_realpath)
-{
- if (realpath(cmd, cmd_realpath) == NULL) {
- (void) fprintf(stderr,
- gettext("pfexec: can't get real path of ``%s''\n"), cmd);
- return (0);
- }
- return (1);
-}
-
-/*
- * gets execution attributed for cmd, sets uids/gids, checks environ.
- * returns 1 on success, 0 on failure.
- */
-static int
-checkattrs(char *cmd_realpath, int argc, char *argv[])
-{
- char *value;
- uid_t uid, euid;
- gid_t gid = (gid_t)-1;
- gid_t egid = (gid_t)-1;
- struct passwd *pwent;
- execattr_t *exec;
- priv_set_t *lset = NULL;
- priv_set_t *iset = NULL;
-
- adt_session_data_t *ah; /* audit session handle */
- adt_event_data_t *event; /* event to be generated */
- char cwd[MAXPATHLEN];
-
- uid = euid = getuid();
- if ((pwent = getpwuid(uid)) == NULL) {
- (void) fprintf(stderr, "%d: ", (int)uid);
- (void) fprintf(stderr, gettext("can't get passwd entry\n"));
- return (0);
- }
- /* Set up to audit use */
- if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
- perror("pfexec: adt_start_session");
- return (0);
- }
- if ((event = adt_alloc_event(ah, ADT_prof_cmd)) == NULL) {
- perror("pfexec: adt_alloc_event");
- return (0);
- }
- if ((event->adt_prof_cmd.cwdpath = getcwd(cwd, sizeof (cwd))) == NULL) {
- (void) fprintf(stderr, gettext("pfexec: can't add cwd path\n"));
- return (0);
- }
- /*
- * Get the exec attrs: uid, gid, euid and egid
- */
- if ((exec = getexecuser(pwent->pw_name,
- KV_COMMAND, (char *)cmd_realpath, GET_ONE)) == NULL) {
- (void) fprintf(stderr, "%s: ", cmd_realpath);
- (void) fprintf(stderr,
- gettext("can't get execution attributes\n"));
- return (0);
- }
- if ((value = kva_match(exec->attr, EXECATTR_UID_KW)) != NULL) {
- euid = uid = get_uid(value);
- event->adt_prof_cmd.proc_euid = uid;
- event->adt_prof_cmd.proc_ruid = uid;
- }
- if ((value = kva_match(exec->attr, EXECATTR_GID_KW)) != NULL) {
- egid = gid = get_gid(value);
- event->adt_prof_cmd.proc_egid = gid;
- event->adt_prof_cmd.proc_rgid = gid;
- }
- if ((value = kva_match(exec->attr, EXECATTR_EUID_KW)) != NULL) {
- event->adt_prof_cmd.proc_euid = euid = get_uid(value);
- }
- if ((value = kva_match(exec->attr, EXECATTR_EGID_KW)) != NULL) {
- event->adt_prof_cmd.proc_egid = egid = get_gid(value);
- }
- if ((value = kva_match(exec->attr, EXECATTR_LPRIV_KW)) != NULL) {
- lset = get_privset(value);
- event->adt_prof_cmd.limit_set = lset;
- }
- if ((value = kva_match(exec->attr, EXECATTR_IPRIV_KW)) != NULL) {
- iset = get_privset(value);
- event->adt_prof_cmd.inherit_set = iset;
- }
- if (euid == uid || iset != NULL) {
- sanitize_environ();
- }
-
- /* Finish audit info */
- event->adt_prof_cmd.cmdpath = cmd_realpath;
- event->adt_prof_cmd.argc = argc - 1;
- event->adt_prof_cmd.argv = &argv[1];
- event->adt_prof_cmd.envp = environ;
- if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
- perror("pfexec: adt_put_event");
- return (0);
- }
- adt_free_event(event);
- (void) adt_end_session(ah);
-
-set_attrs:
- /*
- * Set gids/uids and privileges.
- *
- */
- if ((gid != (gid_t)-1) || (egid != (gid_t)-1)) {
- if ((setregid(gid, egid) == -1)) {
- (void) fprintf(stderr, "%s: ", cmd_realpath);
- (void) fprintf(stderr, gettext("can't set gid\n"));
- return (0);
- }
- }
- if (lset != NULL && setppriv(PRIV_SET, PRIV_LIMIT, lset) != 0 ||
- iset != NULL && setppriv(PRIV_ON, PRIV_INHERITABLE, iset) != 0) {
- (void) fprintf(stderr, gettext("%s: can't set privileges\n"),
- cmd_realpath);
- return (0);
- }
- if (setreuid(uid, euid) == -1) {
- (void) fprintf(stderr, "%s: ", cmd_realpath);
- (void) fprintf(stderr, gettext("can't set uid\n"));
- return (0);
- }
- if (iset != NULL && getppriv(PRIV_INHERITABLE, iset) == 0)
- (void) setppriv(PRIV_SET, PRIV_PERMITTED, iset);
-
- free_execattr(exec);
-
- return (1);
-}
-
+#define RES_PFEXEC 1
+#define RES_OK 0
+#define RES_FAILURE -1
/*
- * cleans up environ. code from su.c
+ * Return the shellname
*/
-static void
-sanitize_environ()
-{
- char **pp = environ;
- char **qq, *p;
-
- while ((p = *pp) != NULL) {
- if (*p == 'L' && p[1] == 'D' && p[2] == '_') {
- for (qq = pp; (*qq = qq[1]) != NULL; qq++) {
- ;
- }
- } else {
- pp++;
- }
- }
-}
-
-
-static uid_t
-get_uid(char *value)
-{
- struct passwd *passwd_ent;
-
- if ((passwd_ent = getpwnam(value)) != NULL)
- return (passwd_ent->pw_uid);
-
- if (isnumber(value))
- return (atoi(value));
-
- (void) fprintf(stderr, "pfexec: %s: ", value);
- (void) fprintf(stderr, gettext("can't get user entry\n"));
- exit(EXIT_FAILURE);
- /*NOTREACHED*/
-}
-
-
-static uid_t
-get_gid(char *value)
+int
+shellname(const char *name, char buf[MAXPATHLEN])
{
- struct group *group_ent;
+ const char *cmd = strrchr(name, '/');
- if ((group_ent = getgrnam(value)) != NULL)
- return (group_ent->gr_gid);
+ if (cmd == NULL)
+ cmd = name;
+ else
+ cmd++;
- if (isnumber(value))
- return (atoi(value));
+ if (strncmp(cmd, "pf", 2) != 0)
+ return (RES_FAILURE);
- (void) fprintf(stderr, "pfexec: %s: ", value);
- (void) fprintf(stderr, gettext("can't get group entry\n"));
- exit(EXIT_FAILURE);
- /*NOTREACHED*/
-}
+ if (strcmp(cmd, PFEXEC) == 0)
+ return (RES_PFEXEC);
+ if (strlen(name) >= MAXPATHLEN)
+ return (RES_FAILURE);
-static int
-isnumber(char *s)
-{
- int c;
-
- if (*s == '\0')
- return (0);
-
- while ((c = *s++) != '\0') {
- if (!isdigit(c)) {
- return (0);
- }
+ if (cmd == name) {
+ (void) strlcpy(buf, cmd + 2, MAXPATHLEN);
+ } else {
+ (void) strncpy(buf, name, cmd - name);
+ (void) strcpy(buf + (cmd - name), cmd + 2);
}
+ return (RES_OK);
- return (1);
-}
-
-static priv_set_t *
-get_privset(const char *s)
-{
- priv_set_t *res;
-
- if ((res = priv_str_to_set(s, ",", NULL)) == NULL) {
- (void) fprintf(stderr, "%s: bad privilege set\n", s);
- exit(EXIT_FAILURE);
- }
- return (res);
}
static void
@@ -419,171 +90,77 @@ usage(void)
exit(EXIT_FAILURE);
}
-
-/*
- * This routine exists on failure and returns NULL if no granted privileges
- * are set.
- */
-static priv_set_t *
-get_granted_privs(uid_t uid)
-{
- struct passwd *pwent;
- userattr_t *ua;
- char *profs;
- priv_set_t *res;
- char *profArray[MAXPROFS];
- int profcnt = 0;
-
- res = priv_allocset();
- if (res == NULL) {
- perror("priv_allocset");
- exit(EXIT_FAILURE);
- }
-
- priv_emptyset(res);
-
- if ((pwent = getpwuid(uid)) == NULL) {
- (void) fprintf(stderr, "%d: ", (int)uid);
- (void) fprintf(stderr, gettext("can't get passwd entry\n"));
- exit(EXIT_FAILURE);
- }
-
- ua = getusernam(pwent->pw_name);
-
- if (ua != NULL && ua->attr != NULL &&
- (profs = kva_match(ua->attr, USERATTR_PROFILES_KW)) != NULL) {
- get_profile_privs(profs, profArray, &profcnt, res);
- free_proflist(profArray, profcnt);
- }
-
- get_default_privs(pwent->pw_name, res);
-
- if (ua != NULL)
- free_userattr(ua);
-
- return (res);
-}
-
-static void
-get_default_privs(const char *user, priv_set_t *pset)
-{
- char *profs = NULL;
- char *profArray[MAXPROFS];
- int profcnt = 0;
-
- if (_get_user_defs(user, NULL, &profs) == 0) {
- /* get privileges from default profiles */
- if (profs != NULL) {
- get_profile_privs(profs, profArray, &profcnt, pset);
- free_proflist(profArray, profcnt);
- _free_user_defs(NULL, profs);
- }
- }
-}
-
-static void
-get_profile_privs(char *profiles, char **profArray, int *profcnt,
- priv_set_t *pset)
+int
+main(int argc, char **argv)
{
-
- char *prof;
- char *lasts;
- profattr_t *pa;
- char *privs;
- int i;
-
- for (prof = strtok_r(profiles, PROFLIST_SEP, &lasts);
- prof != NULL;
- prof = strtok_r(NULL, PROFLIST_SEP, &lasts))
- getproflist(prof, profArray, profcnt);
-
- /* get the privileges from list of profiles */
- for (i = 0; i < *profcnt; i++) {
-
- if ((pa = getprofnam(profArray[i])) == NULL) {
- /*
- * this should never happen.
- * unless the database has an undefined profile
- */
- continue;
+ char *cmd;
+ char *pset = NULL;
+ char pathbuf[MAXPATHLEN];
+ int c;
+ priv_set_t *wanted;
+ int oflag;
+
+ oflag = getpflags(PRIV_PFEXEC);
+ if (setpflags(PRIV_PFEXEC, 1) != 0) {
+ perror("setpflags(PRIV_PFEXEC)");
+ exit(1);
+ }
+
+ if (*argv[0] == '-')
+ cmd = argv[0] + 1;
+ else
+ cmd = argv[0];
+
+ /* Strip "pf" from argv[0], it confuses some shells. */
+ if (strncmp(cmd, "pf", 2) == 0) {
+ argv[0] += 2;
+ /* argv[0] will need to start with '-' again. */
+ if (argv[0][-2] == '-')
+ *argv[0] = '-';
+ }
+
+ /* If this fails, we just continue with plan B */
+ if (shellname(getexecname(), pathbuf) == RES_OK)
+ (void) execv(pathbuf, argv);
+
+ switch (shellname(cmd, pathbuf)) {
+ case RES_OK:
+ (void) execv(pathbuf, argv);
+ perror(pathbuf);
+ return (1);
+ case RES_PFEXEC:
+ case RES_FAILURE:
+ while ((c = getopt(argc, argv, "P:")) != EOF) {
+ switch (c) {
+ case 'P':
+ if (pset == NULL) {
+ pset = optarg;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ usage();
+ }
}
+ argc -= optind;
+ argv += optind;
+ if (argc < 1)
+ usage();
- /* get privs from this profile */
- privs = kva_match(pa->attr, PROFATTR_PRIVS_KW);
- if (privs != NULL) {
- priv_set_t *tmp = priv_str_to_set(privs, ",", NULL);
- if (tmp != NULL) {
- priv_union(tmp, pset);
- priv_freeset(tmp);
+ if (pset != NULL) {
+ wanted = priv_str_to_set(pset, ",", NULL);
+ if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) {
+ (void) fprintf(stderr,
+ gettext("setppriv(): %s\n"),
+ strerror(errno));
+ exit(EXIT_FAILURE);
}
+ (void) setpflags(PRIV_PFEXEC, oflag);
}
- free_profattr(pa);
- }
-}
-
-/*
- * True if someone (user, group, other) can execute this file.
- */
-#define S_ISEXEC(mode) (((mode)&(S_IXUSR|S_IXGRP|S_IXOTH)) != 0)
-
-/*
- * This function can return either the first argument or dynamically
- * allocated memory. Reuse with care.
- */
-static char *
-pathsearch(char *cmd)
-{
- char *path, *dir, *result;
- char buf[MAXPATHLEN];
- struct stat stbuf;
-
- /*
- * Implement shell like PATH searching; if the pathname contains
- * one or more slashes, don't search the path, even if the '/'
- * isn't the first character. (E.g., ./command or dir/command)
- * No path equals to a search in ".", just like the shell.
- */
- if (strchr(cmd, '/') != NULL)
- return (cmd);
-
- path = getenv("PATH");
- if (path == NULL)
- return (cmd);
-
- /*
- * We need to copy $PATH because our sub processes may need it.
- */
- path = strdup(path);
- if (path == NULL) {
- perror("pfexec: strdup $PATH");
- exit(EXIT_FAILURE);
+ (void) execvp(argv[0], argv);
+ perror(argv[0]);
+ return (1);
}
-
- result = NULL;
- for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) {
- if (snprintf(buf, sizeof (buf), "%s/%s", dir, cmd) >=
- sizeof (buf)) {
- continue;
- }
- if (stat(buf, &stbuf) < 0)
- continue;
- /*
- * Shells typically call access() with E_OK flag
- * to determine if the effective uid can execute
- * the file. We don't know what the eventual euid
- * will be; it is determined by the exec_attr
- * attributes which depend on the full pathname of
- * the command. Therefore, we match the first regular
- * file we find that is executable by someone.
- */
- if (S_ISREG(stbuf.st_mode) && S_ISEXEC(stbuf.st_mode)) {
- result = strdup(buf);
- break;
- }
- }
- free(path);
- if (result == NULL)
- (void) fprintf(stderr, gettext("%s: Command not found\n"), cmd);
- return (result);
+ return (1);
}
diff --git a/usr/src/cmd/pfexecd/Makefile b/usr/src/cmd/pfexecd/Makefile
new file mode 100644
index 0000000000..262bef7054
--- /dev/null
+++ b/usr/src/cmd/pfexecd/Makefile
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Makefile for the pfexec daemon.
+#
+
+PROG= pfexecd
+MANIFEST= pfexecd.xml
+SRCS= $(PROG:%=%.c)
+lint: lint_SRCS
+
+include ../Makefile.cmd
+
+TARGET= all
+
+ROOTMANIFESTDIR= $(ROOTSVCSYSTEM)
+
+LDLIBS += -lsecdb
+
+# install macros and rule
+#
+GROUP= bin
+ROOTPROG= $(ROOTLIB)/$(PROG)
+$(ROOTPROG) := FILEMODE= 555
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all .WAIT $(ROOTPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+clean:
+
+check: $(CHKMANIFEST)
+
+${ROOTLIB}/%: %
+ ${INS.file}
+
+lint: lint_SRCS
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/pfexecd/pfexecd.c b/usr/src/cmd/pfexecd/pfexecd.c
new file mode 100644
index 0000000000..b043c33e9c
--- /dev/null
+++ b/usr/src/cmd/pfexecd/pfexecd.c
@@ -0,0 +1,525 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ */
+
+#define _POSIX_PTHREAD_SEMANTICS 1
+
+#include <sys/param.h>
+#include <sys/klpd.h>
+#include <sys/syscall.h>
+#include <sys/systeminfo.h>
+
+#include <alloca.h>
+#include <ctype.h>
+#include <deflt.h>
+#include <door.h>
+#include <errno.h>
+#include <grp.h>
+#include <priv.h>
+#include <pwd.h>
+#include <regex.h>
+#include <secdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <auth_attr.h>
+#include <exec_attr.h>
+#include <prof_attr.h>
+#include <user_attr.h>
+
+static int doorfd = -1;
+
+static size_t repsz, setsz;
+
+static uid_t get_uid(const char *, boolean_t *, char *);
+static gid_t get_gid(const char *, boolean_t *, char *);
+static priv_set_t *get_privset(const char *, boolean_t *, char *);
+static priv_set_t *get_granted_privs(uid_t);
+
+/*
+ * Remove the isaexec path of an executable if we can't find the
+ * executable at the first attempt.
+ */
+
+static regex_t regc;
+static boolean_t cansplice = B_TRUE;
+
+static void
+init_isa_regex(void)
+{
+ char *isalist;
+ size_t isalen = 255; /* wild guess */
+ size_t len;
+ long ret;
+ char *regexpr;
+ char *p;
+
+ /*
+ * Extract the isalist(5) for userland from the kernel.
+ */
+ isalist = malloc(isalen);
+ do {
+ ret = sysinfo(SI_ISALIST, isalist, isalen);
+ if (ret == -1l) {
+ free(isalist);
+ return;
+ }
+ if (ret > isalen) {
+ isalen = ret;
+ isalist = realloc(isalist, isalen);
+ } else
+ break;
+ } while (isalist != NULL);
+
+
+ if (isalist == NULL)
+ return;
+
+ /* allocate room for the regex + (/())/[^/]*$ + needed \\. */
+#define LEFT "(/("
+#define RIGHT "))/[^/]*$"
+
+ regexpr = alloca(ret * 2 + sizeof (LEFT RIGHT));
+ (void) strcpy(regexpr, LEFT);
+ len = strlen(regexpr);
+
+ for (p = isalist; *p; p++) {
+ switch (*p) {
+ case '+':
+ case '|':
+ case '*':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case '\\':
+ regexpr[len++] = '\\';
+ default:
+ regexpr[len++] = *p;
+ break;
+ case ' ':
+ case '\t':
+ regexpr[len++] = '|';
+ break;
+ }
+ }
+
+ free(isalist);
+ regexpr[len] = '\0';
+ (void) strcat(regexpr, RIGHT);
+
+ if (regcomp(&regc, regexpr, REG_EXTENDED) != 0)
+ return;
+
+ cansplice = B_TRUE;
+}
+
+#define NMATCH 2
+
+static boolean_t
+removeisapath(char *path)
+{
+ regmatch_t match[NMATCH];
+
+ if (!cansplice || regexec(&regc, path, NMATCH, match, 0) != 0)
+ return (B_FALSE);
+
+ /*
+ * The first match includes the whole matched expression including the
+ * end of the string. The second match includes the "/" + "isa" and
+ * that is the part we need to remove.
+ */
+
+ if (match[1].rm_so == -1)
+ return (B_FALSE);
+
+ /* match[0].rm_eo == strlen(path) */
+ (void) memmove(path + match[1].rm_so, path + match[1].rm_eo,
+ match[0].rm_eo - match[1].rm_eo + 1);
+
+ return (B_TRUE);
+}
+
+static int
+register_pfexec(int fd)
+{
+ int ret = syscall(SYS_privsys, PRIVSYS_PFEXEC_REG, fd);
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static void
+unregister_pfexec(int sig)
+{
+ if (doorfd != -1)
+ (void) syscall(SYS_privsys, PRIVSYS_PFEXEC_UNREG, doorfd);
+ _exit(0);
+}
+
+static int
+alldigits(const char *s)
+{
+ int c;
+
+ if (*s == '\0')
+ return (0);
+
+ while ((c = *s++) != '\0') {
+ if (!isdigit(c)) {
+ return (0);
+ }
+ }
+
+ return (1);
+}
+
+static uid_t
+get_uid(const char *v, boolean_t *ok, char *path)
+{
+ struct passwd *pwd, pwdm;
+ char buf[1024];
+
+ if (getpwnam_r(v, &pwdm, buf, sizeof (buf), &pwd) == 0 && pwd != NULL)
+ return (pwd->pw_uid);
+
+ if (alldigits(v))
+ return (atoi(v));
+
+ *ok = B_FALSE;
+ syslog(LOG_ERR, "%s: %s: unknown username\n", path, v);
+ return ((uid_t)-1);
+}
+
+static uid_t
+get_gid(const char *v, boolean_t *ok, char *path)
+{
+ struct group *grp, grpm;
+ char buf[1024];
+
+ if (getgrnam_r(v, &grpm, buf, sizeof (buf), &grp) == 0 && grp != NULL)
+ return (grp->gr_gid);
+
+ if (alldigits(v))
+ return (atoi(v));
+
+ *ok = B_FALSE;
+ syslog(LOG_ERR, "%s: %s: unknown groupname\n", path, v);
+ return ((gid_t)-1);
+}
+
+static priv_set_t *
+get_privset(const char *s, boolean_t *ok, char *path)
+{
+ priv_set_t *res;
+
+ if ((res = priv_str_to_set(s, ",", NULL)) == NULL) {
+ syslog(LOG_ERR, "%s: %s: bad privilege set\n", path, s);
+ if (ok != NULL)
+ *ok = B_FALSE;
+ }
+ return (res);
+}
+
+/*ARGSUSED*/
+static int
+ggp_callback(const char *prof, kva_t *attr, void *ctxt, void *vres)
+{
+ priv_set_t *res = vres;
+ char *privs;
+
+ if (attr == NULL)
+ return (0);
+
+ /* get privs from this profile */
+ privs = kva_match(attr, PROFATTR_PRIVS_KW);
+ if (privs != NULL) {
+ priv_set_t *tmp = priv_str_to_set(privs, ",", NULL);
+ if (tmp != NULL) {
+ priv_union(tmp, res);
+ priv_freeset(tmp);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * This routine exists on failure and returns NULL if no granted privileges
+ * are set.
+ */
+static priv_set_t *
+get_granted_privs(uid_t uid)
+{
+ priv_set_t *res;
+ struct passwd *pwd, pwdm;
+ char buf[1024];
+
+ if (getpwuid_r(uid, &pwdm, buf, sizeof (buf), &pwd) != 0 || pwd == NULL)
+ return (NULL);
+
+ res = priv_allocset();
+ if (res == NULL)
+ return (NULL);
+
+ priv_emptyset(res);
+
+ (void) _enum_profs(pwd->pw_name, ggp_callback, NULL, res);
+
+ return (res);
+}
+
+static void
+callback_forced_privs(pfexec_arg_t *pap)
+{
+ execattr_t *exec;
+ char *value;
+ priv_set_t *fset;
+ void *res = alloca(setsz);
+
+ /* Empty set signifies no forced privileges. */
+ priv_emptyset(res);
+
+ exec = getexecprof("Forced Privilege", KV_COMMAND, pap->pfa_path,
+ GET_ONE);
+
+ if (exec == NULL && removeisapath(pap->pfa_path)) {
+ exec = getexecprof("Forced Privilege", KV_COMMAND,
+ pap->pfa_path, GET_ONE);
+ }
+
+ if (exec == NULL) {
+ (void) door_return(res, setsz, NULL, 0);
+ return;
+ }
+
+ if ((value = kva_match(exec->attr, EXECATTR_IPRIV_KW)) == NULL ||
+ (fset = get_privset(value, NULL, pap->pfa_path)) == NULL) {
+ free_execattr(exec);
+ (void) door_return(res, setsz, NULL, 0);
+ return;
+ }
+
+ priv_copyset(fset, res);
+ priv_freeset(fset);
+
+ free_execattr(exec);
+ (void) door_return(res, setsz, NULL, 0);
+}
+
+static void
+callback_user_privs(pfexec_arg_t *pap)
+{
+ priv_set_t *gset, *wset;
+ uint32_t res;
+
+ wset = (priv_set_t *)&pap->pfa_buf;
+ gset = get_granted_privs(pap->pfa_uid);
+
+ res = priv_issubset(wset, gset);
+ priv_freeset(gset);
+
+ (void) door_return((char *)&res, sizeof (res), NULL, 0);
+}
+
+static void
+callback_pfexec(pfexec_arg_t *pap)
+{
+ pfexec_reply_t *res = alloca(repsz);
+ uid_t uid, euid, uuid;
+ gid_t gid, egid;
+ struct passwd pw, *pwd;
+ char buf[1024];
+ execattr_t *exec;
+ char *value;
+ priv_set_t *lset, *iset;
+ size_t mysz = repsz - 2 * setsz;
+ char *path = pap->pfa_path;
+
+ uuid = pap->pfa_uid;
+
+ if (getpwuid_r(uuid, &pw, buf, sizeof (buf), &pwd) != 0 || pwd == NULL)
+ goto stdexec;
+
+ exec = getexecuser(pwd->pw_name, KV_COMMAND, path, GET_ONE);
+
+ if (exec == NULL && removeisapath(path))
+ exec = getexecuser(pwd->pw_name, KV_COMMAND, path, GET_ONE);
+
+ if (exec == NULL) {
+ res->pfr_allowed = B_FALSE;
+ goto ret;
+ }
+
+ if (exec->attr == NULL)
+ goto stdexec;
+
+ /* Found in execattr, so clearly we can use it */
+ res->pfr_allowed = B_TRUE;
+
+ uid = euid = (uid_t)-1;
+ gid = egid = (gid_t)-1;
+ lset = iset = NULL;
+
+ /*
+ * If there's an error in parsing uid, gid, privs, then return
+ * failure.
+ */
+ if ((value = kva_match(exec->attr, EXECATTR_UID_KW)) != NULL)
+ euid = uid = get_uid(value, &res->pfr_allowed, path);
+
+ if ((value = kva_match(exec->attr, EXECATTR_GID_KW)) != NULL)
+ egid = gid = get_gid(value, &res->pfr_allowed, path);
+
+ if ((value = kva_match(exec->attr, EXECATTR_EUID_KW)) != NULL)
+ euid = get_uid(value, &res->pfr_allowed, path);
+
+ if ((value = kva_match(exec->attr, EXECATTR_EGID_KW)) != NULL)
+ egid = get_gid(value, &res->pfr_allowed, path);
+
+ if ((value = kva_match(exec->attr, EXECATTR_LPRIV_KW)) != NULL)
+ lset = get_privset(value, &res->pfr_allowed, path);
+
+ if ((value = kva_match(exec->attr, EXECATTR_IPRIV_KW)) != NULL)
+ iset = get_privset(value, &res->pfr_allowed, path);
+
+ /*
+ * Remove LD_* variables in the kernel when the runtime linker might
+ * use them later on because the uids are equal.
+ */
+ res->pfr_scrubenv = (uid != (uid_t)-1 && euid == uid) ||
+ (gid != (gid_t)-1 && egid == gid) || iset != NULL;
+
+ res->pfr_euid = euid;
+ res->pfr_ruid = uid;
+ res->pfr_egid = egid;
+ res->pfr_rgid = gid;
+
+ /* Now add the privilege sets */
+ res->pfr_ioff = res->pfr_loff = 0;
+ if (iset != NULL) {
+ res->pfr_ioff = mysz;
+ priv_copyset(iset, PFEXEC_REPLY_IPRIV(res));
+ mysz += setsz;
+ priv_freeset(iset);
+ }
+ if (lset != NULL) {
+ res->pfr_loff = mysz;
+ priv_copyset(lset, PFEXEC_REPLY_LPRIV(res));
+ mysz += setsz;
+ priv_freeset(lset);
+ }
+
+ res->pfr_setcred = uid != (uid_t)-1 || euid != (uid_t)-1 ||
+ egid != (gid_t)-1 || gid != (gid_t)-1 || iset != NULL ||
+ lset != NULL;
+
+ /* If the real uid changes, we stop running under a profile shell */
+ res->pfr_clearflag = uid != (uid_t)-1 && uid != uuid;
+ free_execattr(exec);
+ret:
+ (void) door_return((char *)res, mysz, NULL, 0);
+ return;
+
+stdexec:
+ res->pfr_scrubenv = B_FALSE;
+ res->pfr_setcred = B_FALSE;
+ res->pfr_allowed = B_TRUE;
+
+ (void) door_return((char *)res, mysz, NULL, 0);
+}
+
+/* ARGSUSED */
+static void
+callback(void *cookie, char *argp, size_t asz, door_desc_t *dp, uint_t ndesc)
+{
+ /* LINTED ALIGNMENT */
+ pfexec_arg_t *pap = (pfexec_arg_t *)argp;
+
+ if (asz < sizeof (pfexec_arg_t) || pap->pfa_vers != PFEXEC_ARG_VERS) {
+ (void) door_return(NULL, 0, NULL, 0);
+ return;
+ }
+
+ switch (pap->pfa_call) {
+ case PFEXEC_EXEC_ATTRS:
+ callback_pfexec(pap);
+ break;
+ case PFEXEC_FORCED_PRIVS:
+ callback_forced_privs(pap);
+ break;
+ case PFEXEC_USER_PRIVS:
+ callback_user_privs(pap);
+ break;
+ default:
+ syslog(LOG_ERR, "Bad Call: %d\n", pap->pfa_call);
+ break;
+ }
+
+ /*
+ * If the door_return(ptr, size, NULL, 0) fails, make sure we
+ * don't lose server threads.
+ */
+ (void) door_return(NULL, 0, NULL, 0);
+}
+
+int
+main(void)
+{
+ const priv_impl_info_t *info;
+
+ (void) signal(SIGINT, unregister_pfexec);
+ (void) signal(SIGQUIT, unregister_pfexec);
+ (void) signal(SIGTERM, unregister_pfexec);
+ (void) signal(SIGHUP, unregister_pfexec);
+
+ info = getprivimplinfo();
+ if (info == NULL)
+ exit(1);
+
+ if (fork() > 0)
+ _exit(0);
+
+ openlog("pfexecd", LOG_PID, LOG_DAEMON);
+ setsz = info->priv_setsize * sizeof (priv_chunk_t);
+ repsz = 2 * setsz + sizeof (pfexec_reply_t);
+
+ init_isa_regex();
+
+ doorfd = door_create(callback, NULL, DOOR_REFUSE_DESC);
+
+ if (doorfd == -1 || register_pfexec(doorfd) != 0) {
+ perror("doorfd");
+ exit(1);
+ }
+
+ /* LINTED CONSTCOND */
+ while (1)
+ (void) sigpause(SIGINT);
+
+ return (0);
+}
diff --git a/usr/src/cmd/pfexecd/pfexecd.xml b/usr/src/cmd/pfexecd/pfexecd.xml
new file mode 100644
index 0000000000..c13249e4b6
--- /dev/null
+++ b/usr/src/cmd/pfexecd/pfexecd.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ NOTE: This service manifest is not editable; its contents will
+ be overwritten by package or patch operations, including
+ operating system upgrade. Make customizations in a different
+ file.
+-->
+
+<service_bundle type='manifest' name='SUNWcs:pfexec'>
+
+<service
+ name='system/pfexec'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='true' />
+
+ <single_instance />
+
+ <dependency
+ name='usr'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/usr' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/usr/lib/pfexecd'
+ timeout_seconds='60'>
+ </exec_method>
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':kill'
+ timeout_seconds='60'>
+ </exec_method>
+
+ <exec_method
+ type='method'
+ name='refresh'
+ exec=':kill'
+ timeout_seconds='60'>
+ </exec_method>
+
+ <property_group name='options' type='application'>
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ Supports in-kernel pfexec and forced privileges.
+ </loctext>
+ </common_name>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/profiles/profiles.c b/usr/src/cmd/profiles/profiles.c
index 8ac26920a4..265fd0c22e 100644
--- a/usr/src/cmd/profiles/profiles.c
+++ b/usr/src/cmd/profiles/profiles.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdio.h>
@@ -51,17 +50,10 @@
#define TEXT_DOMAIN "SYS_TEST"
#endif
-#define PROFLIST_SEP ","
-
-
static void usage();
static int show_profs(char *, int);
-static int list_profs(userattr_t *, int);
static void print_profs_long(execattr_t *);
-static void print_profs(char **, int, int);
-static void getProfiles(char *, char **, int *);
-static void getDefaultProfiles(char *, char **, int *);
-static void print_profile_privs(const char *);
+static void print_profile_privs(kva_t *);
static char *progname = "profiles";
@@ -110,15 +102,31 @@ main(int argc, char *argv[])
return (status);
}
+static int
+show_profs_callback(const char *prof, kva_t *pa, void *pflag, void *vcnt)
+{
+ char *indent = "";
+ const int *print_flag = pflag;
+ int *pcnt = vcnt;
+
+ (*pcnt)++;
+
+ if ((*print_flag) & PRINT_NAME) {
+ indent = " ";
+ }
+
+ (void) printf("%s%s", indent, prof);
+ print_profile_privs(pa);
+ (void) printf("\n");
+
+ return (0);
+}
static int
show_profs(char *username, int print_flag)
{
int status = EXIT_OK;
struct passwd *pw;
- userattr_t *user;
- char *profArray[MAXPROFS];
- int profcnt = 0;
execattr_t *exec;
if (username == NULL) {
@@ -135,76 +143,33 @@ show_profs(char *username, int print_flag)
(void) fprintf(stderr, gettext("No such user\n"));
return (status);
}
- if (username != NULL) {
- if ((user = getusernam(username)) != NULL) {
- status = list_profs(user, print_flag);
- } else {
- getDefaultProfiles(username, profArray, &profcnt);
- if (profcnt == 0) {
- status = EXIT_NON_FATAL;
- } else {
- if (print_flag & PRINT_LONG) {
- exec = getexecuser(username, KV_COMMAND,
- NULL, GET_ALL|__SEARCH_ALL_POLS);
- print_profs_long(exec);
- free_execattr(exec);
- } else {
- print_profs(profArray, print_flag,
- profcnt);
- }
- }
- }
- }
-
- if (status == EXIT_NON_FATAL) {
- (void) fprintf(stderr, "%s: %s: ", progname, username);
- (void) fprintf(stderr, gettext("No profiles\n"));
- }
-
- return (status);
-}
-
-
-static int
-list_profs(userattr_t *user, int print_flag)
-{
- int status = EXIT_OK;
- char *proflist = (char *)NULL;
- execattr_t *exec = (execattr_t *)NULL;
- char *profArray[MAXPROFS];
- int profcnt = 0;
if (print_flag & PRINT_LONG) {
- exec = getexecuser(user->name, KV_COMMAND, NULL,
+ exec = getexecuser(username, KV_COMMAND, NULL,
GET_ALL|__SEARCH_ALL_POLS);
- if (exec == NULL) {
+ if (exec != NULL) {
+ print_profs_long(exec);
+ free_execattr(exec);
+ } else {
status = EXIT_NON_FATAL;
}
} else {
- proflist = kva_match(user->attr, USERATTR_PROFILES_KW);
- if (proflist != NULL) {
- getProfiles(proflist, profArray, &profcnt);
- }
- /* Also get any default profiles */
- getDefaultProfiles(user->name, profArray, &profcnt);
- if (profcnt == 0) {
+ int cnt = 0;
+ (void) _enum_profs(username, show_profs_callback, &print_flag,
+ &cnt);
+
+ if (cnt == 0)
status = EXIT_NON_FATAL;
- }
}
- if (status == EXIT_OK) {
- if (print_flag & PRINT_LONG) {
- print_profs_long(exec);
- free_execattr(exec);
- } else {
- print_profs(profArray, print_flag, profcnt);
- }
+
+ if (status == EXIT_NON_FATAL) {
+ (void) fprintf(stderr, "%s: %s: ", progname, username);
+ (void) fprintf(stderr, gettext("No profiles\n"));
}
- free_userattr(user);
return (status);
}
-
/*
* print extended profile information.
*
@@ -242,9 +207,16 @@ print_profs_long(execattr_t *exec)
for (curprofile = ""; exec != NULL; exec = exec->next) {
/* print profile name if it is a new one */
if (strcmp(curprofile, exec->name) != 0) {
+ profattr_t *pa;
curprofile = exec->name;
+
(void) printf(" %s", curprofile);
- print_profile_privs(curprofile);
+
+ pa = getprofnam(curprofile);
+ if (pa != NULL) {
+ print_profile_privs(pa->attr);
+ free_profattr(pa);
+ }
(void) printf("\n");
}
len = printf(" %s ", exec->id);
@@ -289,66 +261,13 @@ usage()
}
static void
-getProfiles(char *profiles, char **profArray, int *profcnt) {
-
- char *prof;
- char *lasts;
-
- for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts);
- prof != NULL;
- prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) {
-
- getproflist(prof, profArray, profcnt);
-
- }
-}
-
-static void
-print_profile_privs(const char *profile)
+print_profile_privs(kva_t *attr)
{
- profattr_t *prof_entry = getprofnam(profile);
char *privs;
- if (prof_entry) {
- privs = kva_match(prof_entry->attr, PROFATTR_PRIVS_KW);
+ if (attr) {
+ privs = kva_match(attr, PROFATTR_PRIVS_KW);
if (privs)
(void) printf(" privs=%s", privs);
- free_profattr(prof_entry);
- }
-}
-
-static void
-print_profs(char **profnames, int print_flag, int profcnt)
-{
-
- int i;
- char *indent = "";
-
- if (print_flag & PRINT_NAME) {
- indent = " ";
- }
-
- for (i = 0; i < profcnt; i++) {
- (void) printf("%s%s", indent, profnames[i]);
- print_profile_privs(profnames[i]);
- (void) printf("\n");
- }
-
- free_proflist(profnames, profcnt);
-}
-
-/*
- * Get the list of default profiles from /etc/security/policy.conf
- */
-static void
-getDefaultProfiles(char *user, char **profArray, int *profcnt)
-{
- char *profs = NULL;
-
- if (_get_user_defs(user, NULL, &profs) == 0) {
- if (profs != NULL) {
- getProfiles(profs, profArray, profcnt);
- _free_user_defs(NULL, profs);
- }
}
}
diff --git a/usr/src/cmd/ptools/ppriv/ppriv.c b/usr/src/cmd/ptools/ppriv/ppriv.c
index d9a155a959..a695c1a09b 100644
--- a/usr/src/cmd/ptools/ppriv/ppriv.c
+++ b/usr/src/cmd/ptools/ppriv/ppriv.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Program to examine or set process privileges.
*/
@@ -60,6 +59,7 @@ static boolean_t Don = B_FALSE;
static boolean_t Doff = B_FALSE;
static boolean_t list = B_FALSE;
static boolean_t mac_aware = B_FALSE;
+static boolean_t pfexec = B_FALSE;
static boolean_t xpol = B_FALSE;
static int mode = PRIV_STR_PORT;
@@ -78,7 +78,7 @@ main(int argc, char **argv)
else
command = argv[0];
- while ((opt = getopt(argc, argv, "lDMNevs:xS")) != EOF) {
+ while ((opt = getopt(argc, argv, "lDMNPevs:xS")) != EOF) {
switch (opt) {
case 'l':
list = B_TRUE;
@@ -94,6 +94,10 @@ main(int argc, char **argv)
set = B_TRUE;
Doff = B_TRUE;
break;
+ case 'P':
+ set = B_TRUE;
+ pfexec = B_TRUE;
+ break;
case 'e':
exec = B_TRUE;
break;
@@ -493,7 +497,7 @@ privupdate(prpriv_t *pr, const char *arg)
}
}
- if (Doff || Don || xpol) {
+ if (Doff || Don || pfexec || xpol) {
priv_info_uint_t *pii;
int sz = PRIV_PRPRIV_SIZE(pr);
char *x = (char *)pr + PRIV_PRPRIV_INFO_OFFSET(pr);
@@ -530,6 +534,8 @@ done:
fl |= PRIV_DEBUG;
if (Doff)
fl &= ~PRIV_DEBUG;
+ if (pfexec)
+ fl |= PRIV_PFEXEC;
if (xpol)
fl |= PRIV_XPOLICY;
@@ -552,6 +558,10 @@ privupdate_self(void)
if (setpflags(NET_MAC_AWARE_INHERIT, 1) != 0)
fatal("setpflags(NET_MAC_AWARE_INHERIT)");
}
+ if (pfexec) {
+ if (setpflags(PRIV_PFEXEC, 1) != 0)
+ fatal("setpflags(PRIV_PFEXEC)");
+ }
if (sets != NULL) {
priv_set_t *target = priv_allocset();
@@ -592,6 +602,8 @@ privupdate_self(void)
(void) setpflags(PRIV_DEBUG, Don ? 1 : 0);
if (xpol)
(void) setpflags(PRIV_XPOLICY, 1);
+ if (pfexec)
+ (void) setpflags(PRIV_PFEXEC, 1);
}
static int
@@ -649,6 +661,7 @@ static struct {
{ PRIV_AWARE_INHERIT, "PRIV_AWARE_INHERIT" },
{ PRIV_AWARE_RESET, "PRIV_AWARE_RESET" },
{ PRIV_XPOLICY, "PRIV_XPOLICY" },
+ { PRIV_PFEXEC, "PRIV_PFEXEC" },
{ NET_MAC_AWARE, "NET_MAC_AWARE" },
{ NET_MAC_AWARE_INHERIT, "NET_MAC_AWARE_INHERIT" },
};
diff --git a/usr/src/cmd/sh/Makefile b/usr/src/cmd/sh/Makefile
index a2660213d0..78db168423 100644
--- a/usr/src/cmd/sh/Makefile
+++ b/usr/src/cmd/sh/Makefile
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
#
PROG = sh
@@ -29,7 +28,7 @@ USR_PROG = $(PROG)
OBJS= args.o blok.o cmd.o defs.o error.o fault.o hash.o hashserv.o \
io.o msg.o print.o stak.o string.o word.o xec.o \
ctype.o echo.o expand.o func.o macro.o pwd.o setbrk.o test.o \
- bltin.o jobs.o ulimit.o sh_policy.o main.o name.o service.o
+ bltin.o jobs.o ulimit.o main.o name.o service.o
SRCS= $(OBJS:%.o=%.c)
include ../Makefile.cmd
@@ -47,7 +46,7 @@ XGETFLAGS += -a -x sh.xcl
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DACCT
MAPFILES = $(MAPFILE.INT) $(MAPFILE.NGB)
LDFLAGS += $(MAPFILES:%=-M%)
-LDLIBS += -lgen -lsecdb
+LDLIBS += -lgen
.KEEP_STATE:
@@ -66,8 +65,6 @@ $(POFILE): $(POFILES)
install: all $(ROOTHASBINPROG)
$(RM) $(ROOTHASBIN)/jsh
$(SYMLINK) sh $(ROOTHASBIN)/jsh
- $(RM) $(ROOTHASBIN)/pfsh
- $(SYMLINK) sh $(ROOTHASBIN)/pfsh
$(RM) $(ROOTHASLIB)/rsh
$(SYMLINK) ../bin/sh $(ROOTHASLIB)/rsh
diff --git a/usr/src/cmd/sh/main.c b/usr/src/cmd/sh/main.c
index 9533e793cc..df42009b5b 100644
--- a/usr/src/cmd/sh/main.c
+++ b/usr/src/cmd/sh/main.c
@@ -20,14 +20,12 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* UNIX shell
*/
@@ -40,7 +38,6 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include "dup.h"
-#include "sh_policy.h"
#ifdef RES
#include <sgtty.h>
@@ -141,15 +138,6 @@ main(int c, char *v[], char *e[])
(void) textdomain(TEXT_DOMAIN);
/*
- * This is a profile shell if the simple name of argv[0] is
- * pfsh or -pfsh
- */
- if (c > 0 && (eq("pfsh", simple(*v)) || eq("-pfsh", simple(*v)))) {
- flags |= pfshflg;
- secpolicy_init();
- }
-
- /*
* 'rsflag' is zero if SHELL variable is
* set in environment and
* the simple file part of the value.
@@ -600,23 +588,3 @@ setmode(int prof)
flags &= ~prompt;
}
}
-
-/*
- * A generic call back routine to output error messages from the
- * policy backing functions called by pfsh.
- *
- * msg must contain '\n' if a new line is to be printed.
- */
-void
-secpolicy_print(int level, const char *msg)
-{
- switch (level) {
- case SECPOLICY_WARN:
- default:
- prs(_gettext(msg));
- return;
- case SECPOLICY_ERROR:
- error(msg);
- break;
- }
-}
diff --git a/usr/src/cmd/sh/service.c b/usr/src/cmd/sh/service.c
index e666aafc65..e74a35b471 100644
--- a/usr/src/cmd/sh/service.c
+++ b/usr/src/cmd/sh/service.c
@@ -20,15 +20,12 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* UNIX shell
*/
@@ -36,7 +33,6 @@
#include "defs.h"
#include <errno.h>
#include <fcntl.h>
-#include "sh_policy.h"
#define ARGMK 01
@@ -202,7 +198,8 @@ catpath(unsigned char *path, unsigned char *name)
if (argp >= brkend)
growstak(argp);
}
- while (*argp++ = *scanp++);
+ while (*argp++ = *scanp++)
+ ;
return (path);
}
@@ -253,7 +250,6 @@ execa(unsigned char *at[], short pos)
static unsigned char *
execs(unsigned char *ap, unsigned char *t[])
{
- int pfstatus = NOATTRS;
unsigned char *p, *prefix;
unsigned char *savptr;
@@ -261,28 +257,8 @@ execs(unsigned char *ap, unsigned char *t[])
trim(p = curstak());
sigchk();
- if (flags & pfshflg) {
- /*
- * Need to save the stack information, or the
- * first memory allocation in secpolicy_profile_lookup()
- * will clobber it.
- */
- savptr = endstak(p + strlen((const char *)p) + 1);
-
- pfstatus = secpolicy_pfexec((const char *)p,
- (char **)t, (const char **)xecenv);
-
- if (pfstatus != NOATTRS) {
- errno = pfstatus;
- }
-
- tdystak(savptr);
- }
-
- if (pfstatus == NOATTRS) {
- execve((const char *)p, (char *const *)&t[0],
- (char *const *)xecenv);
- }
+ execve((const char *)p, (char *const *)&t[0],
+ (char *const *)xecenv);
switch (errno) {
case ENOEXEC: /* could be a shell script */
@@ -351,7 +327,7 @@ trim(unsigned char *at)
last = at;
while (c = *current) {
if ((len = mbtowc(&wc, (char *)current,
- MB_LEN_MAX)) <= 0) {
+ MB_LEN_MAX)) <= 0) {
*last++ = c;
current++;
continue;
@@ -369,7 +345,7 @@ trim(unsigned char *at)
current++;
if (c = *current) {
if ((len = mbtowc(&wc, (char *)current,
- MB_LEN_MAX)) <= 0) {
+ MB_LEN_MAX)) <= 0) {
*last++ = c;
current++;
continue;
@@ -676,7 +652,7 @@ doacct(void)
sabuf.ac_etime = compress(after - before);
if ((fd = open((char *)acctnod.namval,
- O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1) {
+ O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1) {
write(fd, &sabuf, sizeof (sabuf));
close(fd);
}
diff --git a/usr/src/cmd/sh/sh_policy.c b/usr/src/cmd/sh/sh_policy.c
deleted file mode 100644
index d9102e3381..0000000000
--- a/usr/src/cmd/sh/sh_policy.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Policy backing functions for kpolicy=suser,profiles=yes
- *
- */
-
-#include <sys/param.h>
-#include <grp.h>
-#include <pwd.h>
-#include <strings.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "sh_policy.h"
-
-
-static char *username;
-
-/*
- * get the ruid and passwd name
- */
-void
-secpolicy_init(void)
-{
- uid_t ruid;
- struct passwd *passwd_ent;
-
- if (username != NULL) {
- free(username);
- username = NULL;
- }
-
- ruid = getuid();
-
- if ((passwd_ent = getpwuid(ruid)) == NULL) {
- secpolicy_print(SECPOLICY_ERROR, ERR_PASSWD);
- } else if ((username = strdup(passwd_ent->pw_name)) == NULL) {
- secpolicy_print(SECPOLICY_ERROR, ERR_MEM);
- }
-}
-
-
-/*
- * stuff pfexec full path at the begining of the argument vector
- * for the command to be pfexec'd
- *
- * return newly allocated argv on success, else return NULL.
- */
-static char **
-secpolicy_set_argv(char **arg_v)
-{
- int i;
- int arg_c = 0;
- char **pfarg_v = NULL;
-
- if (*arg_v == NULL) {
- return (pfarg_v);
- }
- for (i = 0; arg_v[i] != NULL; i++) {
- arg_c++;
- }
- /* +2 for PFEXEC and null termination */
- if ((pfarg_v = calloc(arg_c + 2, sizeof (char *))) == NULL) {
- return (pfarg_v);
- }
- pfarg_v[0] = PFEXEC;
- for (i = 0; i < arg_c; i++) {
- pfarg_v[i + 1] = arg_v[i];
- }
-
- return (pfarg_v);
-}
-
-
-/*
- * gets realpath for cmd.
- * return 0 on success, else return ENOENT.
- */
-static int
-secpolicy_getrealpath(const char *cmd, char *cmd_realpath)
-{
- register char *mover;
- char cwd[MAXPATHLEN];
-
- /*
- * What about relative paths? Were we passed one?
- */
- mover = (char *)cmd;
- if (*mover != '/') {
- /*
- * Everything in here will be considered a relative
- * path, and therefore we need to prepend cwd to it.
- */
- if (getcwd(cwd, MAXPATHLEN) == NULL) {
- secpolicy_print(SECPOLICY_ERROR, ERR_CWD);
- }
- strcat(cwd, "/");
- if (strlcat(cwd, cmd, MAXPATHLEN) >= MAXPATHLEN) {
- return (ENOENT);
- }
- mover = cwd;
- }
- /*
- * Resolve ".." and other such nonsense.
- * Now, is there *REALLY* a file there?
- */
- if (realpath(mover, cmd_realpath) == NULL) {
- return (ENOENT);
- }
-
- return (0);
-}
-
-
-/*
- * check if the command has execution attributes
- * return -
- * - NOATTRS : command in profile but has no execution attributes
- * - ENOMEM : memory allocation errors
- * - ENOENT : command not in profile
- */
-
-int
-secpolicy_pfexec(const char *command, char **arg_v, const char **xecenv)
-{
- register int status = NOATTRS;
- char **pfarg_v = (char **)NULL;
- char cmd_realpath[MAXPATHLEN + 1];
- execattr_t *exec;
-
- if ((status = secpolicy_getrealpath(command, cmd_realpath)) != 0) {
- return (status);
- }
- if ((exec = getexecuser(username, KV_COMMAND,
- (const char *)cmd_realpath, GET_ONE)) == NULL) {
- /*
- * command not in profile
- */
- return (ENOENT);
- }
- /*
- * In case of "All" profile, we'd go through pfexec
- * if it had any attributes.
- */
- if ((exec->attr != NULL) && (exec->attr->length != 0)) {
- /*
- * command in profile and has attributes
- */
- free_execattr(exec);
- arg_v[0] = (char *)command;
- pfarg_v = secpolicy_set_argv(arg_v);
- if (pfarg_v != NULL) {
- errno = 0;
- if (xecenv == NULL) {
- execv(PFEXEC, (char *const *)pfarg_v);
- } else {
- execve(PFEXEC, (char *const *)pfarg_v,
- (char *const *)xecenv);
- }
- free(pfarg_v);
- status = errno;
- } else {
- status = ENOMEM;
- }
- } else {
- /*
- * command in profile, but has no attributes
- */
- free_execattr(exec);
- status = NOATTRS;
- }
-
-
- return (status);
-}
diff --git a/usr/src/cmd/sh/sh_policy.h b/usr/src/cmd/sh/sh_policy.h
deleted file mode 100644
index 6efd47ca52..0000000000
--- a/usr/src/cmd/sh/sh_policy.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1999 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SH_POLICY_H
-#define _SH_POLICY_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <exec_attr.h>
-
-#define PFEXEC "/usr/bin/pfexec"
-#define ALL_PROFILE "All"
-
-#define ERR_PASSWD "can't get passwd entry"
-#define ERR_MEM "can't allocate memory"
-#define ERR_CWD "can't get current working directory"
-#define ERR_PATH "resolved pathname too large"
-#define ERR_PROFILE "not in profile"
-#define ERR_REALPATH "can't get real path"
-
-#define NOATTRS 0 /* command in profile but w'out attributes */
-
-#define SECPOLICY_WARN 1
-#define SECPOLICY_ERROR 2
-
-/*
- * Shell Policy Interface Functions
- */
-extern void secpolicy_init(void);
-extern int secpolicy_pfexec(const char *, char **, const char **);
-extern void secpolicy_print(int, const char *);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SH_POLICY_H */
diff --git a/usr/src/cmd/svc/configd/rc_node.c b/usr/src/cmd/svc/configd/rc_node.c
index 5dbbce2091..a8aa4c32a7 100644
--- a/usr/src/cmd/svc/configd/rc_node.c
+++ b/usr/src/cmd/svc/configd/rc_node.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -114,9 +113,7 @@
* proceed if the user has been assigned at least one of a set of
* authorization strings. The set of enabling authorizations depends on the
* operation and the target object. The set of authorizations assigned to
- * a user is determined by reading /etc/security/policy.conf, querying the
- * user_attr database, and possibly querying the prof_attr database, as per
- * chkauthattr() in libsecdb.
+ * a user is determined by an algorithm defined in libsecdb.
*
* The fastest way to decide whether the two sets intersect is by entering the
* strings into a hash table and detecting collisions, which takes linear time
@@ -360,7 +357,6 @@
#include <libuutil.h>
#include <libscf.h>
#include <libscf_priv.h>
-#include <prof_attr.h>
#include <pthread.h>
#include <pwd.h>
#include <stdio.h>
@@ -369,7 +365,7 @@
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
-#include <user_attr.h>
+#include <secdb.h>
#include "configd.h"
@@ -388,8 +384,6 @@
#define AUTH_PROP_MODIFY "modify_authorization"
#define AUTH_PROP_VALUE "value_authorization"
#define AUTH_PROP_READ "read_authorization"
-/* libsecdb should take care of this. */
-#define RBAC_AUTH_SEP ","
#define MAX_VALID_CHILDREN 3
@@ -1498,29 +1492,24 @@ perm_add_enabling(permcheck_t *pcp, const char *auth)
* perm_granted() returns PERM_GRANTED if the current door caller has one of
* the enabling authorizations in pcp, PERM_DENIED if it doesn't, PERM_GONE if
* the door client went away and PERM_FAIL if an error (usually lack of
- * memory) occurs. check_auth_list() checks an RBAC_AUTH_SEP-separated
- * list of authorizations for existence in pcp, and check_prof_list()
- * checks the authorizations granted to an RBAC_AUTH_SEP-separated list of
- * profiles.
+ * memory) occurs. auth_cb() checks each and every authorizations as
+ * enumerated by _enum_auths. When we find a result other than PERM_DENIED,
+ * we short-cut the enumeration and return non-zero.
*/
-static perm_status_t
-check_auth_list(permcheck_t *pcp, char *authlist)
-{
- char *auth, *lasts;
- perm_status_t ret;
- for (auth = (char *)strtok_r(authlist, RBAC_AUTH_SEP, &lasts);
- auth != NULL;
- auth = (char *)strtok_r(NULL, RBAC_AUTH_SEP, &lasts)) {
- if (strchr(auth, KV_WILDCHAR) == NULL)
- ret = pc_exists(pcp, auth);
- else
- ret = pc_match(pcp, auth);
+static int
+auth_cb(const char *auth, void *ctxt, void *vres)
+{
+ permcheck_t *pcp = ctxt;
+ int *pret = vres;
- if (ret != PERM_DENIED)
- return (ret);
- }
+ if (strchr(auth, KV_WILDCHAR) == NULL)
+ *pret = pc_exists(pcp, auth);
+ else
+ *pret = pc_match(pcp, auth);
+ if (*pret != PERM_DENIED)
+ return (1);
/*
* If we failed, choose the most specific auth string for use in
* the audit event.
@@ -1528,40 +1517,7 @@ check_auth_list(permcheck_t *pcp, char *authlist)
assert(pcp->pc_specific != NULL);
pcp->pc_auth_string = pcp->pc_specific->pce_auth;
- return (PERM_DENIED);
-}
-
-static perm_status_t
-check_prof_list(permcheck_t *pcp, char *proflist)
-{
- char *prof, *lasts, *authlist, *subproflist;
- profattr_t *pap;
- perm_status_t ret = PERM_DENIED;
-
- for (prof = strtok_r(proflist, RBAC_AUTH_SEP, &lasts);
- prof != NULL;
- prof = strtok_r(NULL, RBAC_AUTH_SEP, &lasts)) {
- pap = getprofnam(prof);
- if (pap == NULL)
- continue;
-
- authlist = kva_match(pap->attr, PROFATTR_AUTHS_KW);
- if (authlist != NULL)
- ret = check_auth_list(pcp, authlist);
-
- if (ret == PERM_DENIED) {
- subproflist = kva_match(pap->attr, PROFATTR_PROFS_KW);
- if (subproflist != NULL)
- /* depth check to avoid infinite recursion? */
- ret = check_prof_list(pcp, subproflist);
- }
-
- free_profattr(pap);
- if (ret != PERM_DENIED)
- return (ret);
- }
-
- return (ret);
+ return (0); /* Tells that we need to continue */
}
static perm_status_t
@@ -1570,10 +1526,7 @@ perm_granted(permcheck_t *pcp)
ucred_t *uc;
perm_status_t ret = PERM_DENIED;
- int rv;
uid_t uid;
- userattr_t *uap;
- char *authlist, *userattr_authlist, *proflist, *def_prof = NULL;
struct passwd pw;
char pwbuf[1024]; /* XXX should be NSS_BUFLEN_PASSWD */
@@ -1606,51 +1559,12 @@ perm_granted(permcheck_t *pcp)
}
/*
- * Get user's default authorizations from policy.conf
+ * Enumerate all the auths defined for the user and return the
+ * result in ret.
*/
- rv = _get_user_defs(pw.pw_name, &authlist, &def_prof);
-
- if (rv != 0)
+ if (_enum_auths(pw.pw_name, auth_cb, pcp, &ret) < 0)
return (PERM_FAIL);
- if (authlist != NULL) {
- ret = check_auth_list(pcp, authlist);
-
- if (ret != PERM_DENIED) {
- _free_user_defs(authlist, def_prof);
- return (ret);
- }
- }
-
- /*
- * Put off checking def_prof for later in an attempt to consolidate
- * prof_attr accesses.
- */
-
- uap = getusernam(pw.pw_name);
- if (uap != NULL) {
- /* Get the authorizations from user_attr. */
- userattr_authlist = kva_match(uap->attr, USERATTR_AUTHS_KW);
- if (userattr_authlist != NULL) {
- ret = check_auth_list(pcp, userattr_authlist);
- }
- }
-
- if ((ret == PERM_DENIED) && (def_prof != NULL)) {
- /* Check generic profiles. */
- ret = check_prof_list(pcp, def_prof);
- }
-
- if ((ret == PERM_DENIED) && (uap != NULL)) {
- proflist = kva_match(uap->attr, USERATTR_PROFILES_KW);
- if (proflist != NULL)
- ret = check_prof_list(pcp, proflist);
- }
-
- _free_user_defs(authlist, def_prof);
- if (uap != NULL)
- free_userattr(uap);
-
return (ret);
}
diff --git a/usr/src/cmd/truss/actions.c b/usr/src/cmd/truss/actions.c
index e04db7bdb5..2dda60fb3e 100644
--- a/usr/src/cmd/truss/actions.c
+++ b/usr/src/cmd/truss/actions.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1988 AT&T */
@@ -973,7 +972,7 @@ showargs(private_t *pri, int raw)
if (raw)
showpaths(pri, &systable[SYS_execve]);
- show_cred(pri, FALSE);
+ show_cred(pri, FALSE, FALSE);
if (aflag || eflag) { /* dump args or environment */
diff --git a/usr/src/cmd/truss/main.c b/usr/src/cmd/truss/main.c
index 736b8bc2ef..151c7492ad 100644
--- a/usr/src/cmd/truss/main.c
+++ b/usr/src/cmd/truss/main.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -47,6 +46,7 @@
#include <sys/mman.h>
#include <sys/resource.h>
#include <libproc.h>
+#include <priv.h>
#include "ramdata.h"
#include "proto.h"
#include "htbl.h"
@@ -603,7 +603,7 @@ main(int argc, char *argv[])
if (created) {
per_proc_init();
procadd(created, NULL);
- show_cred(pri, TRUE);
+ show_cred(pri, TRUE, FALSE);
} else { /* grab the specified processes */
int gotone = FALSE;
@@ -1127,6 +1127,7 @@ worker_thread(void *arg)
exit_called = TRUE;
break;
case SYS_execve:
+ show_cred(pri, FALSE, TRUE);
(void) sysentry(pri, dotrace);
if (dotrace && !cflag &&
prismember(&trace, what)) {
@@ -2307,18 +2308,31 @@ fetchstring(private_t *pri, long addr, int maxleng)
return (pri->str_buffer);
}
+static priv_set_t *
+getset(prpriv_t *p, priv_ptype_t set)
+{
+ return ((priv_set_t *)
+ &p->pr_sets[priv_getsetbyname(set) * p->pr_setsize]);
+}
+
void
-show_cred(private_t *pri, int new)
+show_cred(private_t *pri, int new, int loadonly)
{
prcred_t cred;
+ prpriv_t *privs;
if (proc_get_cred(Pstatus(Proc)->pr_pid, &cred, 0) < 0) {
- perror("show_cred()");
+ perror("show_cred() - credential");
(void) printf("%s\t*** Cannot get credentials\n", pri->pname);
return;
}
+ if ((privs = proc_get_priv(Pstatus(Proc)->pr_pid)) == NULL) {
+ perror("show_cred() - privileges");
+ (void) printf("%s\t*** Cannot get privileges\n", pri->pname);
+ return;
+ }
- if (!cflag && prismember(&trace, SYS_execve)) {
+ if (!loadonly && !cflag && prismember(&trace, SYS_execve)) {
if (new)
credentials = cred;
if ((new && cred.pr_ruid != cred.pr_suid) ||
@@ -2339,9 +2353,29 @@ show_cred(private_t *pri, int new)
(int)cred.pr_rgid,
(int)cred.pr_egid,
(int)cred.pr_sgid);
+ if (privdata != NULL && cred.pr_euid != 0) {
+ priv_set_t *npset = getset(privs, PRIV_PERMITTED);
+ priv_set_t *opset = getset(privdata, PRIV_PERMITTED);
+ char *s, *t;
+ if (!priv_issubset(npset, opset)) {
+ /* Use the to be freed privdata as scratch */
+ priv_inverse(opset);
+ priv_intersect(npset, opset);
+ s = priv_set_to_str(opset, ',', PRIV_STR_SHORT);
+ t = priv_set_to_str(npset, ',', PRIV_STR_SHORT);
+ (void) printf("%s *** FPRIV: P/E: %s ***\n",
+ pri->pname,
+ strlen(s) > strlen(t) ? t : s);
+ free(s);
+ free(t);
+ }
+ }
}
+ if (privdata != NULL)
+ free(privdata);
credentials = cred;
+ privdata = privs;
}
/*
@@ -2479,7 +2513,7 @@ grabit(private_t *pri, proc_set_t *set)
else
(void) Punsetflags(Proc, PR_FORK);
procadd(set->pid, set->lwps);
- show_cred(pri, TRUE);
+ show_cred(pri, TRUE, FALSE);
return (TRUE);
}
diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c
index 2848fd1490..c4ba8b2abd 100644
--- a/usr/src/cmd/truss/print.c
+++ b/usr/src/cmd/truss/print.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -2257,6 +2256,7 @@ prt_pfl(private_t *pri, int raw, long val)
case PRIV_AWARE: s = "PRIV_AWARE"; break;
case PRIV_XPOLICY: s = "PRIV_XPOLICY"; break;
case PRIV_AWARE_RESET: s = "PRIV_AWARE_RESET"; break;
+ case PRIV_PFEXEC: s = "PRIV_PFEXEC"; break;
case NET_MAC_AWARE: s = "NET_MAC_AWARE"; break;
case NET_MAC_AWARE_INHERIT:
s = "NET_MAC_AWARE_INHERIT";
diff --git a/usr/src/cmd/truss/proto.h b/usr/src/cmd/truss/proto.h
index 25f92cef67..670fe95f1b 100644
--- a/usr/src/cmd/truss/proto.h
+++ b/usr/src/cmd/truss/proto.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -110,7 +109,7 @@ extern int fdlist(char *, fileset_t *);
extern int liblist(char *, int);
extern char *fetchstring(private_t *, long, int);
-extern void show_cred(private_t *, int);
+extern void show_cred(private_t *, int, int);
extern void errmsg(const char *, const char *);
extern void abend(const char *, const char *);
diff --git a/usr/src/cmd/truss/ramdata.c b/usr/src/cmd/truss/ramdata.c
index bd02ab6e2a..abb8ee202b 100644
--- a/usr/src/cmd/truss/ramdata.c
+++ b/usr/src/cmd/truss/ramdata.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -52,6 +51,7 @@ uid_t Egid; /* truss's effective gid */
uid_t Ruid; /* truss's real uid */
uid_t Rgid; /* truss's real gid */
prcred_t credentials; /* traced process credentials */
+prpriv_t *privdata; /* traced process privileges */
int istty; /* TRUE iff output is a tty */
time_t starttime; /* start time */
diff --git a/usr/src/cmd/truss/ramdata.h b/usr/src/cmd/truss/ramdata.h
index ea2bbdda46..788422827e 100644
--- a/usr/src/cmd/truss/ramdata.h
+++ b/usr/src/cmd/truss/ramdata.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -136,6 +135,7 @@ extern uid_t Egid; /* truss's effective gid */
extern uid_t Ruid; /* truss's real uid */
extern uid_t Rgid; /* truss's real gid */
extern prcred_t credentials; /* traced process credentials */
+extern prpriv_t *privdata; /* traced process privileges */
extern int istty; /* TRUE iff output is a tty */
extern time_t starttime; /* start time */