Пример #1
0
static kim_error kim_error_set_message (kim_error  in_error,
                                        kim_string in_message)
{
    int lock_err = 0;
    kim_error err = KIM_NO_ERROR;
    kim_last_error last_error = NULL;

    err = lock_err = k5_mutex_lock (&kim_error_lock);

    if (!err) {
        last_error = k5_getspecific (K5_KEY_KIM_ERROR_MESSAGE);

        if (!last_error) {
            last_error = malloc (sizeof (*last_error));
            if (!last_error) {
                err = KIM_OUT_OF_MEMORY_ERR;
            } else {
                last_error->code = KIM_NO_ERROR;
                err = k5_setspecific (K5_KEY_KIM_ERROR_MESSAGE, last_error);
            }
        }
    }

    if (!err) {
        strncpy (last_error->message, in_message, sizeof (last_error->message));
        last_error->message[sizeof (last_error->message)-1] = '\0';
        last_error->code = in_error;
    }

    if (!lock_err) { k5_mutex_unlock (&kim_error_lock); }

    return err;
}
static char *
get_thread_buffer ()
{
    char *cp;
    cp = k5_getspecific(K5_KEY_COM_ERR);
    if (cp == NULL) {
        cp = malloc(ET_EBUFSIZ);
        if (cp == NULL) {
            return NULL;
        }
        if (k5_setspecific(K5_KEY_COM_ERR, cp) != 0) {
            free(cp);
            return NULL;
        }
    }
    return cp;
}
Пример #3
0
kim_string kim_error_message (kim_error in_error)
{
    int lock_err = 0;
    kim_last_error last_error = NULL;
    kim_string message = NULL;

    lock_err = k5_mutex_lock (&kim_error_lock);

    if (!lock_err) {
        last_error = k5_getspecific (K5_KEY_KIM_ERROR_MESSAGE);
        if (last_error && last_error->code == in_error) {
            message = last_error->message;
         }
    }

    if (!lock_err) { k5_mutex_unlock (&kim_error_lock); }

    return message ? message : error_message (kim_error_remap (in_error));
}
Пример #4
0
kern_return_t k5_ipc_client_reply (mach_port_t             in_reply_port,
                                   k5_ipc_inl_reply_t      in_inl_reply,
                                   mach_msg_type_number_t  in_inl_replyCnt,
                                   k5_ipc_ool_reply_t      in_ool_reply,
                                   mach_msg_type_number_t  in_ool_replyCnt)
{
    kern_return_t err = KERN_SUCCESS;
    k5_ipc_connection_info cinfo = NULL;
    
    if (!err) {
        err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init);
    }
    
    if (!err) {
        cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO);
        if (!cinfo || !cinfo->reply_stream) { err = EINVAL; }
    }
    
    if (!err) {
        if (in_inl_replyCnt) {
            err = k5_ipc_stream_write (cinfo->reply_stream, 
                                       in_inl_reply, in_inl_replyCnt);
            
        } else if (in_ool_replyCnt) {
            err = k5_ipc_stream_write (cinfo->reply_stream, 
                                       in_ool_reply, in_ool_replyCnt);
            
        } else {
            err = EINVAL;
        }
    }
    
    if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), 
                                          (vm_address_t) in_ool_reply, 
                                          in_ool_replyCnt); }
    
    return err;
}
Пример #5
0
static int save_error_string_nocopy(OM_uint32 minor_code, char *msg)
{
    gsserrmap *p;
    int ret;

#ifdef DEBUG
    fprintf(stderr, "%s(%lu, %s)", __func__, (unsigned long) minor_code, msg);
#endif
    p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE);
    if (!p) {
        p = malloc(sizeof(*p));
        if (p == NULL) {
            ret = 1;
            goto fail;
        }
        if (gsserrmap_init(p) != 0) {
            free(p);
            p = NULL;
            ret = 1;
            goto fail;
        }
        if (k5_setspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE, p) != 0) {
            gsserrmap_destroy(p);
            free(p);
            p = NULL;
            ret = 1;
            goto fail;
        }
    }
    ret = gsserrmap_replace_or_insert(p, minor_code, msg);
fail:
#ifdef DEBUG
    fprintf(stderr, " p=%p %s\n", (void *)p, ret ? "FAIL" : "SUCCESS");
#endif
    return ret;
}
Пример #6
0
char *get_error_message(OM_uint32 minor_code)
{
    gsserrmap *p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE);
    char *msg = NULL;
#ifdef DEBUG
    fprintf(stderr, "%s(%lu, p=%p)", __func__, (unsigned long) minor_code,
            (void *) p);
#endif
    if (p) {
        char **v = gsserrmap_find(p, minor_code);
        if (v) {
            msg = *v;
#ifdef DEBUG
            fprintf(stderr, " FOUND!");
#endif
        }
    }
    if (msg == 0)
        msg = (char *)error_message((krb5_error_code)minor_code);
#ifdef DEBUG
    fprintf(stderr, " -> %p/%s\n", (void *) msg, msg);
