bsm_user.c revision 185573
1185573Srwatson/*- 2185573Srwatson * Copyright (c) 2004 Apple Inc. 3155131Srwatson * Copyright (c) 2006 Robert N. M. Watson 4155131Srwatson * All rights reserved. 5155131Srwatson * 6155131Srwatson * Redistribution and use in source and binary forms, with or without 7155131Srwatson * modification, are permitted provided that the following conditions 8155131Srwatson * are met: 9155131Srwatson * 1. Redistributions of source code must retain the above copyright 10155131Srwatson * notice, this list of conditions and the following disclaimer. 11155131Srwatson * 2. Redistributions in binary form must reproduce the above copyright 12155131Srwatson * notice, this list of conditions and the following disclaimer in the 13155131Srwatson * documentation and/or other materials provided with the distribution. 14185573Srwatson * 3. Neither the name of Apple Inc. ("Apple") nor the names of 15155131Srwatson * its contributors may be used to endorse or promote products derived 16155131Srwatson * from this software without specific prior written permission. 17155131Srwatson * 18155131Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 19155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 22155131Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26155131Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27155131Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28155131Srwatson * POSSIBILITY OF SUCH DAMAGE. 29155131Srwatson * 30185573Srwatson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_user.c#18 $ 31155131Srwatson */ 32155131Srwatson 33185573Srwatson#include <config/config.h> 34185573Srwatson 35155131Srwatson#include <bsm/libbsm.h> 36155131Srwatson 37155131Srwatson#include <string.h> 38155131Srwatson#include <pthread.h> 39155131Srwatson#include <stdio.h> 40155131Srwatson#include <stdlib.h> 41155131Srwatson 42185573Srwatson#ifndef HAVE_STRLCPY 43185573Srwatson#include <compat/strlcpy.h> 44185573Srwatson#endif 45185573Srwatson 46155131Srwatson/* 47155131Srwatson * Parse the contents of the audit_user file into au_user_ent structures. 48155131Srwatson */ 49155131Srwatson 50155131Srwatsonstatic FILE *fp = NULL; 51155131Srwatsonstatic char linestr[AU_LINE_MAX]; 52155131Srwatsonstatic const char *user_delim = ":"; 53155131Srwatson 54155131Srwatsonstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 55155131Srwatson 56155131Srwatson/* 57155131Srwatson * Parse one line from the audit_user file into the au_user_ent structure. 58155131Srwatson */ 59155131Srwatsonstatic struct au_user_ent * 60155131Srwatsonuserfromstr(char *str, struct au_user_ent *u) 61155131Srwatson{ 62155131Srwatson char *username, *always, *never; 63155131Srwatson char *last; 64155131Srwatson 65155131Srwatson username = strtok_r(str, user_delim, &last); 66155131Srwatson always = strtok_r(NULL, user_delim, &last); 67155131Srwatson never = strtok_r(NULL, user_delim, &last); 68155131Srwatson 69155131Srwatson if ((username == NULL) || (always == NULL) || (never == NULL)) 70155131Srwatson return (NULL); 71155131Srwatson 72155131Srwatson if (strlen(username) >= AU_USER_NAME_MAX) 73155131Srwatson return (NULL); 74155131Srwatson 75185573Srwatson strlcpy(u->au_name, username, AU_USER_NAME_MAX); 76155131Srwatson if (getauditflagsbin(always, &(u->au_always)) == -1) 77155131Srwatson return (NULL); 78155131Srwatson 79155131Srwatson if (getauditflagsbin(never, &(u->au_never)) == -1) 80155131Srwatson return (NULL); 81155131Srwatson 82155131Srwatson return (u); 83155131Srwatson} 84155131Srwatson 85155131Srwatson/* 86155131Srwatson * Rewind to beginning of the file 87155131Srwatson */ 88155131Srwatsonstatic void 89155131Srwatsonsetauuser_locked(void) 90155131Srwatson{ 91155131Srwatson 92155131Srwatson if (fp != NULL) 93155131Srwatson fseek(fp, 0, SEEK_SET); 94155131Srwatson} 95155131Srwatson 96155131Srwatsonvoid 97155131Srwatsonsetauuser(void) 98155131Srwatson{ 99155131Srwatson 100155131Srwatson pthread_mutex_lock(&mutex); 101155131Srwatson setauuser_locked(); 102155131Srwatson pthread_mutex_unlock(&mutex); 103155131Srwatson} 104155131Srwatson 105155131Srwatson/* 106155131Srwatson * Close the file descriptor 107155131Srwatson */ 108155131Srwatsonvoid 109155131Srwatsonendauuser(void) 110155131Srwatson{ 111155131Srwatson 112155131Srwatson pthread_mutex_lock(&mutex); 113155131Srwatson if (fp != NULL) { 114155131Srwatson fclose(fp); 115155131Srwatson fp = NULL; 116155131Srwatson } 117155131Srwatson pthread_mutex_unlock(&mutex); 118155131Srwatson} 119155131Srwatson 120155131Srwatson/* 121155131Srwatson * Enumerate the au_user_ent structures from the file 122155131Srwatson */ 123155131Srwatsonstatic struct au_user_ent * 124155131Srwatsongetauuserent_r_locked(struct au_user_ent *u) 125155131Srwatson{ 126155131Srwatson char *nl; 127155131Srwatson 128155131Srwatson if ((fp == NULL) && ((fp = fopen(AUDIT_USER_FILE, "r")) == NULL)) 129155131Srwatson return (NULL); 130155131Srwatson 131155131Srwatson while (1) { 132155131Srwatson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) 133155131Srwatson return (NULL); 134155131Srwatson 135155131Srwatson /* Remove new lines. */ 136155131Srwatson if ((nl = strrchr(linestr, '\n')) != NULL) 137155131Srwatson *nl = '\0'; 138155131Srwatson 139155131Srwatson /* Skip comments. */ 140155131Srwatson if (linestr[0] == '#') 141155131Srwatson continue; 142155131Srwatson 143155131Srwatson /* Get the next structure. */ 144155131Srwatson if (userfromstr(linestr, u) == NULL) 145155131Srwatson return (NULL); 146155131Srwatson break; 147155131Srwatson } 148155131Srwatson 149155131Srwatson return (u); 150155131Srwatson} 151155131Srwatson 152155131Srwatsonstruct au_user_ent * 153155131Srwatsongetauuserent_r(struct au_user_ent *u) 154155131Srwatson{ 155155131Srwatson struct au_user_ent *up; 156155131Srwatson 157155131Srwatson pthread_mutex_lock(&mutex); 158155131Srwatson up = getauuserent_r_locked(u); 159155131Srwatson pthread_mutex_unlock(&mutex); 160155131Srwatson return (up); 161155131Srwatson} 162155131Srwatson 163155131Srwatsonstruct au_user_ent * 164155131Srwatsongetauuserent(void) 165155131Srwatson{ 166155131Srwatson static char user_ent_name[AU_USER_NAME_MAX]; 167155131Srwatson static struct au_user_ent u; 168155131Srwatson 169155131Srwatson bzero(&u, sizeof(u)); 170155131Srwatson bzero(user_ent_name, sizeof(user_ent_name)); 171155131Srwatson u.au_name = user_ent_name; 172155131Srwatson 173155131Srwatson return (getauuserent_r(&u)); 174155131Srwatson} 175155131Srwatson 176155131Srwatson/* 177155131Srwatson * Find a au_user_ent structure matching the given user name. 178155131Srwatson */ 179155131Srwatsonstruct au_user_ent * 180155131Srwatsongetauusernam_r(struct au_user_ent *u, const char *name) 181155131Srwatson{ 182155131Srwatson struct au_user_ent *up; 183155131Srwatson 184155131Srwatson if (name == NULL) 185155131Srwatson return (NULL); 186155131Srwatson 187155131Srwatson pthread_mutex_lock(&mutex); 188155131Srwatson 189155131Srwatson setauuser_locked(); 190155131Srwatson while ((up = getauuserent_r_locked(u)) != NULL) { 191155131Srwatson if (strcmp(name, u->au_name) == 0) { 192155131Srwatson pthread_mutex_unlock(&mutex); 193155131Srwatson return (u); 194155131Srwatson } 195155131Srwatson } 196155131Srwatson 197155131Srwatson pthread_mutex_unlock(&mutex); 198155131Srwatson return (NULL); 199155131Srwatson 200155131Srwatson} 201155131Srwatson 202155131Srwatsonstruct au_user_ent * 203155131Srwatsongetauusernam(const char *name) 204155131Srwatson{ 205155131Srwatson static char user_ent_name[AU_USER_NAME_MAX]; 206155131Srwatson static struct au_user_ent u; 207155131Srwatson 208155131Srwatson bzero(&u, sizeof(u)); 209155131Srwatson bzero(user_ent_name, sizeof(user_ent_name)); 210155131Srwatson u.au_name = user_ent_name; 211155131Srwatson 212155131Srwatson return (getauusernam_r(&u, name)); 213155131Srwatson} 214155131Srwatson 215155131Srwatson/* 216155131Srwatson * Read the default system wide audit classes from audit_control, combine with 217155131Srwatson * the per-user audit class and update the binary preselection mask. 218155131Srwatson */ 219155131Srwatsonint 220155131Srwatsonau_user_mask(char *username, au_mask_t *mask_p) 221155131Srwatson{ 222155131Srwatson char auditstring[MAX_AUDITSTRING_LEN + 1]; 223155131Srwatson char user_ent_name[AU_USER_NAME_MAX]; 224155131Srwatson struct au_user_ent u, *up; 225155131Srwatson 226155131Srwatson bzero(&u, sizeof(u)); 227155131Srwatson bzero(user_ent_name, sizeof(user_ent_name)); 228155131Srwatson u.au_name = user_ent_name; 229155131Srwatson 230155131Srwatson /* Get user mask. */ 231155131Srwatson if ((up = getauusernam_r(&u, username)) != NULL) { 232155131Srwatson if (-1 == getfauditflags(&up->au_always, &up->au_never, 233155131Srwatson mask_p)) 234155131Srwatson return (-1); 235155131Srwatson return (0); 236155131Srwatson } 237155131Srwatson 238155131Srwatson /* Read the default system mask. */ 239155131Srwatson if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) { 240155131Srwatson if (-1 == getauditflagsbin(auditstring, mask_p)) 241155131Srwatson return (-1); 242155131Srwatson return (0); 243155131Srwatson } 244155131Srwatson 245155131Srwatson /* No masks defined. */ 246155131Srwatson return (-1); 247155131Srwatson} 248155131Srwatson 249155131Srwatson/* 250155131Srwatson * Generate the process audit state by combining the audit masks passed as 251155131Srwatson * parameters with the system audit masks. 252155131Srwatson */ 253155131Srwatsonint 254155131Srwatsongetfauditflags(au_mask_t *usremask, au_mask_t *usrdmask, au_mask_t *lastmask) 255155131Srwatson{ 256155131Srwatson char auditstring[MAX_AUDITSTRING_LEN + 1]; 257155131Srwatson 258155131Srwatson if ((usremask == NULL) || (usrdmask == NULL) || (lastmask == NULL)) 259155131Srwatson return (-1); 260155131Srwatson 261155131Srwatson lastmask->am_success = 0; 262155131Srwatson lastmask->am_failure = 0; 263155131Srwatson 264155131Srwatson /* Get the system mask. */ 265155131Srwatson if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) { 266155131Srwatson if (getauditflagsbin(auditstring, lastmask) != 0) 267155131Srwatson return (-1); 268155131Srwatson } 269155131Srwatson 270155131Srwatson ADDMASK(lastmask, usremask); 271155131Srwatson SUBMASK(lastmask, usrdmask); 272155131Srwatson 273155131Srwatson return (0); 274155131Srwatson} 275