2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
20 #include <Security/Authorization.h>
21 #include <Security/AuthorizationTags.h>
22 #include <Security/AuthSession.h>
23 #include <sys/types.h>
24 #include <sys/select.h>
25 #include <sys/event.h>
26 #include <sys/socket.h>
44 OSStatus
SessionCreate(SessionCreationFlags flags
, SessionAttributeBits attributes
) __attribute__((weak
));
49 static void find_fds(launch_data_t o
, const char *key
__attribute__((unused
)), void *context
__attribute__((unused
)))
55 switch (launch_data_get_type(o
)) {
57 fd
= launch_data_get_fd(o
);
60 fcntl(fd
, F_SETFD
, 1);
61 EV_SET(&kev
, fd
, EVFILT_READ
, EV_ADD
, 0, 0, NULL
);
62 if (kevent(kq
, &kev
, 1, NULL
, 0, NULL
) == -1)
63 syslog(LOG_DEBUG
, "kevent(%d): %m", fd
);
65 case LAUNCH_DATA_ARRAY
:
66 for (i
= 0; i
< launch_data_array_get_count(o
); i
++)
67 find_fds(launch_data_array_get_index(o
, i
), NULL
, NULL
);
69 case LAUNCH_DATA_DICTIONARY
:
70 launch_data_dict_iterate(o
, find_fds
, NULL
);
77 int main(int argc
__attribute__((unused
)), char *argv
[])
79 struct timespec timeout
= { 10, 0 };
80 struct sockaddr_storage ss
;
81 socklen_t slen
= sizeof(ss
);
83 int r
, ec
= EXIT_FAILURE
;
84 launch_data_t tmp
, resp
, msg
= launch_data_alloc(LAUNCH_DATA_STRING
);
85 const char *prog
= argv
[1];
86 bool w
= false, dupstdout
= true, dupstderr
= true;
88 launch_data_set_string(msg
, LAUNCH_KEY_CHECKIN
);
90 openlog(getprogname(), LOG_PERROR
|LOG_PID
|LOG_CONS
, LOG_LAUNCHD
);
94 if ((resp
= launch_msg(msg
)) == NULL
) {
95 syslog(LOG_ERR
, "launch_msg(%s): %m", LAUNCH_KEY_CHECKIN
);
99 launch_data_free(msg
);
101 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_SOCKETS
);
103 find_fds(tmp
, NULL
, NULL
);
105 syslog(LOG_ERR
, "No FDs found to answer requests on!");
109 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_TIMEOUT
);
111 timeout
.tv_sec
= (int)launch_data_get_integer(tmp
);
113 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_PROGRAM
);
115 prog
= launch_data_get_string(tmp
);
117 tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_INETDCOMPATIBILITY
);
119 tmp
= launch_data_dict_lookup(tmp
, LAUNCH_JOBINETDCOMPATIBILITY_WAIT
);
121 w
= launch_data_get_bool(tmp
);
124 if (launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_STANDARDOUTPATH
))
127 if (launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_STANDARDERRORPATH
))
131 signal(SIGCHLD
, SIG_IGN
);
134 if ((r
= kevent(kq
, NULL
, 0, &kev
, 1, &timeout
)) == -1) {
135 syslog(LOG_DEBUG
, "kevent(): %m");
143 dup2(kev
.ident
, STDIN_FILENO
);
145 dup2(kev
.ident
, STDOUT_FILENO
);
147 dup2(kev
.ident
, STDERR_FILENO
);
148 execv(prog
, argv
+ 1);
149 syslog(LOG_ERR
, "execv(): %m");
153 if ((r
= accept(kev
.ident
, (struct sockaddr
*)&ss
, &slen
)) == -1) {
154 if (errno
== EWOULDBLOCK
)
156 syslog(LOG_DEBUG
, "accept(): %m");
159 char fromhost
[NI_MAXHOST
];
160 char fromport
[NI_MAXSERV
];
163 gni_r
= getnameinfo((struct sockaddr
*)&ss
, slen
,
164 fromhost
, sizeof(fromhost
),
165 fromport
, sizeof(fromport
),
166 NI_NUMERICHOST
| NI_NUMERICSERV
);
169 syslog(LOG_WARNING
, "%s: getnameinfo(): %s", prog
, gai_strerror(gni_r
));
171 syslog(LOG_INFO
, "%s: Connection from: %s on port: %s", prog
, fromhost
, fromport
);
176 syslog(LOG_WARNING
, "fork(): %m");
187 if ((tmp
= launch_data_dict_lookup(resp
, LAUNCH_JOBKEY_SESSIONCREATE
)) && launch_data_get_bool(tmp
)) {
189 OSStatus scr
= SessionCreate(0, 0);
191 syslog(LOG_NOTICE
, "%s: SessionCreate() failed: %d", prog
, scr
);
193 syslog(LOG_NOTICE
, "%s: SessionCreate == NULL!", prog
);
196 fcntl(r
, F_SETFL
, 0);
197 dup2(r
, STDIN_FILENO
);
199 dup2(r
, STDOUT_FILENO
);
201 dup2(r
, STDERR_FILENO
);
202 signal(SIGCHLD
, SIG_DFL
);
203 execv(prog
, argv
+ 1);
204 syslog(LOG_ERR
, "execv(): %m");