#endif
    return msg;
}
Пример #7
0
static boolean_t k5_ipc_reply_demux (mach_msg_header_t *request, 
                                     mach_msg_header_t *reply) 
{
    boolean_t handled = 0;
    
    if (CALL_INIT_FUNCTION (k5_cli_ipc_thread_init) != 0) {
        return 0;
    }    
    
    if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
        k5_ipc_connection_info cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO);
        if (cinfo) { 
            cinfo->server_died = 1;
        }
        
        handled = 1; /* server died */
    }
    
    if (!handled) {
        handled = k5_ipc_reply_server (request, reply);
    }
    
    return handled;    
}
Пример #8
0
int32_t k5_ipc_send_request (const char    *in_service_id,
                             int32_t        in_launch_server,
                             k5_ipc_stream  in_request_stream,
                             k5_ipc_stream *out_reply_stream)
{
    int err = 0;
    int32_t done = 0;
    int32_t try_count = 0;
    mach_port_t server_port = MACH_PORT_NULL;
    k5_ipc_connection_info cinfo = NULL;
    k5_ipc_connection connection = NULL;
    mach_port_t reply_port = MACH_PORT_NULL;
    const char *inl_request = NULL; /* char * so we can pass the buffer in directly */
    mach_msg_type_number_t inl_request_length = 0;
    k5_ipc_ool_request_t ool_request = NULL;
    mach_msg_type_number_t ool_request_length = 0;

    if (!in_request_stream) { err = EINVAL; }
    if (!out_reply_stream ) { err = EINVAL; }
    
    if (!err) {
        err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init);
    }    
    
    if (!err) {
        /* depending on how big the message is, use the fast inline buffer or  
         * the slow dynamically allocated buffer */
        mach_msg_type_number_t request_length = k5_ipc_stream_size (in_request_stream);
        
        if (request_length > K5_IPC_MAX_INL_MSG_SIZE) {
            /*dprintf ("%s choosing out of line buffer (size is %d)", 
             *                  __FUNCTION__, request_length); */
            
            err = vm_read (mach_task_self (), 
                           (vm_address_t) k5_ipc_stream_data (in_request_stream), 
                           request_length, 
                           (vm_address_t *) &ool_request, 
                           &ool_request_length);        
        } else {
            /*dprintf ("%s choosing in line buffer (size is %d)",
             *                  __FUNCTION__, request_length); */
            
            inl_request_length = request_length;
            inl_request = k5_ipc_stream_data (in_request_stream);
        }
    }

    if (!err) {
        cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO);

        if (!cinfo) {
            err = k5_ipc_client_cinfo_allocate (&cinfo);

            if (!err) {
                err = k5_setspecific (K5_KEY_IPC_CONNECTION_INFO, cinfo);
            }
        }
        
        if (!err) {
            int i, found = 0;

            for (i = 0; i < KIPC_SERVICE_COUNT; i++) {
                if (!strcmp (in_service_id, cinfo->connections[i].service_id)) {
                    found = 1;
                    connection = &cinfo->connections[i];
                    break;
                }
            }
            
            if (!found) { err = EINVAL; }
        }
    }
    
    if (!err) {
        err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, 
                                           TRUE, &server_port);
    }

    if (!err) {
        err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, 
                                  &reply_port);
    }
    
    while (!err && !done) {
        if (!err && !MACH_PORT_VALID (connection->port)) {
            err = k5_ipc_client_create_client_connection (server_port, 
                                                          &connection->port);
        }
        
        if (!err) {
            err = k5_ipc_client_request (connection->port, reply_port,
                                         inl_request, inl_request_length,
                                         ool_request, ool_request_length);
            
        }
        
        if (err == MACH_SEND_INVALID_DEST) {
            if (try_count < 2) { 
                try_count++;
                err = 0;
            }

            if (MACH_PORT_VALID (connection->port)) {
                mach_port_mod_refs (mach_task_self(), connection->port, 
                                    MACH_PORT_RIGHT_SEND, -1 );
                connection->port = MACH_PORT_NULL;
            }    
            
            /* Look up server name again without using the cached copy */
            err = k5_ipc_client_lookup_server (in_service_id,  
                                               in_launch_server, 
                                               FALSE, &server_port);
            
        } else {
            /* Talked to server, though we may have gotten an error */
            done = 1;
            
            /* Because we use ",dealloc" ool_request will be freed by mach. 
            * Don't double free it. */
            ool_request = NULL; 
            ool_request_length = 0;                
        }            
    }
    
    if (!err) {
        err = k5_ipc_stream_new (&cinfo->reply_stream);
    }
    
    if (!err) {
        mach_port_t old_notification_target = MACH_PORT_NULL;

        /* request no-senders notification so we know when server dies */
        err = mach_port_request_notification (mach_task_self (), reply_port, 
                                              MACH_NOTIFY_NO_SENDERS, 1, 
                                              reply_port, 
                                              MACH_MSG_TYPE_MAKE_SEND_ONCE, 
                                              &old_notification_target);
        
        if (!err && old_notification_target != MACH_PORT_NULL) {
            mach_port_deallocate (mach_task_self (), old_notification_target);
        }
    }
    
    if (!err) {
        cinfo->server_died = 0;
        
        err = mach_msg_server_once (k5_ipc_reply_demux, K5_IPC_MAX_MSG_SIZE, 
                                    reply_port, MACH_MSG_TIMEOUT_NONE);
        
        if (!err && cinfo->server_died) {
            err = ENOTCONN;
        }
    }
    
    if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {
        err = 0;  /* If server is not running just return an empty stream. */
    }
    
    if (!err) {
        *out_reply_stream = cinfo->reply_stream;
        cinfo->reply_stream = NULL;
    }
 
    if (reply_port != MACH_PORT_NULL) { 
        mach_port_destroy (mach_task_self (), reply_port); 
    }
    if (ool_request_length) { 
        vm_deallocate (mach_task_self (), 
                       (vm_address_t) ool_request, ool_request_length); 
    }
    if (cinfo && cinfo->reply_stream) { 
        k5_ipc_stream_release (cinfo->reply_stream); 
        cinfo->reply_stream = NULL;
    }
    
    return err;    
}