2 * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/types.h>
29 #include <sys/socket.h>
33 #include <sys/fcntl.h>
34 #include <sys/signal.h>
35 #include <sys/errno.h>
36 #include <mach/mach.h>
37 #include <mach/mach_error.h>
38 #include <bsm/libbsm.h>
40 #include <netinet/in.h>
41 #include <netinet/tcp.h>
42 #include <sys/event.h>
43 #include <servers/bootstrap.h>
49 #include "asl_ipcServer.h"
51 #include <asl_store.h>
54 #define forever for(;;)
56 #define LIST_SIZE_DELTA 256
58 #define SEND_NOTIFICATION 0xfadefade
60 #define QUERY_FLAG_SEARCH_REVERSE 0x00000001
61 #define SEARCH_FORWARD 1
62 #define SEARCH_BACKWARD -1
64 static pthread_mutex_t db_lock
= PTHREAD_MUTEX_INITIALIZER
;
66 extern char *asl_list_to_string(asl_search_result_t
*list
, uint32_t *outlen
);
67 extern asl_search_result_t
*asl_list_from_string(const char *buf
);
68 extern boolean_t
asl_ipc_server(mach_msg_header_t
*InHeadP
, mach_msg_header_t
*OutHeadP
);
69 extern uint32_t bb_convert(const char *name
);
71 static task_name_t
*client_tasks
= NULL
;
72 static uint32_t client_tasks_count
= 0;
74 static int *direct_watch
= NULL
;
75 /* N.B. ports are in network byte order */
76 static uint16_t *direct_watch_port
= NULL
;
77 static uint32_t direct_watch_count
= 0;
81 mach_msg_header_t head
;
82 union __RequestUnion__asl_ipc_subsystem request
;
87 mach_msg_header_t head
;
88 union __ReplyUnion__asl_ipc_subsystem reply
;
94 if ((global
.dbtype
& DB_TYPE_FILE
) && (global
.file_db
!= NULL
))
96 global
.store_flags
|= STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED
;
98 /* wake up the output worker thread */
99 pthread_cond_signal(&global
.work_queue_cond
);
109 if ((global
.dbtype
& DB_TYPE_FILE
) && (global
.file_db
== NULL
))
111 memset(&sb
, 0, sizeof(struct stat
));
112 if (stat(PATH_ASL_STORE
, &sb
) == 0)
114 /* must be a directory */
115 if (!S_ISDIR(sb
.st_mode
))
117 asldebug("error: %s is not a directory", PATH_ASL_STORE
);
125 /* /var/log/asl doesn't exist - create it */
126 if (mkdir(PATH_ASL_STORE
, 0755) != 0)
128 asldebug("error: can't create data store %s: %s\n", PATH_ASL_STORE
, strerror(errno
));
134 /* stat failed for some other reason */
135 asldebug("error: can't stat data store %s: %s\n", PATH_ASL_STORE
, strerror(errno
));
141 * One-time store conversion from the old "LongTTL" style to the new "Best Before" style.
142 * bb_convert returns quickly if the store has already been converted.
144 status
= bb_convert(PATH_ASL_STORE
);
145 if (status
!= ASL_STATUS_OK
)
147 asldebug("ASL data store conversion failed!: %s\n", asl_core_error(status
));
150 status
= asl_store_open_write(NULL
, &(global
.file_db
));
151 if (status
!= ASL_STATUS_OK
)
153 asldebug("asl_store_open_write: %s\n", asl_core_error(status
));
157 if (global
.db_file_max
!= 0) asl_store_max_file_size(global
.file_db
, global
.db_file_max
);
158 asl_store_signal_sweep(global
.file_db
);
162 if ((global
.dbtype
& DB_TYPE_MEMORY
) && (global
.memory_db
== NULL
))
164 status
= asl_memory_open(global
.db_memory_max
, &(global
.memory_db
));
165 if (status
!= ASL_STATUS_OK
)
167 asldebug("asl_memory_open: %s\n", asl_core_error(status
));
171 if ((global
.dbtype
& DB_TYPE_MINI
) && (global
.mini_db
== NULL
))
173 status
= asl_mini_memory_open(global
.db_mini_max
, &(global
.mini_db
));
174 if (status
!= ASL_STATUS_OK
)
176 asldebug("asl_mini_memory_open: %s\n", asl_core_error(status
));
182 * Takes messages off the work queue and saves them.
183 * Runs in it's own thread.
190 mach_msg_empty_send_t
*empty
;
191 kern_return_t kstatus
;
193 empty
= (mach_msg_empty_send_t
*)calloc(1, sizeof(mach_msg_empty_send_t
));
194 if (empty
== NULL
) return;
200 /* blocks until work is available */
201 work
= work_dequeue(&count
);
205 if ((global
.dbtype
& DB_TYPE_FILE
) && (global
.store_flags
& STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED
))
207 asl_store_sweep_file_cache(global
.file_db
);
208 global
.store_flags
&= ~STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED
;
214 for (i
= 0; i
< count
; i
++)
216 asl_message_match_and_log(work
[i
]);
222 if (global
.store_flags
& STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED
)
224 asl_store_sweep_file_cache(global
.file_db
);
225 global
.store_flags
&= ~STORE_FLAGS_FILE_CACHE_SWEEP_REQUESTED
;
228 empty
->header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, MACH_MSGH_BITS_ZERO
);
229 empty
->header
.msgh_remote_port
= global
.self_port
;
230 empty
->header
.msgh_local_port
= MACH_PORT_NULL
;
231 empty
->header
.msgh_size
= sizeof(mach_msg_empty_send_t
);
232 empty
->header
.msgh_id
= SEND_NOTIFICATION
;
234 kstatus
= mach_msg(&(empty
->header
), MACH_SEND_MSG
| MACH_SEND_TIMEOUT
, empty
->header
.msgh_size
, 0, MACH_PORT_NULL
, 100, MACH_PORT_NULL
);
239 send_to_direct_watchers(asl_msg_t
*msg
)
241 uint32_t i
, j
, nlen
, outlen
, cleanup
, total_sent
;
246 if (global
.lockdown_session_fd
>= 0)
248 /* PurpleConsole eats newlines */
249 out
= asl_format_message(msg
, ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &outlen
);
250 if ((write(global
.lockdown_session_fd
, "\n", 1) < 0) ||
251 (write(global
.lockdown_session_fd
, out
, outlen
) < 0) ||
252 (write(global
.lockdown_session_fd
, "\n", 1) < 0))
254 close(global
.lockdown_session_fd
);
255 global
.lockdown_session_fd
= -1;
256 global
.watchers_active
= direct_watch_count
+ ((global
.lockdown_session_fd
< 0) ? 0 : 1);
263 if (direct_watch_count
== 0) return;
266 out
= asl_msg_to_string(msg
, &outlen
);
268 if (out
== NULL
) return;
270 nlen
= htonl(outlen
);
271 for (i
= 0; i
< direct_watch_count
; i
++)
273 sent
= send(direct_watch
[i
], &nlen
, sizeof(nlen
), 0);
274 if (sent
< sizeof(nlen
))
276 /* bail out if we can't send 4 bytes */
277 close(direct_watch
[i
]);
278 direct_watch
[i
] = -1;
284 while (total_sent
< outlen
)
286 sent
= send(direct_watch
[i
], out
+ total_sent
, outlen
- total_sent
, 0);
289 close(direct_watch
[i
]);
290 direct_watch
[i
] = -1;
302 if (cleanup
== 0) return;
305 for (i
= 0; i
< direct_watch_count
; i
++)
307 if (direct_watch
[i
] >= 0)
311 direct_watch
[j
] = direct_watch
[i
];
312 direct_watch_port
[j
] = direct_watch_port
[i
];
318 direct_watch_count
= j
;
319 if (direct_watch_count
== 0)
324 free(direct_watch_port
);
325 direct_watch_port
= NULL
;
329 direct_watch
= reallocf(direct_watch
, direct_watch_count
* sizeof(int));
330 direct_watch_port
= reallocf(direct_watch_port
, direct_watch_count
* sizeof(uint16_t));
331 if ((direct_watch
== NULL
) || (direct_watch_port
== NULL
))
336 free(direct_watch_port
);
337 direct_watch_port
= NULL
;
339 direct_watch_count
= 0;
345 * Called from asl_action.c to save messgaes to the ASL data store
348 db_save_message(aslmsg msg
)
353 send_to_direct_watchers((asl_msg_t
*)msg
);
355 pthread_mutex_lock(&db_lock
);
359 if (global
.dbtype
& DB_TYPE_FILE
)
361 status
= asl_store_save(global
.file_db
, msg
);
362 if (status
!= ASL_STATUS_OK
)
364 /* write failed - reopen & retry */
365 asldebug("asl_store_save: %s\n", asl_core_error(status
));
366 asl_store_close(global
.file_db
);
367 global
.file_db
= NULL
;
370 status
= asl_store_save(global
.file_db
, msg
);
371 if (status
!= ASL_STATUS_OK
)
373 asldebug("(retry) asl_store_save: %s\n", asl_core_error(status
));
374 asl_store_close(global
.file_db
);
375 global
.file_db
= NULL
;
377 global
.dbtype
|= DB_TYPE_MEMORY
;
378 if (global
.memory_db
== NULL
)
380 status
= asl_memory_open(global
.db_memory_max
, &(global
.memory_db
));
381 if (status
!= ASL_STATUS_OK
)
383 asldebug("asl_memory_open: %s\n", asl_core_error(status
));
390 if (global
.dbtype
& DB_TYPE_MEMORY
)
393 status
= asl_memory_save(global
.memory_db
, msg
, &msgid
);
394 if (status
!= ASL_STATUS_OK
)
396 /* save failed - reopen & retry*/
397 asldebug("asl_memory_save: %s\n", asl_core_error(status
));
398 asl_memory_close(global
.memory_db
);
399 global
.memory_db
= NULL
;
403 status
= asl_memory_save(global
.memory_db
, msg
, &msgid
);
404 if (status
!= ASL_STATUS_OK
)
406 asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status
));
407 asl_memory_close(global
.memory_db
);
408 global
.memory_db
= NULL
;
413 if (global
.dbtype
& DB_TYPE_MINI
)
415 status
= asl_mini_memory_save(global
.mini_db
, msg
, &msgid
);
416 if (status
!= ASL_STATUS_OK
)
418 /* save failed - reopen & retry*/
419 asldebug("asl_mini_memory_save: %s\n", asl_core_error(status
));
420 asl_mini_memory_close(global
.mini_db
);
421 global
.mini_db
= NULL
;
424 status
= asl_mini_memory_save(global
.mini_db
, msg
, &msgid
);
425 if (status
!= ASL_STATUS_OK
)
427 asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status
));
428 asl_mini_memory_close(global
.mini_db
);
429 global
.mini_db
= NULL
;
434 pthread_mutex_unlock(&db_lock
);
438 disaster_message(aslmsg msg
)
445 if ((global
.dbtype
& DB_TYPE_MINI
) == 0)
447 if (global
.mini_db
== NULL
)
449 status
= asl_mini_memory_open(global
.db_mini_max
, &(global
.mini_db
));
450 if (status
!= ASL_STATUS_OK
) asldebug("asl_mini_memory_open: %s\n", asl_core_error(status
));
451 else asl_mini_memory_save(global
.mini_db
, msg
, &msgid
);
457 * Do a database search.
460 db_query(aslresponse query
, aslresponse
*res
, uint64_t startid
, int count
, int flags
, uint64_t *lastid
, int32_t ruid
, int32_t rgid
)
462 uint32_t status
, ucount
;
466 * Special case: if count is -1, we return ASL_STATUS_OK to indicate that the store is
467 * in memory, and ASL_STATUS_INVALID_STORE to indicate that the file store is in use.
471 if ((global
.dbtype
& DB_TYPE_MEMORY
) || (global
.dbtype
& DB_TYPE_MINI
)) return ASL_STATUS_OK
;
472 else return ASL_STATUS_INVALID_STORE
;
476 dir
= SEARCH_FORWARD
;
477 if (flags
& QUERY_FLAG_SEARCH_REVERSE
) dir
= SEARCH_BACKWARD
;
479 pthread_mutex_lock(&db_lock
);
481 status
= ASL_STATUS_FAILED
;
483 if (global
.dbtype
& DB_TYPE_MEMORY
)
485 status
= asl_memory_match(global
.memory_db
, query
, res
, lastid
, startid
, ucount
, dir
, ruid
, rgid
);
487 else if (global
.dbtype
& DB_TYPE_MINI
)
489 status
= asl_mini_memory_match(global
.mini_db
, query
, res
, lastid
, startid
, ucount
, dir
);
491 else if (global
.disaster_occurred
!= 0)
493 /* KernelEventAgent calls us to get the kernel disaster messages. */
494 status
= asl_mini_memory_match(global
.mini_db
, query
, res
, lastid
, startid
, ucount
, dir
);
497 pthread_mutex_unlock(&db_lock
);
503 register_session(task_name_t task_name
, pid_t pid
)
505 mach_port_t previous
;
508 if (task_name
== MACH_PORT_NULL
) return;
510 if (global
.dead_session_port
== MACH_PORT_NULL
)
512 mach_port_deallocate(mach_task_self(), task_name
);
516 for (i
= 0; i
< client_tasks_count
; i
++) if (task_name
== client_tasks
[i
])
518 mach_port_deallocate(mach_task_self(), task_name
);
522 if (client_tasks_count
== 0) client_tasks
= (task_name_t
*)calloc(1, sizeof(task_name_t
));
523 else client_tasks
= (task_name_t
*)reallocf(client_tasks
, (client_tasks_count
+ 1) * sizeof(task_name_t
));
525 if (client_tasks
== NULL
)
527 mach_port_deallocate(mach_task_self(), task_name
);
531 client_tasks
[client_tasks_count
] = task_name
;
532 client_tasks_count
++;
534 asldebug("register_session: %u PID %d\n", (unsigned int)task_name
, (int)pid
);
536 /* register for port death notification */
537 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
);
538 mach_port_deallocate(mach_task_self(), previous
);
540 asl_client_count_increment();
544 cancel_session(task_name_t task_name
)
548 for (i
= 0; (i
< client_tasks_count
) && (task_name
!= client_tasks
[i
]); i
++);
550 if (i
>= client_tasks_count
) return;
552 if (client_tasks_count
== 1)
556 client_tasks_count
= 0;
560 for (i
++; i
< client_tasks_count
; i
++) client_tasks
[i
-1] = client_tasks
[i
];
561 client_tasks_count
--;
562 client_tasks
= (task_name_t
*)reallocf(client_tasks
, client_tasks_count
* sizeof(task_name_t
));
565 asldebug("cancel_session: %u\n", (unsigned int)task_name
);
567 /* we hold a send right or dead name right for the task name port */
568 mach_port_deallocate(mach_task_self(), task_name
);
569 asl_client_count_decrement();
573 register_direct_watch(uint16_t port
)
577 struct sockaddr_in address
;
579 if (port
== 0) return ASL_STATUS_FAILED
;
581 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
582 if (sock
< 0) return ASL_STATUS_FAILED
;
584 address
.sin_family
= AF_INET
;
585 /* port must be sent in network byte order */
586 address
.sin_port
= port
;
587 address
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
589 if (connect(sock
, (struct sockaddr
*)&address
, sizeof(address
)) != 0) return ASL_STATUS_FAILED
;
592 setsockopt(sock
, SOL_SOCKET
, SO_NOSIGPIPE
, &i
, sizeof(i
));
595 setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
, &i
, sizeof(i
));
597 /* make socket non-blocking */
598 flags
= fcntl(sock
, F_GETFL
, 0);
599 if (flags
== -1) flags
= 0;
600 fcntl(sock
, F_SETFL
, flags
| O_NONBLOCK
);
602 if (direct_watch_count
== 0)
604 direct_watch
= (int *)calloc(1, sizeof(int));
605 direct_watch_port
= (uint16_t *)calloc(1, sizeof(uint16_t));
609 direct_watch
= (int *)reallocf(direct_watch
, (direct_watch_count
+ 1) * sizeof(int));
610 direct_watch_port
= (uint16_t *)reallocf(direct_watch_port
, (direct_watch_count
+ 1) * sizeof(uint16_t));
613 if ((direct_watch
== NULL
) || (direct_watch_port
== NULL
))
620 free(direct_watch_port
);
621 direct_watch_port
= NULL
;
623 direct_watch_count
= 0;
624 global
.watchers_active
= 0;
625 if (global
.lockdown_session_fd
>= 0) global
.watchers_active
= 1;
627 return ASL_STATUS_FAILED
;
630 direct_watch
[direct_watch_count
] = sock
;
631 direct_watch_port
[direct_watch_count
] = port
;
632 direct_watch_count
++;
633 global
.watchers_active
= direct_watch_count
+ ((global
.lockdown_session_fd
< 0) ? 0 : 1);
635 return ASL_STATUS_OK
;
639 cancel_direct_watch(uint16_t port
)
643 for (i
= 0; (i
< direct_watch_count
) && (port
!= direct_watch_port
[i
]); i
++);
645 if (i
>= direct_watch_count
) return;
647 if (direct_watch_count
== 1)
652 free(direct_watch_port
);
653 direct_watch_port
= NULL
;
655 direct_watch_count
= 0;
656 global
.watchers_active
= 0;
657 if (global
.lockdown_session_fd
>= 0) global
.watchers_active
= 1;
661 for (i
++; i
< direct_watch_count
; i
++)
663 direct_watch
[i
-1] = direct_watch
[i
];
664 direct_watch_port
[i
-1] = direct_watch_port
[i
];
667 direct_watch_count
--;
668 global
.watchers_active
= direct_watch_count
+ ((global
.lockdown_session_fd
< 0) ? 0 : 1);
670 direct_watch
= (int *)reallocf(direct_watch
, direct_watch_count
* sizeof(int));
671 direct_watch_port
= (uint16_t *)reallocf(direct_watch_port
, direct_watch_count
* sizeof(uint16_t));
673 if ((direct_watch
== NULL
) || (direct_watch_port
== NULL
))
678 free(direct_watch_port
);
679 direct_watch_port
= NULL
;
681 direct_watch_count
= 0;
682 global
.watchers_active
= 0;
683 if (global
.lockdown_session_fd
>= 0) global
.watchers_active
= 1;
689 * Receives messages on the "com.apple.system.logger" mach port.
690 * Services database search requests.
691 * Runs in it's own thread.
696 kern_return_t kstatus
;
697 asl_request_msg
*request
;
698 asl_reply_msg
*reply
;
700 uint32_t rbits
, sbits
;
701 uint32_t flags
, snooze
;
702 struct timeval now
, send_time
;
703 mach_dead_name_notification_t
*deadname
;
705 send_time
.tv_sec
= 0;
706 send_time
.tv_usec
= 0;
708 rqs
= sizeof(asl_request_msg
) + MAX_TRAILER_SIZE
;
709 rps
= sizeof(asl_reply_msg
) + MAX_TRAILER_SIZE
;
710 reply
= (asl_reply_msg
*)calloc(1, rps
);
711 if (reply
== NULL
) return;
713 rbits
= MACH_RCV_MSG
| MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT
) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0
);
714 sbits
= MACH_SEND_MSG
| MACH_SEND_TIMEOUT
;
722 /* Check if it's time to post a database change notification */
723 if (send_time
.tv_sec
!= 0)
725 gettimeofday(&now
, NULL
);
726 if ((now
.tv_sec
> send_time
.tv_sec
) || ((now
.tv_sec
== send_time
.tv_sec
) && (now
.tv_usec
> send_time
.tv_usec
)))
728 notify_post(ASL_DB_NOTIFICATION
);
729 send_time
.tv_sec
= 0;
730 send_time
.tv_usec
= 0;
735 /* mach_msg timeout is in milliseconds */
736 snooze
= ((send_time
.tv_sec
- now
.tv_sec
) * 1000) + ((send_time
.tv_usec
- now
.tv_usec
) / 1000);
740 request
= (asl_request_msg
*)calloc(1, rqs
);
741 if (request
== NULL
) continue;
743 request
->head
.msgh_local_port
= global
.server_port
;
744 request
->head
.msgh_size
= rqs
;
746 memset(reply
, 0, rps
);
749 if (snooze
!= 0) flags
|= MACH_RCV_TIMEOUT
;
751 kstatus
= mach_msg(&(request
->head
), flags
, 0, rqs
, global
.listen_set
, snooze
, MACH_PORT_NULL
);
752 if (request
->head
.msgh_id
== SEND_NOTIFICATION
)
754 if (send_time
.tv_sec
== 0)
756 gettimeofday(&send_time
, NULL
);
757 send_time
.tv_sec
+= 1;
764 if (request
->head
.msgh_id
== MACH_NOTIFY_DEAD_NAME
)
766 deadname
= (mach_dead_name_notification_t
*)request
;
767 cancel_session(deadname
->not_port
);
769 /* dead name notification includes a dead name right - release it here */
770 mach_port_deallocate(mach_task_self(), deadname
->not_port
);
775 kstatus
= asl_ipc_server(&(request
->head
), &(reply
->head
));
776 kstatus
= mach_msg(&(reply
->head
), sbits
, reply
->head
.msgh_size
, 0, MACH_PORT_NULL
, 10, MACH_PORT_NULL
);
777 if (kstatus
== MACH_SEND_INVALID_DEST
)
779 /* release send right for the port */
780 mach_port_deallocate(mach_task_self(), request
->head
.msgh_remote_port
);
792 mach_msg_type_number_t requestCnt
,
797 mach_msg_type_number_t
*replyCnt
,
800 security_token_t
*token
805 char *out
, *vmbuffer
;
807 kern_return_t kstatus
;
809 *status
= ASL_STATUS_OK
;
811 if ((request
!= NULL
) && (request
[requestCnt
- 1] != '\0'))
813 *status
= ASL_STATUS_INVALID_ARG
;
814 vm_deallocate(mach_task_self(), (vm_address_t
)request
, requestCnt
);
818 query
= asl_list_from_string(request
);
819 if (request
!= NULL
) vm_deallocate(mach_task_self(), (vm_address_t
)request
, requestCnt
);
822 *status
= db_query(query
, &res
, startid
, count
, flags
, lastid
, token
->val
[0], token
->val
[1]);
824 aslresponse_free(query
);
825 if (*status
!= ASL_STATUS_INVALID_STORE
)
829 else if (*status
!= ASL_STATUS_OK
)
831 if (res
!= NULL
) aslresponse_free(res
);
837 out
= asl_list_to_string((asl_search_result_t
*)res
, &outlen
);
838 aslresponse_free(res
);
840 if ((out
== NULL
) || (outlen
== 0)) return KERN_SUCCESS
;
842 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmbuffer
, outlen
, TRUE
);
843 if (kstatus
!= KERN_SUCCESS
)
849 memmove(vmbuffer
, out
, outlen
);
860 __asl_server_query_timeout
864 mach_msg_type_number_t requestCnt
,
869 mach_msg_type_number_t
*replyCnt
,
872 security_token_t
*token
875 return __asl_server_query(server
, request
, requestCnt
, startid
, count
, flags
, reply
, replyCnt
, lastid
, status
, token
);
883 mach_msg_type_number_t requestCnt
,
885 security_token_t
*token
896 mach_msg_type_number_t messageCnt
,
905 kern_return_t kstatus
;
906 mach_port_name_t client
;
913 if (message
[messageCnt
- 1] != '\0')
915 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
919 asldebug("__asl_server_message: %s\n", (message
== NULL
) ? "NULL" : message
);
921 msg
= (aslmsg
)asl_msg_from_string(message
);
922 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
924 if (msg
== NULL
) return KERN_SUCCESS
;
929 audit_token_to_au32(token
, NULL
, &uid
, &gid
, NULL
, NULL
, &pid
, NULL
, NULL
);
931 client
= MACH_PORT_NULL
;
932 kstatus
= task_name_for_pid(mach_task_self(), pid
, &client
);
933 if (kstatus
== KERN_SUCCESS
) register_session(client
, pid
);
935 snprintf(tmp
, sizeof(tmp
), "%d", uid
);
936 asl_set(msg
, ASL_KEY_UID
, tmp
);
938 snprintf(tmp
, sizeof(tmp
), "%d", gid
);
939 asl_set(msg
, ASL_KEY_GID
, tmp
);
941 snprintf(tmp
, sizeof(tmp
), "%d", pid
);
942 asl_set(msg
, ASL_KEY_PID
, tmp
);
944 /* verify and enqueue for processing */
945 asl_enqueue_message(SOURCE_ASL_MESSAGE
, NULL
, msg
);
951 __asl_server_create_aux_link
955 mach_msg_type_number_t messageCnt
,
956 mach_port_t
*fileport
,
958 mach_msg_type_number_t
*newurlCnt
,
968 kern_return_t kstatus
;
969 mach_port_name_t client
;
970 char *url
, *vmbuffer
;
973 *status
= ASL_STATUS_OK
;
977 *status
= ASL_STATUS_INVALID_ARG
;
981 if (message
[messageCnt
- 1] != '\0')
983 *status
= ASL_STATUS_INVALID_ARG
;
984 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
988 asldebug("__asl_server_create_aux_link: %s\n", (message
== NULL
) ? "NULL" : message
);
990 if ((global
.dbtype
& DB_TYPE_FILE
) == 0)
992 *status
= ASL_STATUS_INVALID_STORE
;
996 *fileport
= MACH_PORT_NULL
;
998 msg
= (aslmsg
)asl_msg_from_string(message
);
999 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
1001 if (msg
== NULL
) return KERN_SUCCESS
;
1006 audit_token_to_au32(token
, NULL
, &uid
, &gid
, NULL
, NULL
, &pid
, NULL
, NULL
);
1008 client
= MACH_PORT_NULL
;
1009 kstatus
= task_name_for_pid(mach_task_self(), pid
, &client
);
1010 if (kstatus
== KERN_SUCCESS
) register_session(client
, pid
);
1012 snprintf(tmp
, sizeof(tmp
), "%d", uid
);
1013 asl_set(msg
, ASL_KEY_UID
, tmp
);
1015 snprintf(tmp
, sizeof(tmp
), "%d", gid
);
1016 asl_set(msg
, ASL_KEY_GID
, tmp
);
1018 snprintf(tmp
, sizeof(tmp
), "%d", pid
);
1019 asl_set(msg
, ASL_KEY_PID
, tmp
);
1021 /* create a file for the client */
1022 *status
= asl_store_open_aux(global
.file_db
, msg
, &fd
, &url
);
1024 if (*status
!= ASL_STATUS_OK
) return KERN_SUCCESS
;
1027 if (fd
>= 0) close(fd
);
1028 *status
= ASL_STATUS_FAILED
;
1029 return KERN_SUCCESS
;
1032 if (fileport_makeport(fd
, (fileport_t
*)fileport
) < 0)
1036 *status
= ASL_STATUS_FAILED
;
1037 return KERN_SUCCESS
;
1042 *newurlCnt
= strlen(url
) + 1;
1044 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmbuffer
, *newurlCnt
, TRUE
);
1045 if (kstatus
!= KERN_SUCCESS
)
1051 memmove(vmbuffer
, url
, *newurlCnt
);
1056 return KERN_SUCCESS
;
1060 __asl_server_register_direct_watch
1067 uint16_t p16
= port
;
1069 asldebug("__asl_server_register_direct_watch: %hu\n", ntohs(p16
));
1071 register_direct_watch(p16
);
1073 return KERN_SUCCESS
;
1077 __asl_server_cancel_direct_watch
1084 uint16_t p16
= port
;
1086 asldebug("__asl_server_cancel_direct_watch: %hu\n", ntohs(p16
));
1088 cancel_direct_watch(p16
);
1090 return KERN_SUCCESS
;