Beispiel #1
0
cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback,
				       k5_ipc_stream   in_stream)
{
    cc_int32 err = ccNoError;
    
    if (!io_callback) { err = cci_check_error (ccErrBadParam); }
    
    if (!err) {
        if (io_callback->pending) {
	    cci_debug_printf ("%s: callback %p replying to client.", __FUNCTION__, io_callback);

            err = ccs_server_send_reply (io_callback->reply_pipe, err, in_stream);
            
            if (err) {
                cci_debug_printf ("WARNING %s() called on a lock belonging to a dead client!", 
                                  __FUNCTION__);
            }
            
            io_callback->pending = 0;
        } else {
            cci_debug_printf ("WARNING %s() called on non-pending callback!", 
                              __FUNCTION__);
        }
    }
    
    return cci_check_error (err);    
}
Beispiel #2
0
static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t              in_client_pipe,
					    ccs_pipe_t              in_reply_pipe,
					    ccs_ccache_t            io_ccache,
					    ccs_cache_collection_t  io_cache_collection,
					    k5_ipc_stream            in_request_data,
					    k5_ipc_stream            io_reply_data,
					    cc_uint32              *out_will_block)
{
    cc_int32 err = ccNoError;
    cc_time_t last_wait_for_change_time = 0;
    cc_uint32 will_block = 0;

    if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
    if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); }
    if (!io_ccache                      ) { err = cci_check_error (ccErrBadParam); }
    if (!io_cache_collection            ) { err = cci_check_error (ccErrBadParam); }
    if (!in_request_data                ) { err = cci_check_error (ccErrBadParam); }
    if (!out_will_block                 ) { err = cci_check_error (ccErrBadParam); }

    if (!err) {
        err = krb5int_ipc_stream_read_time (in_request_data, &last_wait_for_change_time);
    }

    if (!err) {
	if (last_wait_for_change_time < io_ccache->last_changed_time) {
	    cci_debug_printf ("%s returning immediately", __FUNCTION__);
	    err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time);

	} else {
	    ccs_callback_t callback = NULL;

	    err = ccs_callback_new (&callback,
				    ccErrInvalidCCache,
				    in_client_pipe,
				    in_reply_pipe,
				    (ccs_callback_owner_t) io_ccache,
				    ccs_ccache_invalidate_change_callback);

	    if (!err) {
		err = ccs_callback_array_insert (io_ccache->change_callbacks, callback,
						 ccs_callback_array_count (io_ccache->change_callbacks));
		if (!err) { callback = NULL; /* take ownership */ }

		cci_debug_printf ("%s blocking", __FUNCTION__);
		will_block = 1;
	    }

	    ccs_callback_release (callback);
	}
    }

    if (!err) {
	*out_will_block = will_block;
    }

    return cci_check_error (err);
}
Beispiel #3
0
WorkList::~WorkList() {
    // Delete any WorkItems in the queue:
    WorkItem*   item;
    cci_debug_printf("%s", __FUNCTION__);
    char        buf[2048];
    char*       pbuf        = (char*)buf;
    while (remove(&item)) {
        cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));
        delete item;
        }

    DeleteCriticalSection(&cs);
    }
