X-Git-Url: https://git.saurik.com/apple/syslog.git/blobdiff_plain/5dd30d768c7cd795c2a3b974a6a1809dd8a3becf..1496e7d1dd53a3a0fed695ccb7ea6f5197672810:/syslogd.tproj/dbserver.c diff --git a/syslogd.tproj/dbserver.c b/syslogd.tproj/dbserver.c index a900355..a0a51e0 100644 --- a/syslogd.tproj/dbserver.c +++ b/syslogd.tproj/dbserver.c @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + #include #include #include @@ -9,8 +32,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -20,14 +45,13 @@ #include #include #include -#include +#include +#include #include "daemon.h" #define forever for(;;) #define LIST_SIZE_DELTA 256 -#define MAX_PRE_DISASTER_COUNT 64 -#define MAX_DISASTER_COUNT LIST_SIZE_DELTA #define SEND_NOTIFICATION 0xfadefade @@ -35,31 +59,15 @@ #define SEARCH_FORWARD 1 #define SEARCH_BACKWARD -1 -static asl_store_t *store = NULL; -static int disaster_occurred = 0; - -extern mach_port_t server_port; -extern int archive_enable; -extern uint64_t db_curr_size; -extern uint64_t db_curr_empty; - static pthread_mutex_t db_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER; extern char *asl_list_to_string(asl_search_result_t *list, uint32_t *outlen); extern asl_search_result_t *asl_list_from_string(const char *buf); +extern boolean_t asl_ipc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); +extern uint32_t bb_convert(const char *name); -static time_t last_archive_sod = 0; - -static asl_search_result_t work_queue = {0, 0, NULL}; -static asl_search_result_t disaster_log = {0, 0, NULL}; - -extern boolean_t asl_ipc_server -( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP -); +static task_name_t *client_tasks = NULL; +static uint32_t client_tasks_count = 0; typedef union { @@ -74,227 +82,262 @@ typedef union } asl_reply_msg; void -list_append_msg(asl_search_result_t *list, asl_msg_t *msg, uint32_t retain) +db_ping_store(void) +{ + if ((global.dbtype & DB_TYPE_FILE) && (global.file_db != NULL)) + { + global.store_flags |= STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED; + + /* wake up the output worker thread */ + pthread_cond_signal(&global.work_queue_cond); + } +} + +void +db_asl_open() { - if (list == NULL) return; - if (msg == NULL) return; - - /* - * NB: curr is the list size - * grow list if necessary - */ - if (list->count == list->curr) + uint32_t status; + struct stat sb; + + if ((global.dbtype & DB_TYPE_FILE) && (global.file_db == NULL)) { - if (list->curr == 0) + memset(&sb, 0, sizeof(struct stat)); + if (stat(PATH_ASL_STORE, &sb) == 0) { - list->msg = (asl_msg_t **)calloc(LIST_SIZE_DELTA, sizeof(asl_msg_t *)); + /* must be a directory */ + if ((sb.st_mode & S_IFDIR) == 0) + { + asldebug("error: %s is not a directory", PATH_ASL_STORE); + return; + } } else { - list->msg = (asl_msg_t **)reallocf(list->msg, (list->curr + LIST_SIZE_DELTA) * sizeof(asl_msg_t *)); + if (errno == ENOENT) + { + /* /var/log/asl doesn't exist - create it */ + if (mkdir(PATH_ASL_STORE, 0755) != 0) + { + asldebug("error: can't create data store %s: %s\n", PATH_ASL_STORE, strerror(errno)); + return; + } + } + else + { + /* stat failed for some other reason */ + asldebug("error: can't stat data store %s: %s\n", PATH_ASL_STORE, strerror(errno)); + return; + } } - if (list->msg == NULL) + /* + * One-time store conversion from the old "LongTTL" style to the new "Best Before" style. + * bb_convert returns quickly if the store has already been converted. + */ + status = bb_convert(PATH_ASL_STORE); + if (status != ASL_STATUS_OK) { - list->curr = 0; - list->count = 0; - return; + asldebug("ASL data store conversion failed!: %s\n", asl_core_error(status)); } - list->curr += LIST_SIZE_DELTA; + status = asl_store_open_write(NULL, &(global.file_db)); + if (status != ASL_STATUS_OK) + { + asldebug("asl_store_open_write: %s\n", asl_core_error(status)); + } + else + { + if (global.db_file_max != 0) asl_store_max_file_size(global.file_db, global.db_file_max); + asl_store_signal_sweep(global.file_db); + } } - if (retain != 0) asl_msg_retain(msg); - list->msg[list->count] = msg; - list->count++; -} - -void -disaster_message(asl_msg_t *m) -{ - uint32_t i; - - if (disaster_occurred == 0) + if ((global.dbtype & DB_TYPE_MEMORY) && (global.memory_db == NULL)) { - /* retain last MAX_PRE_DISASTER_COUNT messages */ - while (disaster_log.count >= MAX_PRE_DISASTER_COUNT) + status = asl_memory_open(global.db_memory_max, &(global.memory_db)); + if (status != ASL_STATUS_OK) { - asl_msg_release(disaster_log.msg[0]); - for (i = 1; i < disaster_log.count; i++) disaster_log.msg[i - 1] = disaster_log.msg[i]; - disaster_log.count--; + asldebug("asl_memory_open: %s\n", asl_core_error(status)); } } - if (disaster_log.count < MAX_DISASTER_COUNT) list_append_msg(&disaster_log, m, 1); -} - -void -db_enqueue(asl_msg_t *m) -{ - if (m == NULL) return; - - pthread_mutex_lock(&queue_lock); - list_append_msg(&work_queue, m, 1); - pthread_mutex_unlock(&queue_lock); - pthread_cond_signal(&queue_cond); -} - -asl_msg_t ** -db_dequeue(uint32_t *count) -{ - asl_msg_t **work; - - pthread_mutex_lock(&queue_lock); - pthread_cond_wait(&queue_cond, &queue_lock); - - work = NULL; - *count = 0; - - if (work_queue.count == 0) + if ((global.dbtype & DB_TYPE_MINI) && (global.mini_db == NULL)) { - pthread_mutex_unlock(&queue_lock); - return NULL; + status = asl_mini_memory_open(global.db_mini_max, &(global.mini_db)); + if (status != ASL_STATUS_OK) + { + asldebug("asl_mini_memory_open: %s\n", asl_core_error(status)); + } } - - work = work_queue.msg; - *count = work_queue.count; - - work_queue.count = 0; - work_queue.curr = 0; - work_queue.msg = NULL; - - pthread_mutex_unlock(&queue_lock); - return work; } /* - * Takes messages off the work queue and saves them in the database. + * Takes messages off the work queue and saves them. * Runs in it's own thread. */ void -db_worker() +output_worker() { asl_msg_t **work; - uint64_t msgid; - uint32_t i, count, status; - mach_msg_empty_send_t *msg; + uint32_t i, count; + mach_msg_empty_send_t *empty; kern_return_t kstatus; - msg = (mach_msg_empty_send_t *)calloc(1, sizeof(mach_msg_empty_send_t)); - if (msg == NULL) return; - - msg->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO); - msg->header.msgh_remote_port = server_port; - msg->header.msgh_local_port = MACH_PORT_NULL; - msg->header.msgh_size = sizeof(mach_msg_empty_send_t); - msg->header.msgh_id = SEND_NOTIFICATION; + empty = (mach_msg_empty_send_t *)calloc(1, sizeof(mach_msg_empty_send_t)); + if (empty == NULL) return; forever { count = 0; - work = db_dequeue(&count); - - if (work == NULL) continue; - pthread_mutex_lock(&db_lock); + /* blocks until work is available */ + work = asl_work_dequeue(&count); - if (store == NULL) + if (work == NULL) { - status = asl_store_open(_PATH_ASL_DB, 0, &store); - if (status != ASL_STATUS_OK) + if ((global.dbtype & DB_TYPE_FILE) && (global.store_flags & STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED)) { - disaster_occurred = 1; - store = NULL; + asl_store_sweep_file_cache(global.file_db); + global.store_flags &= ~STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED; } + + continue; } - for (i = 0; (i < count) && (store != NULL); i++) + for (i = 0; i < count; i++) { - msgid = 0; - status = ASL_STATUS_OK; + asl_message_match_and_log(work[i]); + asl_msg_release(work[i]); + } + + free(work); + + if (global.store_flags & STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED) + { + asl_store_sweep_file_cache(global.file_db); + global.store_flags &= ~STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED; + } + + empty->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO); + empty->header.msgh_remote_port = global.self_port; + empty->header.msgh_local_port = MACH_PORT_NULL; + empty->header.msgh_size = sizeof(mach_msg_empty_send_t); + empty->header.msgh_id = SEND_NOTIFICATION; - status = asl_store_save(store, work[i], -1, -1, &msgid); + kstatus = mach_msg(&(empty->header), MACH_SEND_MSG | MACH_SEND_TIMEOUT, empty->header.msgh_size, 0, MACH_PORT_NULL, 2, MACH_PORT_NULL); + } +} + +/* + * Called from asl_action.c to save messgaes to the ASL data store + */ +void +db_save_message(asl_msg_t *msg) +{ + uint64_t msgid; + uint32_t status; + + pthread_mutex_lock(&db_lock); + + db_asl_open(); + + if (global.dbtype & DB_TYPE_FILE) + { + status = asl_store_save(global.file_db, msg); + if (status != ASL_STATUS_OK) + { + /* write failed - reopen & retry */ + asldebug("asl_store_save: %s\n", asl_core_error(status)); + asl_store_close(global.file_db); + global.file_db = NULL; + + db_asl_open(); + status = asl_store_save(global.file_db, msg); if (status != ASL_STATUS_OK) { - /* write failed - reopen store */ - asl_store_close(store); - store = NULL; + asldebug("(retry) asl_store_save: %s\n", asl_core_error(status)); + asl_store_close(global.file_db); + global.file_db = NULL; - status = asl_store_open(_PATH_ASL_DB, 0, &store); - if (status != ASL_STATUS_OK) + global.dbtype |= DB_TYPE_MEMORY; + if (global.memory_db == NULL) { - disaster_occurred = 1; - store = NULL; - } - - /* if the store re-opened, retry the save */ - if (store != NULL) - { - status = asl_store_save(store, work[i], -1, -1, &msgid); + status = asl_memory_open(global.db_memory_max, &(global.memory_db)); if (status != ASL_STATUS_OK) { - disaster_occurred = 1; - store = NULL; + asldebug("asl_memory_open: %s\n", asl_core_error(status)); } } } + } + } + + if (global.dbtype & DB_TYPE_MEMORY) + { + msgid = 0; + status = asl_memory_save(global.memory_db, msg, &msgid); + if (status != ASL_STATUS_OK) + { + /* save failed - reopen & retry*/ + asldebug("asl_memory_save: %s\n", asl_core_error(status)); + asl_memory_close(global.memory_db); + global.memory_db = NULL; - if ((i % 500) == 499) + db_asl_open(); + msgid = 0; + status = asl_memory_save(global.memory_db, msg, &msgid); + if (status != ASL_STATUS_OK) { - pthread_mutex_unlock(&db_lock); - pthread_mutex_lock(&db_lock); + asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status)); + asl_memory_close(global.memory_db); + global.memory_db = NULL; } } + } - db_curr_size = 0; - db_curr_empty = 0; - - if (store != NULL) + if (global.dbtype & DB_TYPE_MINI) + { + status = asl_mini_memory_save(global.mini_db, msg, &msgid); + if (status != ASL_STATUS_OK) { - db_curr_size = (store->record_count + 1) * DB_RECORD_LEN; - db_curr_empty = store->empty_count * DB_RECORD_LEN; + /* save failed - reopen & retry*/ + asldebug("asl_mini_memory_save: %s\n", asl_core_error(status)); + asl_mini_memory_close(global.mini_db); + global.mini_db = NULL; + + db_asl_open(); + status = asl_mini_memory_save(global.mini_db, msg, &msgid); + if (status != ASL_STATUS_OK) + { + asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status)); + asl_mini_memory_close(global.mini_db); + global.mini_db = NULL; + } } + } - pthread_mutex_unlock(&db_lock); - for (i = 0; i < count; i++) asl_msg_release(work[i]); - free(work); + pthread_mutex_unlock(&db_lock); - kstatus = mach_msg(&(msg->header), MACH_SEND_MSG, msg->header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - } } -static char * -disaster_query(aslresponse query, uint32_t *outlen) +void +disaster_message(asl_msg_t *msg) { - asl_search_result_t res; - uint32_t i, j, match; - char *out; - - if (outlen == NULL) return NULL; - *outlen = 0; - - if ((query == NULL) || ((query != NULL) && (query->count == 0))) return asl_list_to_string(&disaster_log, outlen); + uint64_t msgid; + uint32_t status; - memset(&res, 0, sizeof(asl_search_result_t)); + msgid = 0; - for (i = 0; i < disaster_log.count; i++) + if ((global.dbtype & DB_TYPE_MINI) == 0) { - match = 1; - - for (j = 0; (j < query->count) && (match == 1); j++) + if (global.mini_db == NULL) { - match = asl_msg_cmp(query->msg[j], disaster_log.msg[i]); + status = asl_mini_memory_open(global.db_mini_max, &(global.mini_db)); + if (status != ASL_STATUS_OK) asldebug("asl_mini_memory_open: %s\n", asl_core_error(status)); + else asl_mini_memory_save(global.mini_db, msg, &msgid); } - - if (match == 1) list_append_msg(&res, disaster_log.msg[i], 0); } - - if (res.count == 0) return NULL; - - out = asl_list_to_string((aslresponse)&res, outlen); - free(res.msg); - return out; } /* @@ -312,138 +355,73 @@ db_query(aslresponse query, aslresponse *res, uint64_t startid, int count, int f pthread_mutex_lock(&db_lock); - if (store == NULL) - { - status = asl_store_open(_PATH_ASL_DB, 0, &store); - if (status != ASL_STATUS_OK) store = NULL; - } - - status = asl_store_match(store, query, res, lastid, startid, ucount, dir, ruid, rgid); - - pthread_mutex_unlock(&db_lock); - - return status; -} - -/* - * Prune the database. - */ -uint32_t -db_prune(aslresponse query) -{ - uint32_t status; + status = ASL_STATUS_FAILED; - if (disaster_occurred == 1) return ASL_STATUS_FAILED; - - pthread_mutex_lock(&db_lock); - - if (store == NULL) - { - status = asl_store_open(_PATH_ASL_DB, 0, &store); - if (status != ASL_STATUS_OK) store = NULL; - } - - status = asl_store_prune(store, query); + if (global.dbtype & DB_TYPE_MEMORY) status = asl_memory_match(global.memory_db, query, res, lastid, startid, ucount, dir, ruid, rgid); + else status = asl_mini_memory_match(global.mini_db, query, res, lastid, startid, ucount, dir); pthread_mutex_unlock(&db_lock); return status; } -/* - * Database archiver - */ -uint32_t -db_archive(time_t cut, uint64_t max_size) +static void +register_session(task_name_t task_name, pid_t pid) { - time_t sod; - struct tm ctm; - char *archive_file_name; - uint32_t status; + mach_port_t previous; + uint32_t i; - archive_file_name = NULL; - memset(&ctm, 0, sizeof(struct tm)); + if (task_name == MACH_PORT_NULL) return; + if (global.dead_session_port == MACH_PORT_NULL) return; - if (localtime_r((const time_t *)&cut, &ctm) == NULL) return ASL_STATUS_FAILED; + for (i = 0; i < client_tasks_count; i++) if (task_name == client_tasks[i]) return; - if (archive_enable != 0) - { - asprintf(&archive_file_name, "%s/asl.%d.%02d.%02d.archive", _PATH_ASL_DIR, ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); - if (archive_file_name == NULL) return ASL_STATUS_NO_MEMORY; - } + if (client_tasks_count == 0) client_tasks = (task_name_t *)calloc(1, sizeof(task_name_t)); + else client_tasks = (task_name_t *)reallocf(client_tasks, (client_tasks_count + 1) * sizeof(task_name_t)); - ctm.tm_sec = 0; - ctm.tm_min = 0; - ctm.tm_hour = 0; + if (client_tasks == NULL) return; + client_tasks[client_tasks_count] = task_name; + client_tasks_count++; - sod = mktime(&ctm); + asldebug("register_session: %u PID %d\n", (unsigned int)task_name, (int)pid); - /* if the day changed, archive message received before the start of the day */ - if (sod > last_archive_sod) - { - last_archive_sod = sod; - status = db_archive(sod - 1, 0); - /* NB return status not checked */ - } + /* register for port death notification */ + mach_port_request_notification(mach_task_self(), task_name, MACH_NOTIFY_DEAD_NAME, 0, global.dead_session_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); + mach_port_deallocate(mach_task_self(), previous); - pthread_mutex_lock(&db_lock); + asl_client_count_increment(); +} - if (store == NULL) - { - status = asl_store_open(_PATH_ASL_DB, 0, &store); - if (status != ASL_STATUS_OK) store = NULL; - } +static void +cancel_session(task_name_t task_name) +{ + uint32_t i; - status = asl_store_archive(store, cut, archive_file_name); - if (status == ASL_STATUS_OK) status = asl_store_compact(store); - if ((status == ASL_STATUS_OK) && (max_size > 0)) status = asl_store_truncate(store, max_size, archive_file_name); + for (i = 0; (i < client_tasks_count) && (task_name != client_tasks[i]); i++); - db_curr_size = 0; - db_curr_empty = 0; + if (i >= client_tasks_count) return; - if (store != NULL) + if (client_tasks_count == 1) { - db_curr_size = (store->record_count + 1) * DB_RECORD_LEN; - db_curr_empty = store->empty_count * DB_RECORD_LEN; + free(client_tasks); + client_tasks = NULL; + client_tasks_count = 0; } - - pthread_mutex_unlock(&db_lock); - - if (archive_file_name != NULL) free(archive_file_name); - - return status; -} - -uint32_t -db_compact(void) -{ - uint32_t status; - - pthread_mutex_lock(&db_lock); - - if (store == NULL) + else { - status = asl_store_open(_PATH_ASL_DB, 0, &store); - if (status != ASL_STATUS_OK) - { - pthread_mutex_unlock(&db_lock); - return status; - } + for (i++; i < client_tasks_count; i++) client_tasks[i-1] = client_tasks[i]; + client_tasks_count--; + client_tasks = (task_name_t *)reallocf(client_tasks, client_tasks_count * sizeof(task_name_t)); } - - status = asl_store_compact(store); - - db_curr_size = (store->record_count + 1) * DB_RECORD_LEN; - db_curr_empty = store->empty_count * DB_RECORD_LEN; - - pthread_mutex_unlock(&db_lock); - return status; + asldebug("cancel_session: %u\n", (unsigned int)task_name); + mach_port_destroy(mach_task_self(), task_name); + asl_client_count_decrement(); } /* * Receives messages on the "com.apple.system.logger" mach port. - * Services database search and pruning requests. + * Services database search requests. * Runs in it's own thread. */ void @@ -456,6 +434,7 @@ database_server() uint32_t rbits, sbits; uint32_t flags, snooze; struct timeval now, send_time; + mach_dead_name_notification_t *deadname; send_time.tv_sec = 0; send_time.tv_usec = 0; @@ -465,7 +444,7 @@ database_server() reply = (asl_reply_msg *)calloc(1, rps); if (reply == NULL) return; - rbits = MACH_RCV_MSG | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0); + rbits = MACH_RCV_MSG | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0); sbits = MACH_SEND_MSG | MACH_SEND_TIMEOUT; forever @@ -495,7 +474,7 @@ database_server() request = (asl_request_msg *)calloc(1, rqs); if (request == NULL) continue; - request->head.msgh_local_port = server_port; + request->head.msgh_local_port = global.server_port; request->head.msgh_size = rqs; memset(reply, 0, rps); @@ -503,7 +482,7 @@ database_server() flags = rbits; if (snooze != 0) flags |= MACH_RCV_TIMEOUT; - kstatus = mach_msg(&(request->head), flags, 0, rqs, server_port, snooze, MACH_PORT_NULL); + kstatus = mach_msg(&(request->head), flags, 0, rqs, global.listen_set, snooze, MACH_PORT_NULL); if (request->head.msgh_id == SEND_NOTIFICATION) { if (send_time.tv_sec == 0) @@ -516,6 +495,14 @@ database_server() continue; } + if (request->head.msgh_id == MACH_NOTIFY_DEAD_NAME) + { + deadname = (mach_dead_name_notification_t *)request; + cancel_session(deadname->not_port); + free(request); + continue; + } + kstatus = asl_ipc_server(&(request->head), &(reply->head)); kstatus = mach_msg(&(reply->head), sbits, reply->head.msgh_size, 0, MACH_PORT_NULL, 10, MACH_PORT_NULL); if (kstatus == MACH_SEND_INVALID_DEST) @@ -554,33 +541,19 @@ __asl_server_query vm_deallocate(mach_task_self(), (vm_address_t)request, requestCnt); res = NULL; - /* - * If the database went offline (i.e. the filesystem died), - * just search the disaster_log messages. - */ - if (disaster_occurred == 1) + *status = db_query(query, &res, startid, count, flags, lastid, token->val[0], token->val[1]); + + aslresponse_free(query); + if (*status != ASL_STATUS_OK) { - out = NULL; - outlen = 0; - out = disaster_query(query, &outlen); - aslresponse_free(query); + if (res != NULL) aslresponse_free(res); + return KERN_SUCCESS; } - else - { - *status = db_query(query, &res, startid, count, flags, lastid, token->val[0], token->val[1]); - aslresponse_free(query); - if (*status != ASL_STATUS_OK) - { - if (res != NULL) aslresponse_free(res); - return KERN_SUCCESS; - } - - out = NULL; - outlen = 0; - out = asl_list_to_string((asl_search_result_t *)res, &outlen); - aslresponse_free(res); - } + out = NULL; + outlen = 0; + out = asl_list_to_string((asl_search_result_t *)res, &outlen); + aslresponse_free(res); if ((out == NULL) || (outlen == 0)) return KERN_SUCCESS; @@ -630,25 +603,53 @@ __asl_server_prune security_token_t *token ) { - aslresponse query; + return KERN_SUCCESS; +} - *status = ASL_STATUS_OK; +kern_return_t +__asl_server_message +( + mach_port_t server, + caddr_t message, + mach_msg_type_number_t messageCnt, + audit_token_t token +) +{ + asl_msg_t *m; + char tmp[64]; + uid_t uid; + gid_t gid; + pid_t pid; + kern_return_t kstatus; + mach_port_name_t client; - if (request == NULL) return KERN_SUCCESS; + asldebug("__asl_server_message: %s\n", (message == NULL) ? "NULL" : message); - query = asl_list_from_string(request); + m = asl_msg_from_string(message); + vm_deallocate(mach_task_self(), (vm_address_t)message, messageCnt); - vm_deallocate(mach_task_self(), (vm_address_t)request, requestCnt); + uid = (uid_t)-1; + gid = (gid_t)-1; + pid = (gid_t)-1; + audit_token_to_au32(token, NULL, &uid, &gid, NULL, NULL, &pid, NULL, NULL); - /* only root may prune the database */ - if (token->val[0] != 0) - { - *status = ASL_STATUS_FAILED; - return KERN_SUCCESS; - } + client = MACH_PORT_NULL; + kstatus = task_name_for_pid(mach_task_self(), pid, &client); + if (kstatus == KERN_SUCCESS) register_session(client, pid); - *status = db_prune(query); - aslresponse_free(query); + if (m == NULL) return KERN_SUCCESS; + + snprintf(tmp, sizeof(tmp), "%d", uid); + asl_set(m, ASL_KEY_UID, tmp); + + snprintf(tmp, sizeof(tmp), "%d", gid); + asl_set(m, ASL_KEY_GID, tmp); + + snprintf(tmp, sizeof(tmp), "%d", pid); + asl_set(m, ASL_KEY_PID, tmp); + + /* verify and enqueue for processing */ + asl_enqueue_message(SOURCE_ASL_MESSAGE, NULL, m); return KERN_SUCCESS; }