]>
Commit | Line | Data |
---|---|---|
57b0aad2 | 1 | /* |
c4fdb7d1 | 2 | * Copyright (c) 2007-2009 Apple Inc. All rights reserved. |
57b0aad2 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
5dd30d76 A |
24 | #include <sys/types.h> |
25 | #include <sys/stat.h> | |
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <unistd.h> | |
29 | #include <sys/socket.h> | |
30 | #include <sys/un.h> | |
31 | #include <sys/ipc.h> | |
32 | #include <sys/mman.h> | |
33 | #include <sys/fcntl.h> | |
34 | #include <sys/signal.h> | |
57b0aad2 | 35 | #include <sys/errno.h> |
5dd30d76 A |
36 | #include <mach/mach.h> |
37 | #include <mach/mach_error.h> | |
c4fdb7d1 | 38 | #include <bsm/libbsm.h> |
5dd30d76 A |
39 | #include <errno.h> |
40 | #include <netinet/in.h> | |
41 | #include <sys/event.h> | |
42 | #include <servers/bootstrap.h> | |
43 | #include <pthread.h> | |
44 | #include <notify.h> | |
45 | #include <sys/time.h> | |
46 | #include <asl.h> | |
47 | #include <asl_ipc.h> | |
c4fdb7d1 | 48 | #include <asl_ipc_server.h> |
57b0aad2 | 49 | #include <asl_core.h> |
5dd30d76 A |
50 | #include "daemon.h" |
51 | ||
52 | #define forever for(;;) | |
53 | ||
54 | #define LIST_SIZE_DELTA 256 | |
5dd30d76 A |
55 | |
56 | #define SEND_NOTIFICATION 0xfadefade | |
57 | ||
58 | #define QUERY_FLAG_SEARCH_REVERSE 0x00000001 | |
59 | #define SEARCH_FORWARD 1 | |
60 | #define SEARCH_BACKWARD -1 | |
61 | ||
5dd30d76 | 62 | static pthread_mutex_t db_lock = PTHREAD_MUTEX_INITIALIZER; |
5dd30d76 A |
63 | |
64 | extern char *asl_list_to_string(asl_search_result_t *list, uint32_t *outlen); | |
65 | extern asl_search_result_t *asl_list_from_string(const char *buf); | |
57b0aad2 | 66 | extern boolean_t asl_ipc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); |
c4fdb7d1 | 67 | extern uint32_t bb_convert(const char *name); |
5dd30d76 | 68 | |
c4fdb7d1 A |
69 | static task_name_t *client_tasks = NULL; |
70 | static uint32_t client_tasks_count = 0; | |
5dd30d76 A |
71 | |
72 | typedef union | |
73 | { | |
74 | mach_msg_header_t head; | |
75 | union __RequestUnion__asl_ipc_subsystem request; | |
76 | } asl_request_msg; | |
77 | ||
78 | typedef union | |
79 | { | |
80 | mach_msg_header_t head; | |
81 | union __ReplyUnion__asl_ipc_subsystem reply; | |
82 | } asl_reply_msg; | |
83 | ||
84 | void | |
c4fdb7d1 | 85 | db_ping_store(void) |
5dd30d76 | 86 | { |
57b0aad2 | 87 | if ((global.dbtype & DB_TYPE_FILE) && (global.file_db != NULL)) |
5dd30d76 | 88 | { |
c4fdb7d1 | 89 | global.store_flags |= STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED; |
5dd30d76 | 90 | |
c4fdb7d1 A |
91 | /* wake up the output worker thread */ |
92 | pthread_cond_signal(&global.work_queue_cond); | |
5dd30d76 | 93 | } |
5dd30d76 A |
94 | } |
95 | ||
57b0aad2 A |
96 | void |
97 | db_asl_open() | |
98 | { | |
99 | uint32_t status; | |
100 | struct stat sb; | |
101 | ||
102 | if ((global.dbtype & DB_TYPE_FILE) && (global.file_db == NULL)) | |
103 | { | |
104 | memset(&sb, 0, sizeof(struct stat)); | |
105 | if (stat(PATH_ASL_STORE, &sb) == 0) | |
106 | { | |
107 | /* must be a directory */ | |
108 | if ((sb.st_mode & S_IFDIR) == 0) | |
109 | { | |
110 | asldebug("error: %s is not a directory", PATH_ASL_STORE); | |
111 | return; | |
112 | } | |
113 | } | |
114 | else | |
115 | { | |
116 | if (errno == ENOENT) | |
117 | { | |
118 | /* /var/log/asl doesn't exist - create it */ | |
119 | if (mkdir(PATH_ASL_STORE, 0755) != 0) | |
120 | { | |
121 | asldebug("error: can't create data store %s: %s\n", PATH_ASL_STORE, strerror(errno)); | |
122 | return; | |
c4fdb7d1 | 123 | } |
57b0aad2 A |
124 | } |
125 | else | |
126 | { | |
127 | /* stat failed for some other reason */ | |
128 | asldebug("error: can't stat data store %s: %s\n", PATH_ASL_STORE, strerror(errno)); | |
129 | return; | |
130 | } | |
131 | } | |
132 | ||
c4fdb7d1 A |
133 | /* |
134 | * One-time store conversion from the old "LongTTL" style to the new "Best Before" style. | |
135 | * bb_convert returns quickly if the store has already been converted. | |
136 | */ | |
137 | status = bb_convert(PATH_ASL_STORE); | |
138 | if (status != ASL_STATUS_OK) | |
139 | { | |
140 | asldebug("ASL data store conversion failed!: %s\n", asl_core_error(status)); | |
141 | } | |
142 | ||
57b0aad2 A |
143 | status = asl_store_open_write(NULL, &(global.file_db)); |
144 | if (status != ASL_STATUS_OK) | |
145 | { | |
146 | asldebug("asl_store_open_write: %s\n", asl_core_error(status)); | |
147 | } | |
148 | else | |
149 | { | |
150 | if (global.db_file_max != 0) asl_store_max_file_size(global.file_db, global.db_file_max); | |
c4fdb7d1 | 151 | asl_store_signal_sweep(global.file_db); |
57b0aad2 A |
152 | } |
153 | } | |
154 | ||
155 | if ((global.dbtype & DB_TYPE_MEMORY) && (global.memory_db == NULL)) | |
156 | { | |
157 | status = asl_memory_open(global.db_memory_max, &(global.memory_db)); | |
158 | if (status != ASL_STATUS_OK) | |
159 | { | |
160 | asldebug("asl_memory_open: %s\n", asl_core_error(status)); | |
161 | } | |
162 | } | |
163 | ||
164 | if ((global.dbtype & DB_TYPE_MINI) && (global.mini_db == NULL)) | |
165 | { | |
166 | status = asl_mini_memory_open(global.db_mini_max, &(global.mini_db)); | |
167 | if (status != ASL_STATUS_OK) | |
168 | { | |
169 | asldebug("asl_mini_memory_open: %s\n", asl_core_error(status)); | |
170 | } | |
171 | } | |
172 | } | |
173 | ||
5dd30d76 | 174 | /* |
c4fdb7d1 | 175 | * Takes messages off the work queue and saves them. |
5dd30d76 A |
176 | * Runs in it's own thread. |
177 | */ | |
178 | void | |
c4fdb7d1 | 179 | output_worker() |
5dd30d76 A |
180 | { |
181 | asl_msg_t **work; | |
c4fdb7d1 A |
182 | uint32_t i, count; |
183 | mach_msg_empty_send_t *empty; | |
5dd30d76 A |
184 | kern_return_t kstatus; |
185 | ||
c4fdb7d1 A |
186 | empty = (mach_msg_empty_send_t *)calloc(1, sizeof(mach_msg_empty_send_t)); |
187 | if (empty == NULL) return; | |
5dd30d76 A |
188 | |
189 | forever | |
190 | { | |
191 | count = 0; | |
5dd30d76 | 192 | |
c4fdb7d1 A |
193 | /* blocks until work is available */ |
194 | work = asl_work_dequeue(&count); | |
5dd30d76 | 195 | |
c4fdb7d1 A |
196 | if (work == NULL) |
197 | { | |
198 | if ((global.dbtype & DB_TYPE_FILE) && (global.store_flags & STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED)) | |
199 | { | |
200 | asl_store_sweep_file_cache(global.file_db); | |
201 | global.store_flags &= ~STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED; | |
202 | } | |
5dd30d76 | 203 | |
c4fdb7d1 A |
204 | continue; |
205 | } | |
57b0aad2 A |
206 | |
207 | for (i = 0; i < count; i++) | |
5dd30d76 | 208 | { |
c4fdb7d1 A |
209 | asl_message_match_and_log(work[i]); |
210 | asl_msg_release(work[i]); | |
211 | } | |
5dd30d76 | 212 | |
c4fdb7d1 A |
213 | free(work); |
214 | ||
215 | if (global.store_flags & STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED) | |
216 | { | |
217 | asl_store_sweep_file_cache(global.file_db); | |
218 | global.store_flags &= ~STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED; | |
219 | } | |
220 | ||
221 | empty->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO); | |
222 | empty->header.msgh_remote_port = global.self_port; | |
223 | empty->header.msgh_local_port = MACH_PORT_NULL; | |
224 | empty->header.msgh_size = sizeof(mach_msg_empty_send_t); | |
225 | empty->header.msgh_id = SEND_NOTIFICATION; | |
226 | ||
227 | kstatus = mach_msg(&(empty->header), MACH_SEND_MSG | MACH_SEND_TIMEOUT, empty->header.msgh_size, 0, MACH_PORT_NULL, 2, MACH_PORT_NULL); | |
228 | } | |
229 | } | |
230 | ||
231 | /* | |
232 | * Called from asl_action.c to save messgaes to the ASL data store | |
233 | */ | |
234 | void | |
235 | db_save_message(asl_msg_t *msg) | |
236 | { | |
237 | uint64_t msgid; | |
238 | uint32_t status; | |
239 | ||
240 | pthread_mutex_lock(&db_lock); | |
241 | ||
242 | db_asl_open(); | |
5dd30d76 | 243 | |
c4fdb7d1 A |
244 | if (global.dbtype & DB_TYPE_FILE) |
245 | { | |
246 | status = asl_store_save(global.file_db, msg); | |
247 | if (status != ASL_STATUS_OK) | |
248 | { | |
249 | /* write failed - reopen & retry */ | |
250 | asldebug("asl_store_save: %s\n", asl_core_error(status)); | |
251 | asl_store_close(global.file_db); | |
252 | global.file_db = NULL; | |
253 | ||
254 | db_asl_open(); | |
255 | status = asl_store_save(global.file_db, msg); | |
256 | if (status != ASL_STATUS_OK) | |
5dd30d76 | 257 | { |
c4fdb7d1 A |
258 | asldebug("(retry) asl_store_save: %s\n", asl_core_error(status)); |
259 | asl_store_close(global.file_db); | |
260 | global.file_db = NULL; | |
261 | ||
262 | global.dbtype |= DB_TYPE_MEMORY; | |
263 | if (global.memory_db == NULL) | |
5dd30d76 | 264 | { |
c4fdb7d1 | 265 | status = asl_memory_open(global.db_memory_max, &(global.memory_db)); |
57b0aad2 A |
266 | if (status != ASL_STATUS_OK) |
267 | { | |
c4fdb7d1 | 268 | asldebug("asl_memory_open: %s\n", asl_core_error(status)); |
57b0aad2 | 269 | } |
5dd30d76 | 270 | } |
57b0aad2 | 271 | } |
c4fdb7d1 A |
272 | } |
273 | } | |
5dd30d76 | 274 | |
c4fdb7d1 A |
275 | if (global.dbtype & DB_TYPE_MEMORY) |
276 | { | |
277 | msgid = 0; | |
278 | status = asl_memory_save(global.memory_db, msg, &msgid); | |
279 | if (status != ASL_STATUS_OK) | |
280 | { | |
281 | /* save failed - reopen & retry*/ | |
282 | asldebug("asl_memory_save: %s\n", asl_core_error(status)); | |
283 | asl_memory_close(global.memory_db); | |
284 | global.memory_db = NULL; | |
285 | ||
286 | db_asl_open(); | |
287 | msgid = 0; | |
288 | status = asl_memory_save(global.memory_db, msg, &msgid); | |
289 | if (status != ASL_STATUS_OK) | |
57b0aad2 | 290 | { |
c4fdb7d1 A |
291 | asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status)); |
292 | asl_memory_close(global.memory_db); | |
293 | global.memory_db = NULL; | |
5dd30d76 | 294 | } |
c4fdb7d1 A |
295 | } |
296 | } | |
5dd30d76 | 297 | |
c4fdb7d1 A |
298 | if (global.dbtype & DB_TYPE_MINI) |
299 | { | |
300 | status = asl_mini_memory_save(global.mini_db, msg, &msgid); | |
301 | if (status != ASL_STATUS_OK) | |
302 | { | |
303 | /* save failed - reopen & retry*/ | |
304 | asldebug("asl_mini_memory_save: %s\n", asl_core_error(status)); | |
305 | asl_mini_memory_close(global.mini_db); | |
306 | global.mini_db = NULL; | |
307 | ||
308 | db_asl_open(); | |
309 | status = asl_mini_memory_save(global.mini_db, msg, &msgid); | |
310 | if (status != ASL_STATUS_OK) | |
5dd30d76 | 311 | { |
c4fdb7d1 A |
312 | asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status)); |
313 | asl_mini_memory_close(global.mini_db); | |
314 | global.mini_db = NULL; | |
5dd30d76 A |
315 | } |
316 | } | |
c4fdb7d1 | 317 | } |
5dd30d76 | 318 | |
5dd30d76 | 319 | |
c4fdb7d1 | 320 | pthread_mutex_unlock(&db_lock); |
5dd30d76 | 321 | |
5dd30d76 A |
322 | } |
323 | ||
57b0aad2 A |
324 | void |
325 | disaster_message(asl_msg_t *msg) | |
5dd30d76 | 326 | { |
57b0aad2 A |
327 | uint64_t msgid; |
328 | uint32_t status; | |
5dd30d76 | 329 | |
57b0aad2 | 330 | msgid = 0; |
5dd30d76 | 331 | |
57b0aad2 | 332 | if ((global.dbtype & DB_TYPE_MINI) == 0) |
5dd30d76 | 333 | { |
57b0aad2 | 334 | if (global.mini_db == NULL) |
5dd30d76 | 335 | { |
57b0aad2 A |
336 | status = asl_mini_memory_open(global.db_mini_max, &(global.mini_db)); |
337 | if (status != ASL_STATUS_OK) asldebug("asl_mini_memory_open: %s\n", asl_core_error(status)); | |
338 | else asl_mini_memory_save(global.mini_db, msg, &msgid); | |
5dd30d76 | 339 | } |
5dd30d76 | 340 | } |
5dd30d76 A |
341 | } |
342 | ||
343 | /* | |
344 | * Do a database search. | |
345 | */ | |
346 | uint32_t | |
347 | db_query(aslresponse query, aslresponse *res, uint64_t startid, int count, int flags, uint64_t *lastid, int32_t ruid, int32_t rgid) | |
348 | { | |
349 | uint32_t status, ucount; | |
350 | int32_t dir; | |
351 | ||
352 | ucount = count; | |
353 | dir = SEARCH_FORWARD; | |
354 | if (flags & QUERY_FLAG_SEARCH_REVERSE) dir = SEARCH_BACKWARD; | |
355 | ||
356 | pthread_mutex_lock(&db_lock); | |
357 | ||
57b0aad2 | 358 | status = ASL_STATUS_FAILED; |
5dd30d76 | 359 | |
57b0aad2 A |
360 | if (global.dbtype & DB_TYPE_MEMORY) status = asl_memory_match(global.memory_db, query, res, lastid, startid, ucount, dir, ruid, rgid); |
361 | else status = asl_mini_memory_match(global.mini_db, query, res, lastid, startid, ucount, dir); | |
5dd30d76 A |
362 | |
363 | pthread_mutex_unlock(&db_lock); | |
364 | ||
365 | return status; | |
366 | } | |
367 | ||
c4fdb7d1 A |
368 | static void |
369 | register_session(task_name_t task_name, pid_t pid) | |
370 | { | |
371 | mach_port_t previous; | |
372 | uint32_t i; | |
373 | ||
374 | if (task_name == MACH_PORT_NULL) return; | |
375 | if (global.dead_session_port == MACH_PORT_NULL) return; | |
376 | ||
377 | for (i = 0; i < client_tasks_count; i++) if (task_name == client_tasks[i]) return; | |
378 | ||
379 | if (client_tasks_count == 0) client_tasks = (task_name_t *)calloc(1, sizeof(task_name_t)); | |
380 | else client_tasks = (task_name_t *)reallocf(client_tasks, (client_tasks_count + 1) * sizeof(task_name_t)); | |
381 | ||
382 | if (client_tasks == NULL) return; | |
383 | client_tasks[client_tasks_count] = task_name; | |
384 | client_tasks_count++; | |
385 | ||
386 | asldebug("register_session: %u PID %d\n", (unsigned int)task_name, (int)pid); | |
387 | ||
388 | /* register for port death notification */ | |
389 | 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); | |
390 | mach_port_deallocate(mach_task_self(), previous); | |
391 | ||
392 | asl_client_count_increment(); | |
393 | } | |
394 | ||
395 | static void | |
396 | cancel_session(task_name_t task_name) | |
397 | { | |
398 | uint32_t i; | |
399 | ||
400 | for (i = 0; (i < client_tasks_count) && (task_name != client_tasks[i]); i++); | |
401 | ||
402 | if (i >= client_tasks_count) return; | |
403 | ||
404 | if (client_tasks_count == 1) | |
405 | { | |
406 | free(client_tasks); | |
407 | client_tasks = NULL; | |
408 | client_tasks_count = 0; | |
409 | } | |
410 | else | |
411 | { | |
412 | for (i++; i < client_tasks_count; i++) client_tasks[i-1] = client_tasks[i]; | |
413 | client_tasks_count--; | |
414 | client_tasks = (task_name_t *)reallocf(client_tasks, client_tasks_count * sizeof(task_name_t)); | |
415 | } | |
416 | ||
417 | asldebug("cancel_session: %u\n", (unsigned int)task_name); | |
418 | mach_port_destroy(mach_task_self(), task_name); | |
419 | asl_client_count_decrement(); | |
420 | } | |
421 | ||
5dd30d76 A |
422 | /* |
423 | * Receives messages on the "com.apple.system.logger" mach port. | |
57b0aad2 | 424 | * Services database search requests. |
5dd30d76 A |
425 | * Runs in it's own thread. |
426 | */ | |
427 | void | |
428 | database_server() | |
429 | { | |
430 | kern_return_t kstatus; | |
431 | asl_request_msg *request; | |
432 | asl_reply_msg *reply; | |
433 | uint32_t rqs, rps; | |
434 | uint32_t rbits, sbits; | |
435 | uint32_t flags, snooze; | |
436 | struct timeval now, send_time; | |
c4fdb7d1 | 437 | mach_dead_name_notification_t *deadname; |
5dd30d76 A |
438 | |
439 | send_time.tv_sec = 0; | |
440 | send_time.tv_usec = 0; | |
441 | ||
442 | rqs = sizeof(asl_request_msg) + MAX_TRAILER_SIZE; | |
443 | rps = sizeof(asl_reply_msg) + MAX_TRAILER_SIZE; | |
444 | reply = (asl_reply_msg *)calloc(1, rps); | |
445 | if (reply == NULL) return; | |
446 | ||
c4fdb7d1 | 447 | rbits = MACH_RCV_MSG | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0); |
5dd30d76 A |
448 | sbits = MACH_SEND_MSG | MACH_SEND_TIMEOUT; |
449 | ||
450 | forever | |
451 | { | |
452 | snooze = 0; | |
453 | now.tv_sec = 0; | |
454 | now.tv_usec = 0; | |
455 | ||
456 | /* Check if it's time to post a database change notification */ | |
457 | if (send_time.tv_sec != 0) | |
458 | { | |
459 | gettimeofday(&now, NULL); | |
460 | if ((now.tv_sec > send_time.tv_sec) || ((now.tv_sec == send_time.tv_sec) && (now.tv_usec > send_time.tv_usec))) | |
461 | { | |
462 | notify_post(ASL_DB_NOTIFICATION); | |
463 | send_time.tv_sec = 0; | |
464 | send_time.tv_usec = 0; | |
465 | snooze = 0; | |
466 | } | |
467 | else | |
468 | { | |
469 | /* mach_msg timeout is in milliseconds */ | |
470 | snooze = ((send_time.tv_sec - now.tv_sec) * 1000) + ((send_time.tv_usec - now.tv_usec) / 1000); | |
471 | } | |
472 | } | |
473 | ||
474 | request = (asl_request_msg *)calloc(1, rqs); | |
475 | if (request == NULL) continue; | |
476 | ||
57b0aad2 | 477 | request->head.msgh_local_port = global.server_port; |
5dd30d76 A |
478 | request->head.msgh_size = rqs; |
479 | ||
480 | memset(reply, 0, rps); | |
481 | ||
482 | flags = rbits; | |
483 | if (snooze != 0) flags |= MACH_RCV_TIMEOUT; | |
484 | ||
c4fdb7d1 | 485 | kstatus = mach_msg(&(request->head), flags, 0, rqs, global.listen_set, snooze, MACH_PORT_NULL); |
5dd30d76 A |
486 | if (request->head.msgh_id == SEND_NOTIFICATION) |
487 | { | |
488 | if (send_time.tv_sec == 0) | |
489 | { | |
490 | gettimeofday(&send_time, NULL); | |
491 | send_time.tv_sec += 1; | |
492 | } | |
493 | ||
494 | free(request); | |
495 | continue; | |
496 | } | |
497 | ||
c4fdb7d1 A |
498 | if (request->head.msgh_id == MACH_NOTIFY_DEAD_NAME) |
499 | { | |
500 | deadname = (mach_dead_name_notification_t *)request; | |
501 | cancel_session(deadname->not_port); | |
502 | free(request); | |
503 | continue; | |
504 | } | |
505 | ||
5dd30d76 A |
506 | kstatus = asl_ipc_server(&(request->head), &(reply->head)); |
507 | kstatus = mach_msg(&(reply->head), sbits, reply->head.msgh_size, 0, MACH_PORT_NULL, 10, MACH_PORT_NULL); | |
508 | if (kstatus == MACH_SEND_INVALID_DEST) | |
509 | { | |
510 | mach_port_destroy(mach_task_self(), request->head.msgh_remote_port); | |
511 | } | |
512 | ||
513 | free(request); | |
514 | } | |
515 | } | |
516 | ||
517 | kern_return_t | |
518 | __asl_server_query | |
519 | ( | |
c4fdb7d1 A |
520 | mach_port_t server, |
521 | caddr_t request, | |
522 | mach_msg_type_number_t requestCnt, | |
523 | uint64_t startid, | |
524 | int count, | |
525 | int flags, | |
526 | caddr_t *reply, | |
527 | mach_msg_type_number_t *replyCnt, | |
528 | uint64_t *lastid, | |
529 | int *status, | |
530 | security_token_t *token | |
5dd30d76 A |
531 | ) |
532 | { | |
533 | aslresponse query; | |
534 | aslresponse res; | |
535 | char *out, *vmbuffer; | |
536 | uint32_t outlen; | |
537 | kern_return_t kstatus; | |
538 | ||
539 | *status = ASL_STATUS_OK; | |
540 | query = asl_list_from_string(request); | |
541 | vm_deallocate(mach_task_self(), (vm_address_t)request, requestCnt); | |
542 | res = NULL; | |
543 | ||
57b0aad2 A |
544 | *status = db_query(query, &res, startid, count, flags, lastid, token->val[0], token->val[1]); |
545 | ||
546 | aslresponse_free(query); | |
547 | if (*status != ASL_STATUS_OK) | |
5dd30d76 | 548 | { |
57b0aad2 A |
549 | if (res != NULL) aslresponse_free(res); |
550 | return KERN_SUCCESS; | |
5dd30d76 | 551 | } |
5dd30d76 | 552 | |
57b0aad2 A |
553 | out = NULL; |
554 | outlen = 0; | |
555 | out = asl_list_to_string((asl_search_result_t *)res, &outlen); | |
556 | aslresponse_free(res); | |
5dd30d76 A |
557 | |
558 | if ((out == NULL) || (outlen == 0)) return KERN_SUCCESS; | |
559 | ||
560 | kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmbuffer, outlen, TRUE); | |
561 | if (kstatus != KERN_SUCCESS) | |
562 | { | |
563 | free(out); | |
564 | return kstatus; | |
565 | } | |
566 | ||
567 | memmove(vmbuffer, out, outlen); | |
568 | free(out); | |
569 | ||
570 | *reply = vmbuffer; | |
571 | *replyCnt = outlen; | |
572 | ||
573 | return KERN_SUCCESS; | |
574 | } | |
575 | ||
576 | ||
577 | kern_return_t | |
578 | __asl_server_query_timeout | |
579 | ( | |
c4fdb7d1 A |
580 | mach_port_t server, |
581 | caddr_t request, | |
582 | mach_msg_type_number_t requestCnt, | |
583 | uint64_t startid, | |
584 | int count, | |
585 | int flags, | |
586 | caddr_t *reply, | |
587 | mach_msg_type_number_t *replyCnt, | |
588 | uint64_t *lastid, | |
589 | int *status, | |
590 | security_token_t *token | |
5dd30d76 A |
591 | ) |
592 | { | |
593 | return __asl_server_query(server, request, requestCnt, startid, count, flags, reply, replyCnt, lastid, status, token); | |
594 | } | |
595 | ||
596 | kern_return_t | |
597 | __asl_server_prune | |
598 | ( | |
599 | mach_port_t server, | |
600 | caddr_t request, | |
601 | mach_msg_type_number_t requestCnt, | |
602 | int *status, | |
603 | security_token_t *token | |
604 | ) | |
605 | { | |
5dd30d76 A |
606 | return KERN_SUCCESS; |
607 | } | |
c4fdb7d1 A |
608 | |
609 | kern_return_t | |
610 | __asl_server_message | |
611 | ( | |
612 | mach_port_t server, | |
613 | caddr_t message, | |
614 | mach_msg_type_number_t messageCnt, | |
615 | audit_token_t token | |
616 | ) | |
617 | { | |
618 | asl_msg_t *m; | |
619 | char tmp[64]; | |
620 | uid_t uid; | |
621 | gid_t gid; | |
622 | pid_t pid; | |
623 | kern_return_t kstatus; | |
624 | mach_port_name_t client; | |
625 | ||
626 | asldebug("__asl_server_message: %s\n", (message == NULL) ? "NULL" : message); | |
627 | ||
628 | m = asl_msg_from_string(message); | |
629 | vm_deallocate(mach_task_self(), (vm_address_t)message, messageCnt); | |
630 | ||
631 | uid = (uid_t)-1; | |
632 | gid = (gid_t)-1; | |
633 | pid = (gid_t)-1; | |
634 | audit_token_to_au32(token, NULL, &uid, &gid, NULL, NULL, &pid, NULL, NULL); | |
635 | ||
636 | client = MACH_PORT_NULL; | |
637 | kstatus = task_name_for_pid(mach_task_self(), pid, &client); | |
638 | if (kstatus == KERN_SUCCESS) register_session(client, pid); | |
639 | ||
640 | if (m == NULL) return KERN_SUCCESS; | |
641 | ||
642 | snprintf(tmp, sizeof(tmp), "%d", uid); | |
643 | asl_set(m, ASL_KEY_UID, tmp); | |
644 | ||
645 | snprintf(tmp, sizeof(tmp), "%d", gid); | |
646 | asl_set(m, ASL_KEY_GID, tmp); | |
647 | ||
648 | snprintf(tmp, sizeof(tmp), "%d", pid); | |
649 | asl_set(m, ASL_KEY_PID, tmp); | |
650 | ||
651 | /* verify and enqueue for processing */ | |
652 | asl_enqueue_message(SOURCE_ASL_MESSAGE, NULL, m); | |
653 | ||
654 | return KERN_SUCCESS; | |
655 | } |