1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 /*
26  * svc-auditset - auditset transient service (AUDITSET_FMRI) startup method;
27  * sets non-/attributable mask in the kernel context.
28  */
29 
30 #include <audit_scf.h>
31 #include <bsm/adt.h>
32 #include <bsm/libbsm.h>
33 #include <zone.h>
34 #include <errno.h>
35 #include <locale.h>
36 #include <stdio.h>
37 
38 #if !defined(SMF_EXIT_ERR_OTHER)
39 #define	SMF_EXIT_ERR_OTHER	1
40 #endif
41 
42 /*
43  * update_kcontext() - updates the non-/attributable preselection masks in
44  * the kernel context. Returns B_TRUE on success, B_FALSE otherwise.
45  */
46 boolean_t
47 update_kcontext(int cmd, char *cmask)
48 {
49 	au_mask_t	bmask;
50 
51 	(void) getauditflagsbin(cmask, &bmask);
52 	if (auditon(cmd, (caddr_t)&bmask, sizeof (bmask)) == -1) {
53 		(void) printf("Could not update kernel context (%s).\n",
54 		    cmd == A_SETAMASK ? "A_SETAMASK" : "A_SETKMASK");
55 		return (B_FALSE);
56 	}
57 
58 #ifdef	DEBUG
59 	(void) printf("svc-auditset: %s mask set to %s",
60 	    cmd == A_SETAMASK ? "Attributable" : "Non-Attributable", cmask);
61 #endif
62 
63 	return (B_TRUE);
64 }
65 
66 int
67 main(void)
68 {
69 	char		*auditset_fmri;
70 	char		*mask_cfg;
71 	uint32_t	policy;
72 
73 	(void) setlocale(LC_ALL, "");
74 	(void) textdomain(TEXT_DOMAIN);
75 
76 	/* allow execution only inside the SMF facility */
77 	if ((auditset_fmri = getenv("SMF_FMRI")) == NULL ||
78 	    strcmp(auditset_fmri, AUDITSET_FMRI) != 0) {
79 		(void) printf(gettext("svc-auditset can be executed only "
80 		    "inside the SMF facility.\n"));
81 		return (SMF_EXIT_ERR_NOSMF);
82 	}
83 
84 	/* check the c2audit module state */
85 	if (adt_audit_state(AUC_DISABLED)) {
86 #ifdef	DEBUG
87 		if (errno == ENOTSUP) {
88 			(void) printf("c2audit module is excluded from "
89 			    "the system(4); kernel won't be updated.\n");
90 		} else {
91 			(void) printf("%s\n", strerror(errno));
92 		}
93 #endif
94 		return (SMF_EXIT_OK);
95 	}
96 
97 	/* check the audit policy */
98 	if (auditon(A_GETPOLICY, (caddr_t)&policy, 0) == -1) {
99 		(void) printf("Could not read audit policy: %s\n",
100 		    strerror(errno));
101 		return (SMF_EXIT_ERR_OTHER);
102 	}
103 
104 	if (!(policy & AUDIT_PERZONE) && (getzoneid() != GLOBAL_ZONEID))
105 		return (SMF_EXIT_OK);
106 
107 	/* update attributable mask */
108 	if (!do_getflags_scf(&mask_cfg) || mask_cfg == NULL) {
109 		(void) printf("Could not get configured attributable audit "
110 		    "flags.\n");
111 		return (SMF_EXIT_ERR_OTHER);
112 	}
113 	if (!update_kcontext(A_SETAMASK, mask_cfg)) {
114 		free(mask_cfg);
115 		return (SMF_EXIT_ERR_OTHER);
116 	}
117 	free(mask_cfg);
118 
119 	/* update non-attributable mask */
120 	if (!do_getnaflags_scf(&mask_cfg) || mask_cfg == NULL) {
121 		(void) printf("Could not get configured non-attributable "
122 		    "audit flags.\n");
123 		return (SMF_EXIT_ERR_OTHER);
124 	}
125 	if (!update_kcontext(A_SETKMASK, mask_cfg)) {
126 		free(mask_cfg);
127 		return (SMF_EXIT_ERR_OTHER);
128 	}
129 	free(mask_cfg);
130 
131 	return (SMF_EXIT_OK);
132 }
133