Beispiel #4
0
cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state,
                                ccs_pipe_t       in_client_pipe)
{
    cc_int32 err = ccNoError;
    cc_uint32 found_lock = 0;

    if (!io_lock_state                  ) {
        err = cci_check_error (ccErrBadParam);
    }
    if (!ccs_pipe_valid (in_client_pipe)) {
        err = cci_check_error (ccErrBadParam);
    }

    if (!err) {
        cc_uint64 i;

        /* Remove all locks for this client.
         * There should only be one so warn if there are multiple */
        for (i = 0; !err && i < io_lock_state->first_pending_lock_index; i++) {
            ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
            cc_uint32 is_for_client = 0;

            err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &is_for_client);

            if (!err && is_for_client) {
                if (found_lock) {
                    cci_debug_printf ("WARNING %s: Found multiple locks for client.",
                                      __FUNCTION__);
                }

                found_lock = 1;

                cci_debug_printf ("%s: Removing lock %p at index %d.", __FUNCTION__, lock, (int) i);
                err = ccs_lock_status_remove_lock (io_lock_state, i);
                if (!err) {
                    i--;  /* We removed one so back up an index */
                }
            }
        }
    }

    if (!err && !found_lock) {
        err = cci_check_error (io_lock_state->no_lock_err);
    }

    if (!err) {
        err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state);
    }

    return cci_check_error (err);
}
cci_array_object_t cci_array_object_at_index (cci_array_t io_array,
                                              cc_uint64   in_position)
{
    if (io_array && in_position < io_array->count) {
        return io_array->objects[in_position];
    } else {
        if (!io_array) {
            cci_debug_printf ("%s() got NULL array", __FUNCTION__);
        } else {
            cci_debug_printf ("%s() got bad index %lld (count = %lld)", __FUNCTION__,
                              in_position, io_array->count);
        }
        return NULL;
    }
}
Beispiel #6
0
cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator)
{
    cc_int32 err = ccNoError;
    cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator;

    if (!io_ccache_iterator) { err = ccErrBadParam; }

    if (!err) {
        cc_uint32 initialized = 0;

        err = cci_identifier_is_initialized (ccache_iterator->identifier,
                                             &initialized);

        if (!err && initialized) {
            err =  cci_ipc_send (cci_ccache_iterator_release_msg_id,
                                 ccache_iterator->identifier,
                                 NULL,
                                 NULL);
            if (err) {
                cci_debug_printf ("%s: cci_ipc_send failed with error %d",
                                 __FUNCTION__, err);
                err = ccNoError;
            }
        }
    }

    if (!err) {
        free ((char *) ccache_iterator->functions);
        cci_identifier_release (ccache_iterator->identifier);
        free (ccache_iterator->saved_ccache_name);
        free (ccache_iterator);
    }

    return err;
}
Beispiel #7
0
HANDLE createThreadEvent(char* uuid, char* suffix) {
    LPSTR                   event_name  = NULL;
    HANDLE                  hEvent      = NULL;
    PSECURITY_ATTRIBUTES    psa         = 0;        // Everything having to do with
    SECURITY_ATTRIBUTES     sa          = { 0 };    // sa, psa, security is copied
    DWORD                   status      = 0;        // from the previous implementation.

    psa = isNT() ? &sa : 0;

    if (isNT()) {
        sa.nLength = sizeof(sa);
        status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);
        cci_check_error(status);
        }

    if (!status) {
        event_name = allocEventName(uuid, suffix);
        if (!event_name) status = cci_check_error(ccErrNoMem);
        }
#if 0
    cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name);
#endif
    if (!status) {
        hEvent = CreateEvent(psa, FALSE, FALSE, event_name);
        if (!hEvent)     status = cci_check_error(GetLastError());
        }

    if (!status) ResetEvent(hEvent);


    if (event_name) free(event_name);
    if (isNT())     free(sa.lpSecurityDescriptor);

    return hEvent;
    }
Beispiel #8
0
BOOL isNT() {
    OSVERSIONINFO osvi;
    DWORD   status              = 0;
    BOOL    bSupportedVersion   = FALSE;
    BOOL    bIsNT               = FALSE;

    memset(&osvi, 0, sizeof(osvi));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    status = !GetVersionEx(&osvi);       // Returns a boolean.  Invert to 0 is OK.

    if (!status) {
        switch(osvi.dwPlatformId) {
        case VER_PLATFORM_WIN32_WINDOWS:
            bIsNT = FALSE;
            bSupportedVersion = TRUE;
            break;
        case VER_PLATFORM_WIN32_NT:
            bIsNT = TRUE;
            bSupportedVersion = TRUE;
            break;
        case VER_PLATFORM_WIN32s:
        default:
            bIsNT = FALSE;
            break;
            }

        if (!bSupportedVersion) {
            cci_debug_printf("%s Running on an unsupported version of Windows", __FUNCTION__);
            status  = 1;
            }
        }

    return (!status && bIsNT && bSupportedVersion);
    }
