bsm_user.c revision 155131
1155131Srwatson/* 2155131Srwatson * Copyright (c) 2004 Apple Computer, 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. 14155131Srwatson * 3. Neither the name of Apple Computer, 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 * 30155131Srwatson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_user.c#14 $ 31155131Srwatson */ 32155131Srwatson 33155131Srwatson#include <bsm/libbsm.h> 34155131Srwatson 35155131Srwatson#include <string.h> 36155131Srwatson#include <pthread.h> 37155131Srwatson#include <stdio.h> 38155131Srwatson#include <stdlib.h> 39155131Srwatson 40155131Srwatson/* 41155131Srwatson * Parse the contents of the audit_user file into au_user_ent structures. 42155131Srwatson */ 43155131Srwatson 44155131Srwatsonstatic FILE *fp = NULL; 45155131Srwatsonstatic char linestr[AU_LINE_MAX]; 46155131Srwatsonstatic const char *user_delim = ":"; 47155131Srwatson 48155131Srwatsonstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 49155131Srwatson 50155131Srwatson/* 51155131Srwatson * Parse one line from the audit_user file into the au_user_ent structure. 52155131Srwatson */ 53155131Srwatsonstatic struct au_user_ent * 54155131Srwatsonuserfromstr(char *str, struct au_user_ent *u) 55155131Srwatson{ 56155131Srwatson char *username, *always, *never; 57155131Srwatson char *last; 58155131Srwatson 59155131Srwatson username = strtok_r(str, user_delim, &last); 60155131Srwatson always = strtok_r(NULL, user_delim, &last); 61155131Srwatson never = strtok_r(NULL, user_delim, &last); 62155131Srwatson 63155131Srwatson if ((username == NULL) || (always == NULL) || (never == NULL)) 64155131Srwatson return (NULL); 65155131Srwatson 66155131Srwatson if (strlen(username) >= AU_USER_NAME_MAX) 67155131Srwatson return (NULL); 68155131Srwatson 69155131Srwatson strcpy(u->au_name, username); 70155131Srwatson if (getauditflagsbin(always, &(u->au_always)) == -1) 71155131Srwatson return (NULL); 72155131Srwatson 73155131Srwatson if (getauditflagsbin(never, &(u->au_never)) == -1) 74155131Srwatson return (NULL); 75155131Srwatson 76155131Srwatson return (u); 77155131Srwatson} 78155131Srwatson 79155131Srwatson/* 80155131Srwatson * Rewind to beginning of the file 81155131Srwatson */ 82155131Srwatsonstatic void 83155131Srwatsonsetauuser_locked(void) 84155131Srwatson{ 85155131Srwatson 86155131Srwatson if (fp != NULL) 87155131Srwatson fseek(fp, 0, SEEK_SET); 88155131Srwatson} 89155131Srwatson 90155131Srwatsonvoid 91155131Srwatsonsetauuser(void) 92155131Srwatson{ 93155131Srwatson 94155131Srwatson pthread_mutex_lock(&mutex); 95155131Srwatson setauuser_locked(); 96155131Srwatson pthread_mutex_unlock(&mutex); 97155131Srwatson} 98155131Srwatson 99155131Srwatson/* 100155131Srwatson * Close the file descriptor 101155131Srwatson */ 102155131Srwatsonvoid 103155131Srwatsonendauuser(void) 104155131Srwatson{ 105155131Srwatson 106155131Srwatson pthread_mutex_lock(&mutex); 107155131Srwatson if (fp != NULL) { 108155131Srwatson fclose(fp); 109155131Srwatson fp = NULL; 110155131Srwatson } 111155131Srwatson pthread_mutex_unlock(&mutex); 112155131Srwatson} 113155131Srwatson 114155131Srwatson/* 115155131Srwatson * Enumerate the au_user_ent structures from the file 116155131Srwatson */ 117155131Srwatsonstatic struct au_user_ent * 118155131Srwatsongetauuserent_r_locked(struct au_user_ent *u) 119155131Srwatson{ 120155131Srwatson char *nl; 121155131Srwatson 122155131Srwatson if ((fp == NULL) && ((fp = fopen(AUDIT_USER_FILE, "r")) == NULL)) 123155131Srwatson return (NULL); 124155131Srwatson 125155131Srwatson while (1) { 126155131Srwatson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) 127155131Srwatson return (NULL); 128155131Srwatson 129155131Srwatson /* Remove new lines. */ 130155131Srwatson if ((nl = strrchr(linestr, '\n')) != NULL) 131155131Srwatson *nl = '\0'; 132155131Srwatson 133155131Srwatson /* Skip comments. */ 134155131Srwatson if (linestr[0] == '#') 135155131Srwatson continue; 136155131Srwatson 137155131Srwatson /* Get the next structure. */ 138155131Srwatson if (userfromstr(linestr, u) == NULL) 139155131Srwatson return (NULL); 140155131Srwatson break; 141155131Srwatson } 142155131Srwatson 143155131Srwatson return (u); 144155131Srwatson} 145155131Srwatson 146155131Srwatsonstruct au_user_ent * 147155131Srwatsongetauuserent_r(struct au_user_ent *u) 148155131Srwatson{ 149155131Srwatson struct au_user_ent *up; 150155131Srwatson 151155131Srwatson pthread_mutex_lock(&mutex); 152155131Srwatson up = getauuserent_r_locked(u); 153155131Srwatson pthread_mutex_unlock(&mutex); 154155131Srwatson return (up); 155155131Srwatson} 156155131Srwatson 157155131Srwatsonstruct au_user_ent * 158155131Srwatsongetauuserent(void) 159155131Srwatson{ 160155131Srwatson static char user_ent_name[AU_USER_NAME_MAX]; 161155131Srwatson static struct au_user_ent u; 162155131Srwatson 163155131Srwatson bzero(&u, sizeof(u)); 164155131Srwatson bzero(user_ent_name, sizeof(user_ent_name)); 165155131Srwatson u.au_name = user_ent_name; 166155131Srwatson 167155131Srwatson return (getauuserent_r(&u)); 168155131Srwatson} 169155131Srwatson 170155131Srwatson/* 171155131Srwatson * Find a au_user_ent structure matching the given user name. 172155131Srwatson */ 173155131Srwatsonstruct au_user_ent * 174155131Srwatsongetauusernam_r(struct au_user_ent *u, const char *name) 175155131Srwatson{ 176155131Srwatson struct au_user_ent *up; 177155131Srwatson 178155131Srwatson if (name == NULL) 179155131Srwatson return (NULL); 180155131Srwatson 181155131Srwatson pthread_mutex_lock(&mutex); 182155131Srwatson 183155131Srwatson setauuser_locked(); 184155131Srwatson while ((up = getauuserent_r_locked(u)) != NULL) { 185155131Srwatson if (strcmp(name, u->au_name) == 0) { 186155131Srwatson pthread_mutex_unlock(&mutex); 187155131Srwatson return (u); 188155131Srwatson } 189155131Srwatson } 190155131Srwatson 191155131Srwatson pthread_mutex_unlock(&mutex); 192155131Srwatson return (NULL); 193155131Srwatson 194155131Srwatson} 195155131Srwatson 196155131Srwatsonstruct au_user_ent * 197155131Srwatsongetauusernam(const char *name) 198155131Srwatson{ 199155131Srwatson static char user_ent_name[AU_USER_NAME_MAX]; 200155131Srwatson static struct au_user_ent u; 201155131Srwatson 202155131Srwatson bzero(&u, sizeof(u)); 203155131Srwatson bzero(user_ent_name, sizeof(user_ent_name)); 204155131Srwatson u.au_name = user_ent_name; 205155131Srwatson 206155131Srwatson return (getauusernam_r(&u, name)); 207155131Srwatson} 208155131Srwatson 209155131Srwatson/* 210155131Srwatson * Read the default system wide audit classes from audit_control, combine with 211155131Srwatson * the per-user audit class and update the binary preselection mask. 212155131Srwatson */ 213155131Srwatsonint 214155131Srwatsonau_user_mask(char *username, au_mask_t *mask_p) 215155131Srwatson{ 216155131Srwatson char auditstring[MAX_AUDITSTRING_LEN + 1]; 217155131Srwatson char user_ent_name[AU_USER_NAME_MAX]; 218155131Srwatson struct au_user_ent u, *up; 219155131Srwatson 220155131Srwatson bzero(&u, sizeof(u)); 221155131Srwatson bzero(user_ent_name, sizeof(user_ent_name)); 222155131Srwatson u.au_name = user_ent_name; 223155131Srwatson 224155131Srwatson /* Get user mask. */ 225155131Srwatson if ((up = getauusernam_r(&u, username)) != NULL) { 226155131Srwatson if (-1 == getfauditflags(&up->au_always, &up->au_never, 227155131Srwatson mask_p)) 228155131Srwatson return (-1); 229155131Srwatson return (0); 230155131Srwatson } 231155131Srwatson 232155131Srwatson /* Read the default system mask. */ 233155131Srwatson if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) { 234155131Srwatson if (-1 == getauditflagsbin(auditstring, mask_p)) 235155131Srwatson return (-1); 236155131Srwatson return (0); 237155131Srwatson } 238155131Srwatson 239155131Srwatson /* No masks defined. */ 240155131Srwatson return (-1); 241155131Srwatson} 242155131Srwatson 243155131Srwatson/* 244155131Srwatson * Generate the process audit state by combining the audit masks passed as 245155131Srwatson * parameters with the system audit masks. 246155131Srwatson */ 247155131Srwatsonint 248155131Srwatsongetfauditflags(au_mask_t *usremask, au_mask_t *usrdmask, au_mask_t *lastmask) 249155131Srwatson{ 250155131Srwatson char auditstring[MAX_AUDITSTRING_LEN + 1]; 251155131Srwatson 252155131Srwatson if ((usremask == NULL) || (usrdmask == NULL) || (lastmask == NULL)) 253155131Srwatson return (-1); 254155131Srwatson 255155131Srwatson lastmask->am_success = 0; 256155131Srwatson lastmask->am_failure = 0; 257155131Srwatson 258155131Srwatson /* Get the system mask. */ 259155131Srwatson if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) { 260155131Srwatson if (getauditflagsbin(auditstring, lastmask) != 0) 261155131Srwatson return (-1); 262155131Srwatson } 263155131Srwatson 264155131Srwatson ADDMASK(lastmask, usremask); 265155131Srwatson SUBMASK(lastmask, usrdmask); 266155131Srwatson 267155131Srwatson return (0); 268155131Srwatson} 269