2 * Copyright (c) 2005 Apple Computer, 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@
23 #include <Security/Authorization.h>
24 #include <Security/AuthorizationTags.h>
25 #include <Security/AuthSession.h>
26 #include <sys/types.h>
27 #include <sys/select.h>
28 #include <sys/event.h>
29 #include <sys/socket.h>
47 OSStatus
SessionCreate(SessionCreationFlags flags
, SessionAttributeBits attributes
) __attribute__((weak
));
52 static void find_fds(launch_data_t o
, const char *key
__attribute__((unused
)), void *context
__attribute__((unused
)))
58 switch (launch_data_get_type(o
)) {
60 fd
= launch_data_get_fd(o
);
63 fcntl(fd
, F_SETFD
, 1);
64 EV_SET(&kev
, fd
, EVFILT_READ
, EV_ADD
, 0, 0, NULL
);
65 if (kevent(kq
, &kev
, 1, NULL
, 0, NULL
) == -1)
66 syslog(LOG_DEBUG
, "kevent(%d): %m", fd
);
68 case LAUNCH_DATA_ARRAY
:
69 for (i
= 0; i
< launch_data_array_get_count(o
); i
++)
70 find_fds(launch_data_array_get_index(o
, i
), NULL
, NULL
);
72 case LAUNCH_DATA_DICTIONARY
:
73 launch_data_dict_iterate(o
, find_fds
, NULL
);
80 int main(int argc
__attribute__((unused
)), char *argv
[])
82 struct timespec timeout
= { 10, 0 };
83 struct sockaddr_storage ss
;
84 socklen_t slen
= sizeof(ss
);
86 int r
, ec
= EXIT_FAILURE
;
87 launch_data_t tmp
, resp
, msg
= launch_data_alloc(LAUNCH_DATA_STRING
);
88 const char *prog
= argv
[1];
89 bool w
= false, dupstdout
= true, dupstderr
= true;
91 launch_data_set_string(msg
, LAUNCH_KEY_CHECKIN
);
93 openlog(getprogname(), LOG_PERROR
|LOG_PID
|LOG_CONS
, LOG_LAUNCHD
);
97 if ((resp
= launch_msg(msg
)) == NULL
) {
98 syslog(LOG_ERR
, "launch_msg(%s): %m", LAUNCH_KEY_CHECKIN
);
102 launch_data_free(msg
);
104 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_SOCKETS
);
106 find_fds(tmp
, NULL
, NULL
);
108 syslog(LOG_ERR
, "No FDs found to answer requests on!");
112 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_TIMEOUT
);
114 timeout
.tv_sec
= launch_data_get_integer(tmp
);
116 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_PROGRAM
);
118 prog
= launch_data_get_string(tmp
);
120 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_INETDCOMPATIBILITY
);
122 tmp
= launch_data_dict_lookup(tmp
, LAUNCH_JOBINETDCOMPATIBILITY_WAIT
);
124 w
= launch_data_get_bool(tmp
);
127 if (launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_STANDARDOUTPATH
))
130 if (launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_STANDARDERRORPATH
))
134 signal(SIGCHLD
, SIG_IGN
);
137 if ((r
= kevent(kq
, NULL
, 0, &kev
, 1, &timeout
)) == -1) {
138 syslog(LOG_DEBUG
, "kevent(): %m");
146 dup2(kev
.ident
, STDIN_FILENO
);
148 dup2(kev
.ident
, STDOUT_FILENO
);
150 dup2(kev
.ident
, STDERR_FILENO
);
151 execv(prog
, argv
+ 1);
152 syslog(LOG_ERR
, "execv(): %m");
156 if ((r
= accept(kev
.ident
, (struct sockaddr
*)&ss
, &slen
)) == -1) {
157 if (errno
== EWOULDBLOCK
)
159 syslog(LOG_DEBUG
, "accept(): %m");
162 char fromhost
[NI_MAXHOST
];
163 char fromport
[NI_MAXSERV
];
166 gni_r
= getnameinfo((struct sockaddr
*)&ss
, slen
,
167 fromhost
, sizeof(fromhost
),
168 fromport
, sizeof(fromport
),
169 NI_NUMERICHOST
| NI_NUMERICSERV
);
172 syslog(LOG_WARNING
, "%s: getnameinfo(): %s", prog
, gai_strerror(gni_r
));
174 syslog(LOG_INFO
, "%s: Connection from: %s on port: %s", prog
, fromhost
, fromport
);
179 syslog(LOG_WARNING
, "fork(): %m");
188 if ((tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_SESSIONCREATE
)) && launch_data_get_bool(tmp
)) {
190 OSStatus scr
= SessionCreate(0, 0);
192 syslog(LOG_NOTICE
, "%s: SessionCreate() failed: %d", prog
, scr
);
194 syslog(LOG_NOTICE
, "%s: SessionCreate == NULL!", prog
);
197 fcntl(r
, F_SETFL
, 0);
198 dup2(r
, STDIN_FILENO
);
200 dup2(r
, STDOUT_FILENO
);
202 dup2(r
, STDERR_FILENO
);
203 signal(SIGCHLD
, SIG_DFL
);
204 execv(prog
, argv
+ 1);
205 syslog(LOG_ERR
, "execv(): %m");