/* * mach_client_utilities.c * * $Header$ * * Copyright 2003 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include kern_return_t __KerberosIPCError (kern_return_t inError, const char *function, const char *file, int line) { if ((inError != KERN_SUCCESS) && (ddebuglevel () > 0)) { dprintf ("%s() got %d ('%s') at %s: %d", function, inError, mach_error_string (inError), file, line); dprintf ("Session is %s", LoginSessionGetSecuritySessionName ()); //dprintbootstrap (mach_task_self ()); } return inError; } #pragma mark - // --------------------------------------------------------------------------- static kern_return_t mach_client_check_server_registration (mach_port_t inBootstrapPort, const char *inServiceName, const char *inServerPath) { kern_return_t err = KERN_SUCCESS; boolean_t active = FALSE; if (inBootstrapPort == MACH_PORT_NULL) { err = EINVAL; } if (inServiceName == NULL ) { err = EINVAL; } if (inServerPath == NULL ) { err = EINVAL; } if (err == KERN_SUCCESS) { // Is the service registered? err = bootstrap_status (inBootstrapPort, (char *) inServiceName, &active); if ((err != KERN_SUCCESS) || (active == BOOTSTRAP_STATUS_INACTIVE)) { if (!LoginSessionIsRootSession ()) { // Never register per-user servers in the root bootstrap mach_port_t serverPrivPort = MACH_PORT_NULL; mach_port_t servicePort = MACH_PORT_NULL; uid_t serverUID = LoginSessionGetSessionUID (); if (serverUID == 0 /* root */) { serverUID = LoginSessionGetSecurityAgentUID (); } // don't be root // The service got unregistered or was never registered. Register it! err = bootstrap_create_server (inBootstrapPort, (char *) inServerPath, serverUID, TRUE /* on demand */, &serverPrivPort); dprintf ("mach_client_check_server_registration(): bootstrap_create_server() returned err %d", err); if (err == KERN_SUCCESS) { // Set up the server to autolaunch err = bootstrap_create_service (serverPrivPort, (char *) inServiceName, &servicePort); dprintf ("mach_client_check_server_registration(): bootstrap_create_service() returned err %d", err); } if (err == KERN_SUCCESS) { dprintf ("mach_client_check_server_registration(): registered '%s' for service '%s' and uid '%d'.", inServerPath, inServiceName, serverUID); } if (serverPrivPort != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), serverPrivPort); } if (servicePort != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), servicePort); } } } } return KerberosIPCError_ (err); } // --------------------------------------------------------------------------- kern_return_t mach_client_lookup_server (const char *inServiceName, mach_port_t *outServicePort) { kern_return_t err = KERN_SUCCESS; mach_port_t bootstrapPort = MACH_PORT_NULL; boolean_t active = FALSE; if (inServiceName == NULL) { err = EINVAL; } if (outServicePort == NULL) { err = EINVAL; } if (err == KERN_SUCCESS) { // Get our bootstrap port err = task_get_bootstrap_port (mach_task_self (), &bootstrapPort); } if (err == KERN_SUCCESS) { // Is the service running? err = bootstrap_status (bootstrapPort, (char *) inServiceName, &active); // dprintf ("mcls: bootstrap_status('%s'): status is %ld (err = %ld '%s')", // inServiceName, active, err, mach_error_string (err)); } if (err == KERN_SUCCESS) { if (active != BOOTSTRAP_STATUS_ACTIVE) { err = BOOTSTRAP_UNKNOWN_SERVICE; } } if (err == KERN_SUCCESS) { // This will return a valid port even if the server isn't running // which is why we call bootstrap_status() above err = bootstrap_look_up (bootstrapPort, (char *) inServiceName, outServicePort); // dprintf ("mcls: bootstrap_look_up('%s'): port is %lx (err = %ld '%s')", // inServiceName, outServicePort, err, mach_error_string (err)); } if (bootstrapPort != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), bootstrapPort); } if (err == BOOTSTRAP_UNKNOWN_SERVICE) { return err; // Avoid spewing to the log file } else { return KerberosIPCError_ (err); } } // --------------------------------------------------------------------------- kern_return_t mach_client_lookup_and_launch_server (const char *inServiceName, const char *inServerPath, mach_port_t *outServicePort) { kern_return_t err = KERN_SUCCESS; mach_port_t bootstrapPort = MACH_PORT_NULL; if (inServiceName == NULL) { err = EINVAL; } if (inServerPath == NULL) { err = EINVAL; } if (outServicePort == NULL) { err = EINVAL; } if (err == KERN_SUCCESS) { // Get our bootstrap port err = task_get_bootstrap_port (mach_task_self (), &bootstrapPort); } if (err == KERN_SUCCESS) { // Make sure the service is registered err = mach_client_check_server_registration (bootstrapPort, inServiceName, inServerPath); } if (err == KERN_SUCCESS) { // This will return a valid port even if the server isn't running err = bootstrap_look_up (bootstrapPort, (char *) inServiceName, outServicePort); // dprintf ("mclals: bootstrap_look_up('%s'): port is %lx (err = %ld '%s')", // inServiceName, outServicePort, err, mach_error_string (err)); } if (bootstrapPort != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), bootstrapPort); } return KerberosIPCError_ (err); } #pragma mark -