2 * Copyright (c) 2004 Apple Computer, Inc.
3 * Copyright (c) 2006 Robert N. M. Watson
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_user.c#15 $
33 #include <bsm/libbsm.h>
41 * Parse the contents of the audit_user file into au_user_ent structures.
44 static FILE *fp = NULL;
45 static char linestr[AU_LINE_MAX];
46 static const char *user_delim = ":";
48 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
51 * Parse one line from the audit_user file into the au_user_ent structure.
53 static struct au_user_ent *
54 userfromstr(char *str, struct au_user_ent *u)
56 char *username, *always, *never;
59 username = strtok_r(str, user_delim, &last);
60 always = strtok_r(NULL, user_delim, &last);
61 never = strtok_r(NULL, user_delim, &last);
63 if ((username == NULL) || (always == NULL) || (never == NULL))
66 if (strlen(username) >= AU_USER_NAME_MAX)
69 strcpy(u->au_name, username);
70 if (getauditflagsbin(always, &(u->au_always)) == -1)
73 if (getauditflagsbin(never, &(u->au_never)) == -1)
80 * Rewind to beginning of the file
83 setauuser_locked(void)
87 fseek(fp, 0, SEEK_SET);
94 pthread_mutex_lock(&mutex);
96 pthread_mutex_unlock(&mutex);
100 * Close the file descriptor
106 pthread_mutex_lock(&mutex);
111 pthread_mutex_unlock(&mutex);
115 * Enumerate the au_user_ent structures from the file
117 static struct au_user_ent *
118 getauuserent_r_locked(struct au_user_ent *u)
122 if ((fp == NULL) && ((fp = fopen(AUDIT_USER_FILE, "r")) == NULL))
126 if (fgets(linestr, AU_LINE_MAX, fp) == NULL)
129 /* Remove new lines. */
130 if ((nl = strrchr(linestr, '\n')) != NULL)
134 if (linestr[0] == '#')
137 /* Get the next structure. */
138 if (userfromstr(linestr, u) == NULL)
147 getauuserent_r(struct au_user_ent *u)
149 struct au_user_ent *up;
151 pthread_mutex_lock(&mutex);
152 up = getauuserent_r_locked(u);
153 pthread_mutex_unlock(&mutex);
160 static char user_ent_name[AU_USER_NAME_MAX];
161 static struct au_user_ent u;
163 bzero(&u, sizeof(u));
164 bzero(user_ent_name, sizeof(user_ent_name));
165 u.au_name = user_ent_name;
167 return (getauuserent_r(&u));
171 * Find a au_user_ent structure matching the given user name.
174 getauusernam_r(struct au_user_ent *u, const char *name)
176 struct au_user_ent *up;
181 pthread_mutex_lock(&mutex);
184 while ((up = getauuserent_r_locked(u)) != NULL) {
185 if (strcmp(name, u->au_name) == 0) {
186 pthread_mutex_unlock(&mutex);
191 pthread_mutex_unlock(&mutex);
197 getauusernam(const char *name)
199 static char user_ent_name[AU_USER_NAME_MAX];
200 static struct au_user_ent u;
202 bzero(&u, sizeof(u));
203 bzero(user_ent_name, sizeof(user_ent_name));
204 u.au_name = user_ent_name;
206 return (getauusernam_r(&u, name));
210 * Read the default system wide audit classes from audit_control, combine with
211 * the per-user audit class and update the binary preselection mask.
214 au_user_mask(char *username, au_mask_t *mask_p)
216 char auditstring[MAX_AUDITSTRING_LEN + 1];
217 char user_ent_name[AU_USER_NAME_MAX];
218 struct au_user_ent u, *up;
220 bzero(&u, sizeof(u));
221 bzero(user_ent_name, sizeof(user_ent_name));
222 u.au_name = user_ent_name;
225 if ((up = getauusernam_r(&u, username)) != NULL) {
226 if (-1 == getfauditflags(&up->au_always, &up->au_never,
232 /* Read the default system mask. */
233 if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) {
234 if (-1 == getauditflagsbin(auditstring, mask_p))
239 /* No masks defined. */
244 * Generate the process audit state by combining the audit masks passed as
245 * parameters with the system audit masks.
248 getfauditflags(au_mask_t *usremask, au_mask_t *usrdmask, au_mask_t *lastmask)
250 char auditstring[MAX_AUDITSTRING_LEN + 1];
252 if ((usremask == NULL) || (usrdmask == NULL) || (lastmask == NULL))
255 lastmask->am_success = 0;
256 lastmask->am_failure = 0;
258 /* Get the system mask. */
259 if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) {
260 if (getauditflagsbin(auditstring, lastmask) != 0)
264 ADDMASK(lastmask, usremask);
265 SUBMASK(lastmask, usrdmask);