void ccs_rpc_request(
    const long  rpcmsg,             /* Message type */
    const char  tspHandle[],        /* Client's tspdata* */
    const char* pszUUID,            /* Where client will listen for the reply */
    const long  lenRequest,         /* Length of buffer */
    const char  pbRequest[],        /* Data buffer */
    const long  serverStartTime,    /* Which server session we're talking to */
    long*       return_status ) {   /* Return code */

    cc_int32        status  = 0;
    k5_ipc_stream    stream;
    DWORD*          p       = (DWORD*)(tspHandle);
    WIN_PIPE*       pipe    = NULL;
#if 0
    cci_debug_printf("%s rpcmsg:%d; UUID:<%s> SST:<%s>", __FUNCTION__, rpcmsg, pszUUID, serverStartTime);
#endif
    status = (rpcmsg != CCMSG_REQUEST) && (rpcmsg != CCMSG_PING);

    if (!status) {
        status = k5_ipc_stream_new (&stream);  /* Create a stream for the request data */
        }

    if (!status) {                          /* Put the data into the stream */
        status = k5_ipc_stream_write (stream, pbRequest, lenRequest);
        }

    pipe = ccs_win_pipe_new(pszUUID, *p);
    worklist_add(rpcmsg, pipe, stream, serverStartTime);
    *return_status = status;
    }
// 'Authentication' is client setting a value in a file and the server
//   returning that value plus one.
CC_UINT32 ccs_authenticate(const CC_CHAR* name) {
    HANDLE      hMap    = 0;
    PDWORD      pvalue  = 0;
    CC_UINT32   result  = 0;
    DWORD       status  = 0;
#if 0
    cci_debug_printf("%s ( %s )", __FUNCTION__, name);
#endif
    hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, (LPSTR)name);
    status  = !hMap;

    if (!status) {
        pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
        status = !pvalue;
        }

    if (!status) {
        *pvalue += 1;
        result = *pvalue;
        }

    if (pvalue) {
        UnmapViewOfFile(pvalue);
        }

    if (hMap) CloseHandle(hMap);
    return result;
    }
struct ccs_win_pipe_t* ccs_win_pipe_new (const char* uuid, const HANDLE h) {

    cc_int32                err         = ccNoError;
    struct ccs_win_pipe_t*  out_pipe    = NULL;
    char*                   uuidCopy    = NULL;

    if (!err) {
        if (!uuid)      {err = cci_check_error(ccErrBadParam);}
        }

    if (!err) {
        uuidCopy = (char*)malloc(1+strlen(uuid));
        if (!uuidCopy)  {err = cci_check_error(ccErrBadParam);}
        strcpy(uuidCopy, uuid);
        }

    if (!err) {
        out_pipe = (struct ccs_win_pipe_t*)malloc(sizeof(struct ccs_win_pipe_t));
        if (!out_pipe)  {err = cci_check_error(ccErrBadParam);}
        out_pipe->uuid          = uuidCopy;
        out_pipe->clientHandle  = h;
        }
#if 0
    cci_debug_printf("0x%X = %s(%s, 0x%X)", out_pipe, __FUNCTION__, uuid, h);
#endif
    return out_pipe;
    }
cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier,
                                         cc_time_t        in_new_change_time)
{
    cc_int32 err = ccNoError;
    cc_int32 lock_err = err = k5_mutex_lock (&g_change_time_mutex);
    
    if (!err) {
        if (!in_identifier) { err = cci_check_error (err); }
    }
    
    if (!err) {
        if (g_change_time < in_new_change_time) {
            /* Only update if it increases the time.  May be a different server. */
            g_change_time = in_new_change_time;
            cci_debug_printf ("%s: setting change time to %d", 
                              __FUNCTION__, in_new_change_time);
        }
    }
    
    if (!err) {
        err = cci_context_change_time_update_identifier (in_identifier,
                                                         NULL, NULL, NULL);
    }
    
    if (!lock_err) {
        k5_mutex_unlock (&g_change_time_mutex);
    }

    return err;
}
Beispiel #13
0
static cc_int32 ccs_ccache_invalidate_change_callback (ccs_callback_owner_t io_ccache,
						       ccs_callback_t       in_callback)
{
    cc_int32 err = ccNoError;

    if (!io_ccache  ) { err = cci_check_error (ccErrBadParam); }
    if (!in_callback) { err = cci_check_error (ccErrBadParam); }

    if (!err) {
	/* Remove callback */
	ccs_ccache_t ccache = (ccs_ccache_t) io_ccache;
	cc_uint64 i;
        cc_uint64 count = ccs_callback_array_count (ccache->change_callbacks);

        for (i = 0; !err && i < count; i++) {
            ccs_callback_t callback = ccs_callback_array_object_at_index (ccache->change_callbacks, i);

	    if (callback == in_callback) {
		cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
		err = ccs_callback_array_remove (ccache->change_callbacks, i);
		break;
	    }
        }
    }

    return cci_check_error (err);
}
Beispiel #14
0
cc_int32 ccs_ccache_changed (ccs_ccache_t           io_ccache,
                             ccs_cache_collection_t io_cache_collection)
{
    cc_int32 err = ccNoError;
    k5_ipc_stream reply_data = NULL;

    if (!io_ccache          ) { err = cci_check_error (ccErrBadParam); }
    if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }

    if (!err) {
        cc_time_t now = time (NULL);

        if (io_ccache->last_changed_time < now) {
            io_ccache->last_changed_time = now;
        } else {
            io_ccache->last_changed_time++;
        }
    }

    if (!err) {
        err = ccs_cache_collection_changed (io_cache_collection);
    }

    if (!err) {
        err = krb5int_ipc_stream_new (&reply_data);
    }

    if (!err) {
	err = krb5int_ipc_stream_write_time (reply_data, io_ccache->last_changed_time);
    }

    if (!err) {
	/* Loop over callbacks sending messages to them */
	cc_uint64 i;
        cc_uint64 count = ccs_callback_array_count (io_ccache->change_callbacks);

        for (i = 0; !err && i < count; i++) {
            ccs_callback_t callback = ccs_callback_array_object_at_index (io_ccache->change_callbacks, i);

	    err = ccs_callback_reply_to_client (callback, reply_data);

	    if (!err) {
		cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
		err = ccs_callback_array_remove (io_ccache->change_callbacks, i);
		break;
	    }
        }
    }

    if (!err) {
        err = ccs_os_notify_ccache_changed (io_cache_collection,
                                            io_ccache->name);
    }

    krb5int_ipc_stream_release (reply_data);

    return cci_check_error (err);
}
void ccs_rpc_connect(
    const long  rpcmsg,             /* Message type */
    const char  tspHandle[],        /* Client's tspdata* */
    const char* pszUUID,            /* Data buffer */
    long*       return_status ) {   /* Return code */

    DWORD*      p       = (DWORD*)(tspHandle);
    WIN_PIPE*   pipe    = ccs_win_pipe_new(pszUUID, *p);
#if 0
    cci_debug_printf("%s; rpcmsg:%d; UUID: <%s>", __FUNCTION__, rpcmsg, pszUUID);
#endif
    worklist_add(   rpcmsg,
                    pipe,
                    NULL,               /* No payload with connect request */
                    (const time_t)0 );  /* No server session number with connect request */
    }
cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier)
{
    cc_int32 err = ccNoError;
    cc_int32 lock_err = err = k5_mutex_lock (&g_change_time_mutex);
    cc_uint32 server_ids_match = 0;
    cc_uint32 server_was_running = 0;
    cc_uint32 server_is_running = 0;
    
    if (!err) {
        if (!in_new_identifier) { err = cci_check_error (err); }
    }
    
    if (!err) {
        err = cci_context_change_time_update_identifier (in_new_identifier,
                                                         &server_ids_match,
                                                         &server_was_running,
                                                         &server_is_running);
    }
    
    if (!err && !server_ids_match) {        
        /* Increment the change time so callers re-read */
        g_change_time_offset++; 
        
        /* If the server died, absorb the offset */
        if (server_was_running && !server_is_running) {
            cc_time_t now = time (NULL);
            
            g_change_time += g_change_time_offset;
            g_change_time_offset = 0;
            
            /* Make sure the change time increases, ideally with the current time */
            g_change_time = (g_change_time < now) ? now : g_change_time;
        }
        
        cci_debug_printf ("%s noticed server changed ("
                          "server_was_running = %d; server_is_running = %d; "
                          "g_change_time = %d; g_change_time_offset = %d", 
                          __FUNCTION__, server_was_running, server_is_running, 
                          g_change_time, g_change_time_offset);            
    }
    
    if (!lock_err) {
        k5_mutex_unlock (&g_change_time_mutex);
    }
    
    return err;
}
Beispiel #17
0
cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback)
{
    cc_int32 err = ccNoError;
    
    if (!io_callback) { err = cci_check_error (ccErrBadParam); }
    
    if (!err) {
        io_callback->pending = 0; /* client is dead, don't try to talk to it */
	if (io_callback->owner_invalidate) {
	    err = io_callback->owner_invalidate (io_callback->owner, io_callback);
	} else {
	    cci_debug_printf ("WARNING %s() unable to notify callback owner!", 
			      __FUNCTION__);
	}
    }
    
    return cci_check_error (err);
}
Beispiel #18
0
HANDLE openThreadEvent(char* uuid, char* suffix) {
    LPSTR   event_name  = NULL;
    HANDLE  hEvent      = NULL;
    DWORD   status      = 0;

    event_name = allocEventName(uuid, suffix);
    if (!event_name) status = cci_check_error(ccErrNoMem);
#if 0
    cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name);
