static mach_port_t register_service(const char *service_name)
	{
	mach_port_t port = MACH_PORT_NULL;
	kern_return_t kr;

	if (KERN_SUCCESS == (kr = bootstrap_check_in(bootstrap_port, (char *)service_name, &port)))
		{
		if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
			helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr));
		else
			return port;
		}
	if (KERN_SUCCESS != (kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_allocate: %s", mach_error_string(kr)); goto error; }
	if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto error; }

	// XXX bootstrap_register does not modify its second argument, but the prototype does not include const.
	if (KERN_SUCCESS != (kr = bootstrap_register(bootstrap_port, (char *)service_name, port)))
		{ helplog(ASL_LEVEL_ERR, "bootstrap_register failed: %s", mach_error_string(kr)); goto error; }

	return port;
error:
	if (MACH_PORT_NULL != port) mach_port_deallocate(mach_task_self(), port);
	return MACH_PORT_NULL;
	}
示例#2
0
static void diediedie(CFRunLoopTimerRef timer, void *context)
{
    debug("entry %p %p %d", timer, context, actualidle);
    assert(gTimer == timer);
    helplog(ASL_LEVEL_INFO, "mDNSResponder exiting after %d seconds", actualidle);
    if (actualidle)
        (void)proxy_mDNSExit(gPort);
}
static mach_port_t checkin(char *service_name)
	{
	kern_return_t kr = KERN_SUCCESS;
	mach_port_t port = MACH_PORT_NULL;
	launch_data_t msg = NULL, reply = NULL, datum = NULL;

	if (NULL == (msg = launch_data_new_string(LAUNCH_KEY_CHECKIN)))
		{ helplog(ASL_LEVEL_ERR, "Could not create checkin message for launchd."); goto fin; }
	if (NULL == (reply = launch_msg(msg)))
		{ helplog(ASL_LEVEL_ERR, "Could not message launchd."); goto fin; }
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(reply))
		{
		if (launch_data_get_errno(reply) == EACCES) { launch_data_free(msg); launch_data_free(reply); return(MACH_PORT_NULL); }
		helplog(ASL_LEVEL_ERR, "Launchd checkin failed: %s.", strerror(launch_data_get_errno(reply))); goto fin;
		}
	if (NULL == (datum = launch_data_dict_lookup(reply, LAUNCH_JOBKEY_MACHSERVICES)) || LAUNCH_DATA_DICTIONARY != launch_data_get_type(datum))
		{ helplog(ASL_LEVEL_ERR, "Launchd reply does not contain %s dictionary.", LAUNCH_JOBKEY_MACHSERVICES); goto fin; }
	if (NULL == (datum = launch_data_dict_lookup(datum, service_name)) || LAUNCH_DATA_MACHPORT != launch_data_get_type(datum))
		{ helplog(ASL_LEVEL_ERR, "Launchd reply does not contain %s Mach port.", service_name); goto fin; }
	if (MACH_PORT_NULL == (port = launch_data_get_machport(datum)))
		{ helplog(ASL_LEVEL_ERR, "Launchd gave me a null Mach port."); goto fin; }
	if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto fin; }

fin:
	if (NULL != msg)   launch_data_free(msg);
	if (NULL != reply) launch_data_free(reply);
	if (MACH_PORT_NULL == port) exit(EXIT_FAILURE);
	return port;
	}
