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 #define forever for(;;)
53 #define LIST_SIZE_DELTA 256
55 #define SEND_NOTIFICATION 0xfadefade
57 #define QUERY_FLAG_SEARCH_REVERSE 0x00000001
58 #define SEARCH_FORWARD 1
59 #define SEARCH_BACKWARD -1
63 static dispatch_queue_t asl_server_queue
;
65 extern char *asl_list_to_string(asl_search_result_t
*list
, uint32_t *outlen
);
66 extern asl_search_result_t
*asl_list_from_string(const char *buf
);
67 extern boolean_t
asl_ipc_server(mach_msg_header_t
*InHeadP
, mach_msg_header_t
*OutHeadP
);
68 extern uint32_t bb_convert(const char *name
);
70 static task_name_t
*client_tasks
= NULL
;
71 static uint32_t client_tasks_count
= 0;
73 static int *direct_watch
= NULL
;
74 /* N.B. ports are in network byte order */
75 static uint16_t *direct_watch_port
= NULL
;
76 static uint32_t direct_watch_count
= 0;
80 mach_msg_header_t head
;
81 union __RequestUnion__asl_ipc_subsystem request
;
86 mach_msg_header_t head
;
87 union __ReplyUnion__asl_ipc_subsystem reply
;
91 db_asl_open(uint32_t dbtype
)
96 if ((dbtype
& DB_TYPE_FILE
) && (global
.file_db
== NULL
))
98 memset(&sb
, 0, sizeof(struct stat
));
99 if (stat(PATH_ASL_STORE
, &sb
) == 0)
101 /* must be a directory */
102 if (!S_ISDIR(sb
.st_mode
))
104 asldebug("error: %s is not a directory", PATH_ASL_STORE
);
112 /* /var/log/asl doesn't exist - create it */
113 if (mkdir(PATH_ASL_STORE
, 0755) != 0)
115 asldebug("error: can't create data store %s: %s\n", PATH_ASL_STORE
, strerror(errno
));
121 /* stat failed for some other reason */
122 asldebug("error: can't stat data store %s: %s\n", PATH_ASL_STORE
, strerror(errno
));
128 * One-time store conversion from the old "LongTTL" style to the new "Best Before" style.
129 * bb_convert returns quickly if the store has already been converted.
131 status
= bb_convert(PATH_ASL_STORE
);
132 if (status
!= ASL_STATUS_OK
)
134 asldebug("ASL data store conversion failed!: %s\n", asl_core_error(status
));
137 status
= asl_store_open_write(NULL
, &(global
.file_db
));
138 if (status
!= ASL_STATUS_OK
)
140 asldebug("asl_store_open_write: %s\n", asl_core_error(status
));
144 if (global
.db_file_max
!= 0) asl_store_max_file_size(global
.file_db
, global
.db_file_max
);
145 asl_store_signal_sweep(global
.file_db
);
149 if ((dbtype
& DB_TYPE_MEMORY
) && (global
.memory_db
== NULL
))
151 status
= asl_memory_open(global
.db_memory_max
, &(global
.memory_db
));
152 if (status
!= ASL_STATUS_OK
)
154 asldebug("asl_memory_open: %s\n", asl_core_error(status
));
158 if ((dbtype
& DB_TYPE_MINI
) && (global
.mini_db
== NULL
))
160 status
= asl_mini_memory_open(global
.db_mini_max
, &(global
.mini_db
));
161 if (status
!= ASL_STATUS_OK
)
163 asldebug("asl_mini_memory_open: %s\n", asl_core_error(status
));
169 send_to_direct_watchers(asl_msg_t
*msg
)
171 uint32_t i
, j
, nlen
, outlen
, cleanup
, total_sent
, again
;
176 static struct timeval last_time
;
178 if (global
.lockdown_session_fd
>= 0)
180 if (global
.remote_delay_time
> 0)
185 if (gettimeofday(&now
, NULL
) == 0)
187 if (last_time
.tv_sec
!= 0)
189 if (now
.tv_sec
> last_time
.tv_sec
)
192 now
.tv_usec
+= 1000000;
195 delta
= now
.tv_sec
- last_time
.tv_sec
;
197 delta
+= (now
.tv_usec
- last_time
.tv_usec
);
198 if (delta
< global
.remote_delay_time
)
204 if (now
.tv_usec
>= 1000000)
207 now
.tv_usec
-= 1000000;
214 out
= asl_format_message(msg
, ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &outlen
);
215 if ((write(global
.lockdown_session_fd
, out
, outlen
) < 0) || (write(global
.lockdown_session_fd
, "\n", 1) < 0))
217 asldebug("send_to_direct_watchers: lockdown write error: %d %s\n", errno
, strerror(errno
));
218 close(global
.lockdown_session_fd
);
219 global
.lockdown_session_fd
= -1;
220 global
.watchers_active
= direct_watch_count
+ ((global
.lockdown_session_fd
< 0) ? 0 : 1);
228 if (direct_watch_count
== 0)
234 if (direct_watch
== NULL
)
236 direct_watch_count
= 0;
241 out
= asl_msg_to_string(msg
, &outlen
);
243 if (out
== NULL
) return;
245 nlen
= htonl(outlen
);
246 for (i
= 0; i
< direct_watch_count
; i
++)
248 sent
= send(direct_watch
[i
], &nlen
, sizeof(nlen
), 0);
249 if (sent
< sizeof(nlen
))
251 /* bail out if we can't send 4 bytes */
252 close(direct_watch
[i
]);
253 direct_watch
[i
] = -1;
261 while (total_sent
< outlen
)
264 sent
= send(direct_watch
[i
], out
+ total_sent
, outlen
- total_sent
, 0);
267 asldebug("send_to_direct_watchers: send returned %d (errno %d)\n", sent
, errno
);
270 if (again
> MAX_AGAIN
)
272 asldebug("send_to_direct_watchers: exceeded EAGAIN limit - closing connection\n");
283 close(direct_watch
[i
]);
284 direct_watch
[i
] = -1;
296 if (cleanup
== 0) return;
299 for (i
= 0; i
< direct_watch_count
; i
++)
301 if (direct_watch
[i
] >= 0)
305 direct_watch
[j
] = direct_watch
[i
];
306 direct_watch_port
[j
] = direct_watch_port
[i
];
312 direct_watch_count
= j
;
313 if (direct_watch_count
== 0)
318 free(direct_watch_port
);
319 direct_watch_port
= NULL
;
323 direct_watch
= reallocf(direct_watch
, direct_watch_count
* sizeof(int));
324 direct_watch_port
= reallocf(direct_watch_port
, direct_watch_count
* sizeof(uint16_t));
325 if ((direct_watch
== NULL
) || (direct_watch_port
== NULL
))
330 free(direct_watch_port
);
331 direct_watch_port
= NULL
;
333 direct_watch_count
= 0;
339 * Called from asl_action.c to save messgaes to the ASL data store
342 db_save_message(aslmsg msg
)
345 uint32_t status
, dbtype
;
347 static dispatch_source_t timer_src
;
348 static dispatch_once_t once
;
350 dispatch_once(&once
, ^{
351 timer_src
= dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER
, 0, 0, dispatch_get_main_queue());
352 dispatch_source_set_event_handler(timer_src
, ^{
353 notify_post(kNotifyASLDBUpdate
);
354 dispatch_suspend(timer_src
);
360 send_to_direct_watchers((asl_msg_t
*)msg
);
362 dbtype
= global
.dbtype
;
364 if (asl_check_option(msg
, ASL_OPT_DB_FILE
)) dbtype
|= DB_TYPE_FILE
;
365 if (asl_check_option(msg
, ASL_OPT_DB_MINI
)) dbtype
|= DB_TYPE_MINI
;
366 if (asl_check_option(msg
, ASL_OPT_DB_MEMORY
)) dbtype
|= DB_TYPE_MEMORY
;
370 if (dbtype
& DB_TYPE_FILE
)
372 status
= asl_store_save(global
.file_db
, msg
);
373 if (status
!= ASL_STATUS_OK
)
375 /* write failed - reopen & retry */
376 asldebug("asl_store_save: %s\n", asl_core_error(status
));
377 asl_store_close(global
.file_db
);
378 global
.file_db
= NULL
;
381 status
= asl_store_save(global
.file_db
, msg
);
382 if (status
!= ASL_STATUS_OK
)
384 asldebug("(retry) asl_store_save: %s\n", asl_core_error(status
));
385 asl_store_close(global
.file_db
);
386 global
.file_db
= NULL
;
388 global
.dbtype
|= DB_TYPE_MEMORY
;
389 dbtype
|= DB_TYPE_MEMORY
;
390 if (global
.memory_db
== NULL
)
392 status
= asl_memory_open(global
.db_memory_max
, &(global
.memory_db
));
393 if (status
!= ASL_STATUS_OK
)
395 asldebug("asl_memory_open: %s\n", asl_core_error(status
));
402 if (dbtype
& DB_TYPE_MEMORY
)
405 status
= asl_memory_save(global
.memory_db
, msg
, &msgid
);
406 if (status
!= ASL_STATUS_OK
)
408 /* save failed - reopen & retry*/
409 asldebug("asl_memory_save: %s\n", asl_core_error(status
));
410 asl_memory_close(global
.memory_db
);
411 global
.memory_db
= NULL
;
415 status
= asl_memory_save(global
.memory_db
, msg
, &msgid
);
416 if (status
!= ASL_STATUS_OK
)
418 asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status
));
419 asl_memory_close(global
.memory_db
);
420 global
.memory_db
= NULL
;
425 if (dbtype
& DB_TYPE_MINI
)
427 status
= asl_mini_memory_save(global
.mini_db
, msg
, &msgid
);
428 if (status
!= ASL_STATUS_OK
)
430 /* save failed - reopen & retry*/
431 asldebug("asl_mini_memory_save: %s\n", asl_core_error(status
));
432 asl_mini_memory_close(global
.mini_db
);
433 global
.mini_db
= NULL
;
436 status
= asl_mini_memory_save(global
.mini_db
, msg
, &msgid
);
437 if (status
!= ASL_STATUS_OK
)
439 asldebug("(retry) asl_memory_save: %s\n", asl_core_error(status
));
440 asl_mini_memory_close(global
.mini_db
);
441 global
.mini_db
= NULL
;
449 dispatch_source_set_timer(timer_src
, dispatch_walltime(NULL
, NSEC_PER_SEC
/ 2), DISPATCH_TIME_FOREVER
, 0);
450 dispatch_resume(timer_src
);
455 disaster_message(aslmsg msg
)
462 if ((global
.dbtype
& DB_TYPE_MINI
) == 0)
464 if (global
.mini_db
== NULL
)
466 status
= asl_mini_memory_open(global
.db_mini_max
, &(global
.mini_db
));
467 if (status
!= ASL_STATUS_OK
) asldebug("asl_mini_memory_open: %s\n", asl_core_error(status
));
468 else asl_mini_memory_save(global
.mini_db
, msg
, &msgid
);
474 * Do a database search.
477 db_query(aslresponse query
, aslresponse
*res
, uint64_t startid
, int count
, int flags
, uint64_t *lastid
, int32_t ruid
, int32_t rgid
)
479 uint32_t status
, ucount
;
483 * Special case: if count is -1, we return ASL_STATUS_OK to indicate that the store is
484 * in memory, and ASL_STATUS_INVALID_STORE to indicate that the file store is in use.
488 if ((global
.dbtype
& DB_TYPE_MEMORY
) || (global
.dbtype
& DB_TYPE_MINI
)) return ASL_STATUS_OK
;
489 else return ASL_STATUS_INVALID_STORE
;
493 dir
= SEARCH_FORWARD
;
494 if (flags
& QUERY_FLAG_SEARCH_REVERSE
) dir
= SEARCH_BACKWARD
;
496 status
= ASL_STATUS_FAILED
;
498 if (global
.dbtype
& DB_TYPE_MEMORY
)
500 status
= asl_memory_match(global
.memory_db
, query
, res
, lastid
, startid
, ucount
, dir
, ruid
, rgid
);
502 else if (global
.dbtype
& DB_TYPE_MINI
)
504 status
= asl_mini_memory_match(global
.mini_db
, query
, res
, lastid
, startid
, ucount
, dir
);
506 else if (global
.disaster_occurred
!= 0)
508 /* KernelEventAgent calls us to get the kernel disaster messages. */
509 status
= asl_mini_memory_match(global
.mini_db
, query
, res
, lastid
, startid
, ucount
, dir
);
516 register_session(task_name_t task_name
, pid_t pid
)
518 mach_port_t previous
;
521 if (task_name
== MACH_PORT_NULL
) return;
523 if (global
.dead_session_port
== MACH_PORT_NULL
)
525 mach_port_deallocate(mach_task_self(), task_name
);
529 for (i
= 0; i
< client_tasks_count
; i
++) if (task_name
== client_tasks
[i
])
531 mach_port_deallocate(mach_task_self(), task_name
);
535 if (client_tasks_count
== 0) client_tasks
= (task_name_t
*)calloc(1, sizeof(task_name_t
));
536 else client_tasks
= (task_name_t
*)reallocf(client_tasks
, (client_tasks_count
+ 1) * sizeof(task_name_t
));
538 if (client_tasks
== NULL
)
540 mach_port_deallocate(mach_task_self(), task_name
);
544 client_tasks
[client_tasks_count
] = task_name
;
545 client_tasks_count
++;
547 asldebug("register_session: %u PID %d\n", (unsigned int)task_name
, (int)pid
);
549 /* register for port death notification */
550 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
);
551 mach_port_deallocate(mach_task_self(), previous
);
553 asl_client_count_increment();
557 cancel_session(task_name_t task_name
)
561 for (i
= 0; (i
< client_tasks_count
) && (task_name
!= client_tasks
[i
]); i
++);
563 if (i
>= client_tasks_count
) return;
565 if (client_tasks_count
== 1)
569 client_tasks_count
= 0;
573 for (i
++; i
< client_tasks_count
; i
++) client_tasks
[i
-1] = client_tasks
[i
];
574 client_tasks_count
--;
575 client_tasks
= (task_name_t
*)reallocf(client_tasks
, client_tasks_count
* sizeof(task_name_t
));
578 asldebug("cancel_session: %u\n", (unsigned int)task_name
);
580 /* we hold a send right or dead name right for the task name port */
581 mach_port_deallocate(mach_task_self(), task_name
);
582 asl_client_count_decrement();
586 register_direct_watch(uint16_t port
)
591 struct sockaddr_in address
;
593 if (port
== 0) return ASL_STATUS_FAILED
;
595 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
596 if (sock
< 0) return ASL_STATUS_FAILED
;
598 address
.sin_family
= AF_INET
;
599 /* port must be sent in network byte order */
600 address
.sin_port
= port
;
601 address
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
603 if (connect(sock
, (struct sockaddr
*)&address
, sizeof(address
)) != 0) return ASL_STATUS_FAILED
;
606 setsockopt(sock
, SOL_SOCKET
, SO_NOSIGPIPE
, &i
, sizeof(i
));
609 setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
, &i
, sizeof(i
));
611 /* make socket non-blocking */
612 flags
= fcntl(sock
, F_GETFL
, 0);
613 if (flags
== -1) flags
= 0;
614 fcntl(sock
, F_SETFL
, flags
| O_NONBLOCK
);
616 if (direct_watch_count
== 0)
618 direct_watch
= (int *)calloc(1, sizeof(int));
619 direct_watch_port
= (uint16_t *)calloc(1, sizeof(uint16_t));
623 direct_watch
= (int *)reallocf(direct_watch
, (direct_watch_count
+ 1) * sizeof(int));
624 direct_watch_port
= (uint16_t *)reallocf(direct_watch_port
, (direct_watch_count
+ 1) * sizeof(uint16_t));
627 if ((direct_watch
== NULL
) || (direct_watch_port
== NULL
))
634 free(direct_watch_port
);
635 direct_watch_port
= NULL
;
637 direct_watch_count
= 0;
638 global
.watchers_active
= 0;
639 if (global
.lockdown_session_fd
>= 0) global
.watchers_active
= 1;
641 return ASL_STATUS_FAILED
;
644 direct_watch
[direct_watch_count
] = sock
;
645 direct_watch_port
[direct_watch_count
] = port
;
646 direct_watch_count
++;
647 global
.watchers_active
= direct_watch_count
+ ((global
.lockdown_session_fd
< 0) ? 0 : 1);
649 return ASL_STATUS_OK
;
651 return ASL_STATUS_FAILED
;
656 cancel_direct_watch(uint16_t port
)
661 for (i
= 0; (i
< direct_watch_count
) && (port
!= direct_watch_port
[i
]); i
++);
663 if (i
>= direct_watch_count
) return;
665 if (direct_watch_count
== 1)
670 free(direct_watch_port
);
671 direct_watch_port
= NULL
;
673 direct_watch_count
= 0;
674 global
.watchers_active
= 0;
675 if (global
.lockdown_session_fd
>= 0) global
.watchers_active
= 1;
679 for (i
++; i
< direct_watch_count
; i
++)
681 direct_watch
[i
-1] = direct_watch
[i
];
682 direct_watch_port
[i
-1] = direct_watch_port
[i
];
685 direct_watch_count
--;
686 global
.watchers_active
= direct_watch_count
+ ((global
.lockdown_session_fd
< 0) ? 0 : 1);
688 direct_watch
= (int *)reallocf(direct_watch
, direct_watch_count
* sizeof(int));
689 direct_watch_port
= (uint16_t *)reallocf(direct_watch_port
, direct_watch_count
* sizeof(uint16_t));
691 if ((direct_watch
== NULL
) || (direct_watch_port
== NULL
))
696 free(direct_watch_port
);
697 direct_watch_port
= NULL
;
699 direct_watch_count
= 0;
700 global
.watchers_active
= 0;
701 if (global
.lockdown_session_fd
>= 0) global
.watchers_active
= 1;
708 * Receives messages on the "com.apple.system.logger" mach port.
709 * Services database search requests.
710 * Runs in it's own thread.
715 asl_request_msg
*request
;
717 uint32_t rbits
, sbits
;
719 struct timeval now
, send_time
;
720 mach_dead_name_notification_t
*deadname
;
722 send_time
.tv_sec
= 0;
723 send_time
.tv_usec
= 0;
725 rqs
= sizeof(asl_request_msg
) + MAX_TRAILER_SIZE
;
727 rbits
= MACH_RCV_MSG
| MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT
) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0
);
728 sbits
= MACH_SEND_MSG
| MACH_SEND_TIMEOUT
;
730 asl_server_queue
= dispatch_queue_create("ASL Server Queue", NULL
);
737 request
= (asl_request_msg
*)calloc(1, rqs
);
738 if (request
== NULL
) continue;
740 request
->head
.msgh_local_port
= global
.server_port
;
741 request
->head
.msgh_size
= rqs
;
745 (void)mach_msg(&(request
->head
), flags
, 0, rqs
, global
.listen_set
, 0, MACH_PORT_NULL
);
747 if (request
->head
.msgh_id
== MACH_NOTIFY_DEAD_NAME
)
749 deadname
= (mach_dead_name_notification_t
*)request
;
750 dispatch_async(asl_server_queue
, ^{
751 cancel_session(deadname
->not_port
);
752 /* dead name notification includes a dead name right */
753 mach_port_deallocate(mach_task_self(), deadname
->not_port
);
760 dispatch_async(asl_server_queue
, ^{
762 asl_reply_msg
*reply
= calloc(1, sizeof(asl_reply_msg
) + MAX_TRAILER_SIZE
);
764 asl_ipc_server(&(request
->head
), &(reply
->head
));
765 ks
= mach_msg(&(reply
->head
), sbits
, reply
->head
.msgh_size
, 0, MACH_PORT_NULL
, 10, MACH_PORT_NULL
);
767 if ((ks
== MACH_SEND_INVALID_DEST
) || (ks
== MACH_SEND_TIMED_OUT
))
770 mach_msg_destroy(&(reply
->head
));
783 mach_msg_type_number_t requestCnt
,
788 mach_msg_type_number_t
*replyCnt
,
791 security_token_t
*token
796 char *out
, *vmbuffer
;
798 kern_return_t kstatus
;
800 *status
= ASL_STATUS_OK
;
802 if ((request
!= NULL
) && (request
[requestCnt
- 1] != '\0'))
804 *status
= ASL_STATUS_INVALID_ARG
;
805 vm_deallocate(mach_task_self(), (vm_address_t
)request
, requestCnt
);
809 query
= asl_list_from_string(request
);
810 if (request
!= NULL
) vm_deallocate(mach_task_self(), (vm_address_t
)request
, requestCnt
);
813 *status
= db_query(query
, &res
, startid
, count
, flags
, lastid
, token
->val
[0], token
->val
[1]);
815 aslresponse_free(query
);
816 if (*status
!= ASL_STATUS_INVALID_STORE
)
820 else if (*status
!= ASL_STATUS_OK
)
822 if (res
!= NULL
) aslresponse_free(res
);
828 out
= asl_list_to_string((asl_search_result_t
*)res
, &outlen
);
829 aslresponse_free(res
);
831 if ((out
== NULL
) || (outlen
== 0)) return KERN_SUCCESS
;
833 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmbuffer
, outlen
, TRUE
);
834 if (kstatus
!= KERN_SUCCESS
)
840 memmove(vmbuffer
, out
, outlen
);
851 __asl_server_query_timeout
855 mach_msg_type_number_t requestCnt
,
860 mach_msg_type_number_t
*replyCnt
,
863 security_token_t
*token
866 return __asl_server_query(server
, request
, requestCnt
, startid
, count
, flags
, reply
, replyCnt
, lastid
, status
, token
);
874 mach_msg_type_number_t requestCnt
,
876 security_token_t
*token
887 mach_msg_type_number_t messageCnt
,
896 kern_return_t kstatus
;
897 mach_port_name_t client
;
904 if (message
[messageCnt
- 1] != '\0')
906 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
910 asldebug("__asl_server_message: %s\n", (message
== NULL
) ? "NULL" : message
);
912 msg
= (aslmsg
)asl_msg_from_string(message
);
913 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
915 if (msg
== NULL
) return KERN_SUCCESS
;
920 audit_token_to_au32(token
, NULL
, &uid
, &gid
, NULL
, NULL
, &pid
, NULL
, NULL
);
922 client
= MACH_PORT_NULL
;
923 kstatus
= task_name_for_pid(mach_task_self(), pid
, &client
);
924 if (kstatus
== KERN_SUCCESS
) register_session(client
, pid
);
926 snprintf(tmp
, sizeof(tmp
), "%d", uid
);
927 asl_set(msg
, ASL_KEY_UID
, tmp
);
929 snprintf(tmp
, sizeof(tmp
), "%d", gid
);
930 asl_set(msg
, ASL_KEY_GID
, tmp
);
932 snprintf(tmp
, sizeof(tmp
), "%d", pid
);
933 asl_set(msg
, ASL_KEY_PID
, tmp
);
935 dispatch_async(global
.work_queue
, ^{ process_message(msg
, SOURCE_ASL_MESSAGE
); });
941 __asl_server_create_aux_link
945 mach_msg_type_number_t messageCnt
,
946 mach_port_t
*fileport
,
948 mach_msg_type_number_t
*newurlCnt
,
958 kern_return_t kstatus
;
959 mach_port_name_t client
;
960 char *url
, *vmbuffer
;
963 *status
= ASL_STATUS_OK
;
967 *status
= ASL_STATUS_INVALID_ARG
;
971 if (message
[messageCnt
- 1] != '\0')
973 *status
= ASL_STATUS_INVALID_ARG
;
974 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
978 asldebug("__asl_server_create_aux_link: %s\n", (message
== NULL
) ? "NULL" : message
);
980 if ((global
.dbtype
& DB_TYPE_FILE
) == 0)
982 *status
= ASL_STATUS_INVALID_STORE
;
986 *fileport
= MACH_PORT_NULL
;
988 msg
= (aslmsg
)asl_msg_from_string(message
);
989 vm_deallocate(mach_task_self(), (vm_address_t
)message
, messageCnt
);
991 if (msg
== NULL
) return KERN_SUCCESS
;
996 audit_token_to_au32(token
, NULL
, &uid
, &gid
, NULL
, NULL
, &pid
, NULL
, NULL
);
998 client
= MACH_PORT_NULL
;
999 kstatus
= task_name_for_pid(mach_task_self(), pid
, &client
);
1000 if (kstatus
== KERN_SUCCESS
) register_session(client
, pid
);
1002 snprintf(tmp
, sizeof(tmp
), "%d", uid
);
1003 asl_set(msg
, ASL_KEY_UID
, tmp
);
1005 snprintf(tmp
, sizeof(tmp
), "%d", gid
);
1006 asl_set(msg
, ASL_KEY_GID
, tmp
);
1008 snprintf(tmp
, sizeof(tmp
), "%d", pid
);
1009 asl_set(msg
, ASL_KEY_PID
, tmp
);
1011 /* create a file for the client */
1012 *status
= asl_store_open_aux(global
.file_db
, msg
, &fd
, &url
);
1014 if (*status
!= ASL_STATUS_OK
) return KERN_SUCCESS
;
1017 if (fd
>= 0) close(fd
);
1018 *status
= ASL_STATUS_FAILED
;
1019 return KERN_SUCCESS
;
1022 if (fileport_makeport(fd
, (fileport_t
*)fileport
) < 0)
1026 *status
= ASL_STATUS_FAILED
;
1027 return KERN_SUCCESS
;
1032 *newurlCnt
= strlen(url
) + 1;
1034 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmbuffer
, *newurlCnt
, TRUE
);
1035 if (kstatus
!= KERN_SUCCESS
)
1041 memmove(vmbuffer
, url
, *newurlCnt
);
1046 return KERN_SUCCESS
;
1050 __asl_server_register_direct_watch
1057 uint16_t p16
= port
;
1058 pid_t pid
= (pid_t
)-1;
1060 audit_token_to_au32(token
, NULL
, NULL
, NULL
, NULL
, NULL
, &pid
, NULL
, NULL
);
1062 asldebug("__asl_server_register_direct_watch: pid %u port %hu\n", pid
, ntohs(p16
));
1064 register_direct_watch(p16
);
1066 return KERN_SUCCESS
;
1070 __asl_server_cancel_direct_watch
1077 uint16_t p16
= port
;
1079 asldebug("__asl_server_cancel_direct_watch: %hu\n", ntohs(p16
));
1081 cancel_direct_watch(p16
);
1083 return KERN_SUCCESS
;