#endif
    if (!status) {
        hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
        if (!hEvent) status = cci_check_error(GetLastError());
        }

    if (event_name) free(event_name);

    return hEvent;
    }
cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator)
{
    cc_int32 err = ccNoError;
    
    if (!err && io_list_iterator) {
        cc_uint64 i = 0;
        
        if (ccs_list_find_iterator_index (io_list_iterator->list, 
                                          io_list_iterator->identifier, 
                                          &i) == ccNoError) {
            /* cci_array_remove will call ccs_list_iterator_object_release */
            err = cci_array_remove (io_list_iterator->list->iterators, i);
        } else {
            cci_debug_printf ("Warning: iterator not in iterator list!");
        }
    }
    
    return err;        
}
Beispiel #20
0
cc_int32 ccs_lock_state_add (ccs_lock_state_t  io_lock_state,
                             ccs_pipe_t        in_client_pipe,
                             ccs_pipe_t        in_reply_pipe,
                             cc_uint32         in_lock_type,
                             cc_uint32         in_block,
                             cc_uint32        *out_will_send_reply)
{
    cc_int32 err = ccNoError;
    cc_uint32 can_grant_lock_now = 0;

    if (!io_lock_state                  ) {
        err = cci_check_error (ccErrBadParam);
    }
    if (!ccs_pipe_valid (in_client_pipe)) {
        err = cci_check_error (ccErrBadParam);
    }
    if (!ccs_pipe_valid (in_reply_pipe) ) {
        err = cci_check_error (ccErrBadParam);
    }
    if (!out_will_send_reply            ) {
        err = cci_check_error (ccErrBadParam);
    }

    if (!err) {
        /* Sanity check: if there are any pending locks for this client
         * the client must have timed out waiting for our reply.  Remove any
         * existing pending locks for the client. */
        cc_uint64 i;

        for (i = io_lock_state->first_pending_lock_index; !err && i < ccs_lock_array_count (io_lock_state->locks); i++) {
            ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
            cc_uint32 has_pending_lock_for_client = 0;

            err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &has_pending_lock_for_client);

            if (!err && has_pending_lock_for_client) {
                cci_debug_printf ("WARNING %s: Removing unexpected pending lock %p at index %d.",
                                  __FUNCTION__, lock, (int) i);
                err = ccs_lock_status_remove_lock (io_lock_state, i);
                if (!err) {
                    i--;  /* We removed one so back up an index */
                }
            }
        }
    }

    if (!err) {
        err = ccs_lock_state_check_pending_lock (io_lock_state, in_client_pipe,
                in_lock_type, &can_grant_lock_now);
    }

    if (!err) {
        if (!can_grant_lock_now && (in_block == cc_lock_noblock)) {
            err = cci_check_error (io_lock_state->pending_lock_err);

        } else {
            cc_uint64 new_lock_index = 0;

            err = ccs_lock_status_add_pending_lock (io_lock_state,
                                                    in_client_pipe,
                                                    in_reply_pipe,
                                                    in_lock_type,
                                                    &new_lock_index);

            if (!err && can_grant_lock_now) {
                err = ccs_lock_status_grant_lock (io_lock_state, new_lock_index);

                if (!err && (in_lock_type == cc_lock_downgrade)) {
                    /* downgrades can allow us to grant other locks */
                    err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state);
                }
            }
        }
    }

    if (!err) {
        /* ccs_lock_state_add sends its replies via callback so caller shouldn't */
        *out_will_send_reply = 1;
    }

    return cci_check_error (err);
}
Beispiel #21
0
static cc_int32 ccs_lock_status_grant_lock (ccs_lock_state_t io_lock_state,
        cc_uint64        in_pending_lock_index)
{
    cc_int32 err = ccNoError;
    ccs_lock_t pending_lock = NULL;
    cc_uint32 type = 0;

    if (!io_lock_state) {
        err = cci_check_error (ccErrBadParam);
    }

    if (!err) {
        pending_lock = ccs_lock_array_object_at_index (io_lock_state->locks,
                       in_pending_lock_index);
        if (!pending_lock || in_pending_lock_index < io_lock_state->first_pending_lock_index) {
            err = cci_check_error (ccErrBadParam);
        }
    }

    if (!err) {
        err = ccs_lock_type (pending_lock, &type);
    }

    if (!err && (type == cc_lock_upgrade || type == cc_lock_downgrade)) {
        /* lock upgrades or downgrades.  Find the old lock and remove it. */
        ccs_pipe_t pending_client_pipe = CCS_PIPE_NULL;

        err = ccs_lock_client_pipe (pending_lock, &pending_client_pipe);

        if (!err) {
            cc_uint64 i;

            for (i = 0; !err && i < io_lock_state->first_pending_lock_index; i++) {
                ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i);
                cc_uint32 is_lock_for_client = 0;

                err = ccs_lock_is_for_client_pipe (lock, pending_client_pipe, &is_lock_for_client);

                if (!err && is_lock_for_client) {
                    cci_debug_printf ("%s: Removing old lock %p at index %d to replace with pending lock %p.",
                                      __FUNCTION__, lock, (int) i, pending_lock);
                    err = ccs_lock_status_remove_lock (io_lock_state, i);
                    if (!err) {
                        i--;
                        in_pending_lock_index--; /* We removed one so back up an index */
                    }
                    break;
                }
            }
        }
    }

    if (!err) {
        cc_uint64 new_lock_index = 0;

        err = ccs_lock_array_move (io_lock_state->locks,
                                   in_pending_lock_index,
                                   io_lock_state->first_pending_lock_index,
                                   &new_lock_index);
        if (!err) {
            io_lock_state->first_pending_lock_index++;
        }
    }

    if (!err) {
        err = ccs_lock_grant_lock (pending_lock);
    }

    return cci_check_error (err);
}
Beispiel #22
0
cc_int32 ccs_ccache_new (ccs_ccache_t      *out_ccache,
                         cc_uint32          in_creds_version,
                         const char        *in_name,
                         const char        *in_principal,
                         ccs_ccache_list_t  io_ccache_list)
{
    cc_int32 err = ccNoError;
    ccs_ccache_t ccache = NULL;

    if (!out_ccache  ) { err = cci_check_error (ccErrBadParam); }
    if (!in_name     ) { err = cci_check_error (ccErrBadParam); }
    if (!in_principal) { err = cci_check_error (ccErrBadParam); }

    if (!err) {
        ccache = malloc (sizeof (*ccache));
        if (ccache) {
            *ccache = ccs_ccache_initializer;
        } else {
            err = cci_check_error (ccErrNoMem);
        }
    }

    if (!err) {
        err = ccs_server_new_identifier (&ccache->identifier);
    }

    if (!err) {
        err = ccs_lock_state_new (&ccache->lock_state,
                                  ccErrInvalidCCache,
                                  ccErrCCacheLocked,
                                  ccErrCCacheUnlocked);
    }

    if (!err) {
        ccache->name = strdup (in_name);
        if (!ccache->name) { err = cci_check_error (ccErrNoMem); }
    }

    if (!err) {
        ccache->creds_version = in_creds_version;

        if (ccache->creds_version == cc_credentials_v5) {
            ccache->v5_principal = strdup (in_principal);
            if (!ccache->v5_principal) { err = cci_check_error (ccErrNoMem); }

        } else {
            err = cci_check_error (ccErrBadCredentialsVersion);
        }
    }

    if (!err) {
        err = ccs_credentials_list_new (&ccache->credentials);
    }

    if (!err) {
        err = ccs_callback_array_new (&ccache->change_callbacks);
    }

    if (!err) {
        cc_uint64 now = time (NULL);
        cc_uint64 count = 0;

        err = ccs_ccache_list_count (io_ccache_list, &count);

        if (!err) {
            /* first cache is default */
            ccache->last_default_time = (count == 0) ? now : 0;
	    cci_debug_printf ("%s ccache->last_default_time is %d.",
			     __FUNCTION__, ccache->last_default_time);
            ccache->last_changed_time = now;
        }
    }

    if (!err) {
        /* Add self to the list of ccaches */
        err = ccs_ccache_list_add (io_ccache_list, ccache);
    }

    if (!err) {
        *out_ccache = ccache;
        ccache = NULL;
    }

    ccs_ccache_release (ccache);

    return cci_check_error (err);
}