示例#4
0
// for safe_vproc
void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *fmt, ...)
{
    (void)logLevel;
    va_list ap;
    va_start(ap, fmt);
    // safe_vproc only calls LogMsg, so assume logLevel maps to ASL_LEVEL_ERR
    helplog(ASL_LEVEL_ERR, fmt, ap);
    va_end(ap);
}
kern_return_t
do_LKDCHelperExit (__unused mach_port_t port, audit_token_t token)
{
	if (!authorized(token))
		goto fin;
	helplog(ASL_LEVEL_NOTICE, "Idle exit");
	exit(0);

fin:
	return KERN_SUCCESS;
}
示例#6
0
static mach_port_t register_service(const char *service_name)
{
    mach_port_t port = MACH_PORT_NULL;
    kern_return_t kr;

    if (KERN_SUCCESS != (kr = bootstrap_check_in(bootstrap_port, (char *)service_name, &port)))
    {
        helplog(ASL_LEVEL_ERR, "bootstrap_check_in: %d %X %s", kr, kr, mach_error_string(kr));
        return MACH_PORT_NULL;
    }
    
    if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
    {
        helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %d %X %s", kr, kr, mach_error_string(kr));
        mach_port_deallocate(mach_task_self(), port);
        return MACH_PORT_NULL;
    }

    return port;
}
示例#7
0
static int initialize_timer()
{
    gTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + actualidle, actualidle, 0, 0, diediedie, NULL);
    int err = 0;

    debug("entry");
    if (0 != (err = pthread_create(&idletimer_thread, NULL, idletimer, NULL)))
        helplog(ASL_LEVEL_ERR, "Could not start idletimer thread: %s", strerror(err));

    return err;
}
示例#8
0
static void initialize_id(void)
{
    static char login[] = "_mdnsresponder";
    struct passwd hardcode;
    struct passwd *pwd = &hardcode; // getpwnam(login);
    hardcode.pw_uid = 65;
    hardcode.pw_gid = 65;

    if (!pwd) { helplog(ASL_LEVEL_ERR, "Could not find account name `%s'.  I will only help root.", login); return; }
    mDNSResponderUID = pwd->pw_uid;
    mDNSResponderGID = pwd->pw_gid;
}
示例#9
0
int main(int ac, char *av[])
{
    char *p = NULL;
    kern_return_t kr = KERN_FAILURE;
    long n;
    int ch;
    mach_msg_header_t hdr;

    while ((ch = getopt(ac, av, "dt:")) != -1)
        switch (ch)
        {
        case 'd': opt_debug = 1; break;
        case 't':
            n = strtol(optarg, &p, 0);
            if ('\0' == optarg[0] || '\0' != *p || n > LONG_MAX || n < 0)
            { fprintf(stderr, "Invalid idle timeout: %s\n", optarg); exit(EXIT_FAILURE); }
            maxidle = n;
            break;
        case '?':
        default:
            fprintf(stderr, "Usage: mDNSResponderHelper [-d] [-t maxidle]\n");
            exit(EXIT_FAILURE);
        }
    ac -= optind;
    av += optind;
    (void)ac; // Unused
    (void)av; // Unused

    initialize_logging();
    helplog(ASL_LEVEL_INFO, "Starting");
    initialize_id();

#ifndef NO_SECURITYFRAMEWORK
    // We should normally be running as a system daemon.  However, that might not be the case in some scenarios (e.g. debugging).
    // Explicitly ensure that our Keychain operations utilize the system domain.
    if (opt_debug) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
#endif
    gPort = register_service(kmDNSHelperServiceName);
    if (!gPort)
        exit(EXIT_FAILURE);

    if (maxidle) actualidle = maxidle;

    signal(SIGTERM, handle_sigterm);

    if (initialize_timer()) exit(EXIT_FAILURE);
    for (n=0; n<100000; n++) if (!gRunLoop) usleep(100);
    if (!gRunLoop)
    {
        helplog(ASL_LEVEL_ERR, "gRunLoop not set after waiting");
        exit(EXIT_FAILURE);
    }

    for(;;)
    {
        hdr.msgh_bits = 0;
        hdr.msgh_local_port = gPort;
        hdr.msgh_remote_port = MACH_PORT_NULL;
        hdr.msgh_size = sizeof(hdr);
        hdr.msgh_id = 0;
        kr = mach_msg(&hdr, MACH_RCV_LARGE | MACH_RCV_MSG, 0, hdr.msgh_size, gPort, 0, 0);
        if (MACH_RCV_TOO_LARGE != kr)
            helplog(ASL_LEVEL_ERR, "main MACH_RCV_MSG error: %d %X %s", kr, kr, mach_error_string(kr));

        kr = mach_msg_server_once(helper_server, MAX_MSG_SIZE, gPort,
                                  MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
        if (KERN_SUCCESS != kr)
        { helplog(ASL_LEVEL_ERR, "mach_msg_server: %d %X %s", kr, kr, mach_error_string(kr)); exit(EXIT_FAILURE); }

    }
    exit(EXIT_SUCCESS);
}