kernelSessionUtil.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <pthread.h>
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <security/cryptoki.h>
#include "kernelGlobal.h"
#include "kernelSession.h"
#include "kernelSlot.h"
/*
* Delete all the sessions. First, obtain the slot lock.
* Then start to delete one session at a time. The boolean wrapper_only
* argument indicates that whether the caller only wants to clean up the
* session wrappers and the object wrappers in the library.
* - When this function is called by C_CloseAllSessions or indirectly by
* C_Finalize, wrapper_only is FALSE.
* - When this function is called by cleanup_child, wrapper_only is TRUE.
*/
{
/* Acquire the slot lock */
/*
* Delete all the sessions in the slot's session list.
* The routine kernel_delete_session() updates the linked list.
* So, we do not need to maintain the list here.
*/
while (session_p) {
/*
* Delete a session by calling kernel_delete_session()
* with a session pointer and a boolean arguments.
* Boolean value TRUE is used to indicate that the
* caller holds the slot lock.
*/
/* Record the very first error code */
}
}
/* Release the slot lock */
return (rv);
}
/*
* Create a new session struct, and add it to the slot's session list.
*
* This function is called by C_OpenSession(), which hold the slot lock.
*/
{
int r;
/* Allocate a new session struct */
return (CKR_HOST_MEMORY);
}
new_sp->ses_refcnt = 0;
new_sp->ses_close_sync = 0;
/* Initialize the lock for the newly created session */
return (CKR_CANT_LOCK);
}
break;
}
if (r < 0) {
} else {
}
return (rv);
}
/* Insert the new session in front of the slot's session list */
} else {
}
/* Type casting the address of a session struct to a session handle */
return (CKR_OK);
}
/*
* Delete a session:
* - Remove the session from the slot's session list.
* - Release all the objects created by the session.
*
* The boolean argument slot_lock_held is used to indicate that whether
* the caller of this function holds the slot lock or not.
* - When called by kernel_delete_all_sessions(), which is called by
* C_Finalize() or C_CloseAllSessions() -- slot_lock_held = TRUE.
* - When called by C_CloseSession() -- slot_lock_held = FALSE.
*/
{
int r;
/*
* Check to see if the caller holds the lock on the global
* session list. If not, we need to acquire that lock in
* order to proceed.
*/
if (!slot_lock_held) {
/* Acquire the slot lock */
}
/*
* Remove the session from the slot's session list first.
*/
/* Session is the first one in the list */
} else {
/* Session is the only one in the list */
}
} else {
/* Session is not the first one in the list */
/* Session is in the middle of the list */
} else {
/* Session is the last one in the list */
}
}
if (!slot_lock_held) {
/*
* If the slot lock is obtained by
* this function, then release that lock after
* removing the session from session linked list.
* We want the releasing of the objects of the
* session, and freeing of the session itself to
* be done without holding the slot's session list
* lock.
*/
}
/* Acquire the individual session lock */
/*
* Make sure another thread hasn't freed the session.
*/
return (CKR_OK);
}
/*
* The deletion of a session must be blocked when the session reference
* count is not zero. This means that if the thread that is attempting
* to close the session must wait until the prior operations on this
* session are finished.
*/
while (session_p->ses_refcnt != 0) {
/*
* We set the SESSION_REFCNT_WAITING flag before we put
* this closing thread in a wait state, so other non-closing
* operation thread will wake it up only when
* the session reference count becomes zero and this flag
* is set.
*/
}
/* Mark session as no longer valid. */
session_p->magic_marker = 0;
/*
* Remove all the objects created in this session.
*/
/* In case application did not call Final */
/* Reset SESSION_IS_CLOSING flag. */
/* Destroy the individual session lock */
if (!wrapper_only) {
&close_session)) < 0) {
break;
}
if (r < 0) {
} else {
}
}
/*
* Ignore ioctl return codes. If the library tells the kernel to
* close a session and the kernel says "I don't know what session
* you're talking about", there's not much that can be done. All
* sessions in the kernel will be closed when the application exits
*/
/*
* If there is no more session remained in this slot, reset the slot's
* session state to CKU_PUBLIC. Also, clean up all the token object
* wrappers in the library for this slot.
*/
/* Acquire the slot lock if lock is not held */
if (!slot_lock_held) {
}
/* Reset the session auth. state. */
/* Clean up token object wrappers. */
while (objp) {
}
/* Release the slot lock if lock is not held */
if (!slot_lock_held) {
}
}
return (rv);
}
/*
* This function is used to type cast a session handle to a pointer to
* the session struct. Also, it does the following things:
* 1) Check to see if the session struct is tagged with a session
* magic number. This is to detect when an application passes
* a bogus session pointer.
* 2) Acquire the locks on the designated session and the slot which owns
* this session.
* 3) Check to see if the session is in the closing state that another
* thread is performing.
* 4) Increment the session reference count by one. This is to prevent
* this session from being closed by other thread.
* 5) Release the locks on the designated session and on the slot.
*/
{
return (CKR_SESSION_HANDLE_INVALID);
} else {
} else {
/* Increment session ref count. */
sp->ses_refcnt++;
}
}
return (rv);
}