xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/obj_mgr.c (revision d8d810637042c2a73a269f125dee75e8ed1421d1)
1 /*
2  *		Common Public License Version 0.5
3  *
4  *		THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
5  *		THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
6  *		REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
7  *		RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
8  *
9  *		1. DEFINITIONS
10  *
11  *		"Contribution" means:
12  *		      a) in the case of the initial Contributor, the
13  *		      initial code and documentation distributed under
14  *		      this Agreement, and
15  *
16  *		      b) in the case of each subsequent Contributor:
17  *		      i) changes to the Program, and
18  *		      ii) additions to the Program;
19  *
20  *		      where such changes and/or additions to the Program
21  *		      originate from and are distributed by that
22  *		      particular Contributor. A Contribution 'originates'
23  *		      from a Contributor if it was added to the Program
24  *		      by such Contributor itself or anyone acting on such
25  *		      Contributor's behalf. Contributions do not include
26  *		      additions to the Program which: (i) are separate
27  *		      modules of software distributed in conjunction with
28  *		      the Program under their own license agreement, and
29  *		      (ii) are not derivative works of the Program.
30  *
31  *
32  *		"Contributor" means any person or entity that distributes
33  *		the Program.
34  *
35  *		"Licensed Patents " mean patent claims licensable by a
36  *		Contributor which are necessarily infringed by the use or
37  *		sale of its Contribution alone or when combined with the
38  *		Program.
39  *
40  *		"Program" means the Contributions distributed in
41  *		accordance with this Agreement.
42  *
43  *		"Recipient" means anyone who receives the Program under
44  *		this Agreement, including all Contributors.
45  *
46  *		2. GRANT OF RIGHTS
47  *
48  *		      a) Subject to the terms of this Agreement, each
49  *		      Contributor hereby grants Recipient a
50  *		      no - exclusive, worldwide, royalt - free copyright
51  *		      license to reproduce, prepare derivative works of,
52  *		      publicly display, publicly perform, distribute and
53  *		      sublicense the Contribution of such Contributor, if
54  *		      any, and such derivative works, in source code and
55  *		      object code form.
56  *
57  *		      b) Subject to the terms of this Agreement, each
58  *		      Contributor hereby grants Recipient a
59  *		      no - exclusive, worldwide, royalt - free patent
60  *		      license under Licensed Patents to make, use, sell,
61  *		      offer to sell, import and otherwise transfer the
62  *		      Contribution of such Contributor, if any, in source
63  *		      code and object code form. This patent license
64  *		      shall apply to the combination of the Contribution
65  *		      and the Program if, at the time the Contribution is
66  *		      added by the Contributor, such addition of the
67  *		      Contribution causes such combination to be covered
68  *		      by the Licensed Patents. The patent license shall
69  *		      not apply to any other combinations which include
70  *		      the Contribution. No hardware per se is licensed
71  *		      hereunder.
72  *
73  *		      c) Recipient understands that although each
74  *		      Contributor grants the licenses to its
75  *		      Contributions set forth herein, no assurances are
76  *		      provided by any Contributor that the Program does
77  *		      not infringe the patent or other intellectual
78  *		      property rights of any other entity. Each
79  *		      Contributor disclaims any liability to Recipient
80  *		      for claims brought by any other entity based on
81  *		      infringement of intellectual property rights or
82  *		      otherwise. As a condition to exercising the rights
83  *		      and licenses granted hereunder, each Recipient
84  *		      hereby assumes sole responsibility to secure any
85  *		      other intellectual property rights needed, if any.
86  *
87  *		      For example, if a third party patent license is
88  *		      required to allow Recipient to distribute the
89  *		      Program, it is Recipient's responsibility to
90  *		      acquire that license before distributing the
91  *		      Program.
92  *
93  *		      d) Each Contributor represents that to its
94  *		      knowledge it has sufficient copyright rights in its
95  *		      Contribution, if any, to grant the copyright
96  *		      license set forth in this Agreement.
97  *
98  *		3. REQUIREMENTS
99  *
100  *		A Contributor may choose to distribute the Program in
101  *		object code form under its own license agreement, provided
102  *		that:
103  *		      a) it complies with the terms and conditions of
104  *		      this Agreement; and
105  *
106  *		      b) its license agreement:
107  *		      i) effectively disclaims on behalf of all
108  *		      Contributors all warranties and conditions, express
109  *		      and implied, including warranties or conditions of
110  *		      title and no - infringement, and implied warranties
111  *		      or conditions of merchantability and fitness for a
112  *		      particular purpose;
113  *
114  *		      ii) effectively excludes on behalf of all
115  *		      Contributors all liability for damages, including
116  *		      direct, indirect, special, incidental and
117  *		      consequential damages, such as lost profits;
118  *
119  *		      iii) states that any provisions which differ from
120  *		      this Agreement are offered by that Contributor
121  *		      alone and not by any other party; and
122  *
123  *		      iv) states that source code for the Program is
124  *		      available from such Contributor, and informs
125  *		      licensees how to obtain it in a reasonable manner
126  *		      on or through a medium customarily used for
127  *		      software exchange.
128  *
129  *		When the Program is made available in source code form:
130  *		      a) it must be made available under this Agreement;
131  *		      and
132  *		      b) a copy of this Agreement must be included with
133  *		      each copy of the Program.
134  *
135  *		Contributors may not remove or alter any copyright notices
136  *		contained within the Program.
137  *
138  *		Each Contributor must identify itself as the originator of
139  *		its Contribution, if any, in a manner that reasonably
140  *		allows subsequent Recipients to identify the originator of
141  *		the Contribution.
142  *
143  *
144  *		4. COMMERCIAL DISTRIBUTION
145  *
146  *		Commercial distributors of software may accept certain
147  *		responsibilities with respect to end users, business
148  *		partners and the like. While this license is intended to
149  *		facilitate the commercial use of the Program, the
150  *		Contributor who includes the Program in a commercial
151  *		product offering should do so in a manner which does not
152  *		create potential liability for other Contributors.
153  *		Therefore, if a Contributor includes the Program in a
154  *		commercial product offering, such Contributor ("Commercial
155  *		Contributor") hereby agrees to defend and indemnify every
156  *		other Contributor ("Indemnified Contributor") against any
157  *		losses, damages and costs (collectively "Losses") arising
158  *		from claims, lawsuits and other legal actions brought by a
159  *		third party against the Indemnified Contributor to the
160  *		extent caused by the acts or omissions of such Commercial
161  *		Contributor in connection with its distribution of the
162  *		Program in a commercial product offering. The obligations
163  *		in this section do not apply to any claims or Losses
164  *		relating to any actual or alleged intellectual property
165  *		infringement. In order to qualify, an Indemnified
166  *		Contributor must: a) promptly notify the Commercial
167  *		Contributor in writing of such claim, and b) allow the
168  *		Commercial Contributor to control, and cooperate with the
169  *		Commercial Contributor in, the defense and any related
170  *		settlement negotiations. The Indemnified Contributor may
171  *		participate in any such claim at its own expense.
172  *
173  *
174  *		For example, a Contributor might include the Program in a
175  *		commercial product offering, Product X. That Contributor
176  *		is then a Commercial Contributor. If that Commercial
177  *		Contributor then makes performance claims, or offers
178  *		warranties related to Product X, those performance claims
179  *		and warranties are such Commercial Contributor's
180  *		responsibility alone. Under this section, the Commercial
181  *		Contributor would have to defend claims against the other
182  *		Contributors related to those performance claims and
183  *		warranties, and if a court requires any other Contributor
184  *		to pay any damages as a result, the Commercial Contributor
185  *		must pay those damages.
186  *
187  *
188  *		5. NO WARRANTY
189  *
190  *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
191  *		PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
192  *		WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
193  *		IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
194  *		CONDITIONS OF TITLE, NO - INFRINGEMENT, MERCHANTABILITY OR
195  *		FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
196  *		responsible for determining the appropriateness of using
197  *		and distributing the Program and assumes all risks
198  *		associated with its exercise of rights under this
199  *		Agreement, including but not limited to the risks and
200  *		costs of program errors, compliance with applicable laws,
201  *		damage to or loss of data, programs or equipment, and
202  *		unavailability or interruption of operations.
203  *
204  *		6. DISCLAIMER OF LIABILITY
205  *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
206  *		RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
207  *		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
208  *		OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
209  *		LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
210  *		LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
211  *		(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
212  *		OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
213  *		OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
214  *		POSSIBILITY OF SUCH DAMAGES.
215  *
216  *		7. GENERAL
217  *
218  *		If any provision of this Agreement is invalid or
219  *		unenforceable under applicable law, it shall not affect
220  *		the validity or enforceability of the remainder of the
221  *		terms of this Agreement, and without further action by the
222  *		parties hereto, such provision shall be reformed to the
223  *		minimum extent necessary to make such provision valid and
224  *		enforceable.
225  *
226  *
227  *		If Recipient institutes patent litigation against a
228  *		Contributor with respect to a patent applicable to
229  *		software (including a cros - claim or counterclaim in a
230  *		lawsuit), then any patent licenses granted by that
231  *		Contributor to such Recipient under this Agreement shall
232  *		terminate as of the date such litigation is filed. In
233  *		addition, If Recipient institutes patent litigation
234  *		against any entity (including a cros - claim or
235  *		counterclaim in a lawsuit) alleging that the Program
236  *		itself (excluding combinations of the Program with other
237  *		software or hardware) infringes such Recipient's
238  *		patent(s), then such Recipient's rights granted under
239  *		Section 2(b) shall terminate as of the date such
240  *		litigation is filed.
241  *
242  *		All Recipient's rights under this Agreement shall
243  *		terminate if it fails to comply with any of the material
244  *		terms or conditions of this Agreement and does not cure
245  *		such failure in a reasonable period of time after becoming
246  *		aware of such noncompliance. If all Recipient's rights
247  *		under this Agreement terminate, Recipient agrees to cease
248  *		use and distribution of the Program as soon as reasonably
249  *		practicable. However, Recipient's obligations under this
250  *		Agreement and any licenses granted by Recipient relating
251  *		to the Program shall continue and survive.
252  *
253  *		Everyone is permitted to copy and distribute copies of
254  *		this Agreement, but in order to avoid inconsistency the
255  *		Agreement is copyrighted and may only be modified in the
256  *		following manner. The Agreement Steward reserves the right
257  *		to publish new versions (including revisions) of this
258  *		Agreement from time to time. No one other than the
259  *		Agreement Steward has the right to modify this Agreement.
260  *
261  *		IBM is the initial Agreement Steward. IBM may assign the
262  *		responsibility to serve as the Agreement Steward to a
263  *		suitable separate entity. Each new version of the
264  *		Agreement will be given a distinguishing version number.
265  *		The Program (including Contributions) may always be
266  *		distributed subject to the version of the Agreement under
267  *		which it was received. In addition, after a new version of
268  *		the Agreement is published, Contributor may elect to
269  *		distribute the Program (including its Contributions) under
270  *		the new version. Except as expressly stated in Sections
271  *		2(a) and 2(b) above, Recipient receives no rights or
272  *		licenses to the intellectual property of any Contributor
273  *		under this Agreement, whether expressly, by implication,
274  *		estoppel or otherwise. All rights in the Program not
275  *		expressly granted under this Agreement are reserved.
276  *
277  *
278  *		This Agreement is governed by the laws of the State of New
279  *		York and the intellectual property laws of the United
280  *		States of America. No party to this Agreement will bring a
281  *		legal action under this Agreement more than one year after
282  *		the cause of action arose. Each party waives its rights to
283  *		a jury trial in any resulting litigation.
284  *
285  *
286  *
287  * (C) COPYRIGHT International Business Machines Corp. 2001, 2002
288  */
289 /*
290  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
291  * Use is subject to license terms.
292  */
293 
294 #include "tpmtok_int.h"
295 
296 pthread_rwlock_t obj_list_rw_mutex = PTHREAD_RWLOCK_INITIALIZER;
297 
298 static CK_RV
299 object_mgr_search_shm_for_obj(TOK_OBJ_ENTRY *,
300 	CK_ULONG, CK_ULONG, OBJECT *, CK_ULONG *);
301 static CK_RV object_mgr_update_from_shm(TSS_HCONTEXT);
302 static CK_RV object_mgr_check_shm(TSS_HCONTEXT, OBJECT *);
303 
304 static CK_RV
305 check_object_access(SESSION *sess, OBJECT *o)
306 {
307 	CK_BBOOL sess_obj, priv_obj;
308 	CK_RV rc = CKR_OK;
309 
310 	/*
311 	 * check whether session has permissions to create the object, etc
312 	 *
313 	 * Object	  R/O	    R/W    R/O   R/W    R/W
314 	 * Type		  Public   Public  User  User   SO
315 	 * -------------------------------------------------------------
316 	 * Public session  R/W	    R/W	   R/W   R/W    R/W
317 	 * Private session			 R/W    R/W
318 	 * Public token	   R/O	    R/W	   R/O   R/W    R/W
319 	 * Private token			 R/O    R/W
320 	 */
321 	sess_obj = object_is_session_object(o);
322 	priv_obj = object_is_private(o);
323 
324 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
325 		if (priv_obj) {
326 			rc = CKR_USER_NOT_LOGGED_IN;
327 			goto done;
328 		}
329 
330 		if (!sess_obj) {
331 			rc = CKR_SESSION_READ_ONLY;
332 			goto done;
333 		}
334 	}
335 
336 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
337 		if (! sess_obj) {
338 			rc = CKR_SESSION_READ_ONLY;
339 			goto done;
340 		}
341 	}
342 
343 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
344 		if (priv_obj) {
345 			rc = CKR_USER_NOT_LOGGED_IN;
346 			goto done;
347 		}
348 	}
349 
350 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
351 		if (priv_obj) {
352 			rc = CKR_USER_NOT_LOGGED_IN;
353 			goto done;
354 		}
355 	}
356 done:
357 	return (rc);
358 }
359 
360 CK_RV
361 object_mgr_add(SESSION	  * sess,
362 	CK_ATTRIBUTE	* pTemplate,
363 	CK_ULONG	   ulCount,
364 	CK_OBJECT_HANDLE * handle)
365 {
366 	OBJECT    * o = NULL;
367 	CK_BBOOL    priv_obj, sess_obj;
368 	CK_RV	rc;
369 
370 	if (! sess || ! pTemplate || ! handle) {
371 		return (CKR_FUNCTION_FAILED);
372 	}
373 
374 	rc = pthread_mutex_lock(&obj_list_mutex);
375 	if (rc != CKR_OK)
376 		return (CKR_FUNCTION_FAILED);
377 
378 	rc = object_create(pTemplate, ulCount, &o);
379 	if (rc != CKR_OK) {
380 		goto done;
381 	}
382 	rc = check_object_access(sess, o);
383 	if (rc != CKR_OK)
384 		goto done;
385 
386 	/*
387 	 * okay, object is created and the session permissions look okay.
388 	 * add the object to the appropriate list and assign an object handle
389 	 */
390 	sess_obj = object_is_session_object(o);
391 	priv_obj = object_is_private(o);
392 
393 	if (sess_obj) {
394 		o->session = sess;
395 		(void) memset(o->name, 0x00, sizeof (CK_BYTE) * 8);
396 
397 		sess_obj_list = dlist_add_as_first(sess_obj_list, o);
398 	} else {
399 		CK_BYTE current[8];
400 		CK_BYTE next[8];
401 
402 		rc = XProcLock(xproclock);
403 		if (rc != CKR_OK) {
404 			goto done;
405 		} else {
406 
407 			if (priv_obj) {
408 				if (global_shm->num_priv_tok_obj >=
409 				    MAX_TOK_OBJS) {
410 					rc = CKR_HOST_MEMORY;
411 					(void) XProcUnLock(xproclock);
412 					goto done;
413 				}
414 			} else {
415 				if (global_shm->num_publ_tok_obj >=
416 				    MAX_TOK_OBJS) {
417 					rc = CKR_HOST_MEMORY;
418 					(void) XProcUnLock(xproclock);
419 					goto done;
420 				}
421 			}
422 
423 			(void) memcpy(current,
424 			    &nv_token_data->next_token_object_name, 8);
425 
426 			o->session = NULL;
427 			(void) memcpy(&o->name, current, 8);
428 
429 			(void) compute_next_token_obj_name(current, next);
430 
431 			(void) memcpy(&nv_token_data->next_token_object_name,
432 			    next, 8);
433 
434 			rc = save_token_object(sess->hContext, o);
435 			if (rc != CKR_OK) {
436 				(void) XProcUnLock(xproclock);
437 				goto done;
438 			}
439 
440 			(void) object_mgr_add_to_shm(o);
441 			(void) XProcUnLock(xproclock);
442 
443 			(void) save_token_data(nv_token_data);
444 		}
445 
446 		if (priv_obj)
447 			priv_token_obj_list =
448 			    dlist_add_as_last(priv_token_obj_list, o);
449 		else
450 			publ_token_obj_list =
451 			    dlist_add_as_last(publ_token_obj_list, o);
452 	}
453 
454 	rc = object_mgr_add_to_map(sess, o, handle);
455 	if (rc != CKR_OK) {
456 		DL_NODE *node = NULL;
457 
458 		if (sess_obj) {
459 			node = dlist_find(sess_obj_list, o);
460 			if (node)
461 				sess_obj_list =
462 				    dlist_remove_node(sess_obj_list, node);
463 		} else {
464 			(void) delete_token_object(o);
465 
466 			if (priv_obj) {
467 				node = dlist_find(priv_token_obj_list, o);
468 				if (node)
469 					priv_token_obj_list =
470 					    dlist_remove_node(
471 					    priv_token_obj_list, node);
472 			} else {
473 				node = dlist_find(publ_token_obj_list, o);
474 				if (node)
475 					publ_token_obj_list =
476 					    dlist_remove_node(
477 					    publ_token_obj_list, node);
478 			}
479 
480 			rc = XProcLock(xproclock);
481 			if (rc != CKR_OK) {
482 				goto done;
483 			}
484 			(void) object_mgr_del_from_shm(o);
485 
486 			(void) XProcUnLock(xproclock);
487 		}
488 	}
489 
490 done:
491 	(void) pthread_mutex_unlock(&obj_list_mutex);
492 
493 	if ((rc != CKR_OK) && (o != NULL))
494 		(void) object_free(o);
495 
496 	return (rc);
497 }
498 
499 CK_RV
500 object_mgr_add_to_map(SESSION	  * sess,
501 	OBJECT	   * obj,
502 	CK_OBJECT_HANDLE * handle) {
503 	OBJECT_MAP  *map_node = NULL;
504 
505 	if (! sess || ! obj || ! handle) {
506 		return (CKR_FUNCTION_FAILED);
507 	}
508 
509 	map_node = (OBJECT_MAP *)malloc(sizeof (OBJECT_MAP));
510 	if (! map_node) {
511 		return (CKR_HOST_MEMORY);
512 	}
513 	map_node->handle   = next_object_handle++;
514 	map_node->session  = sess;
515 	map_node->ptr	= obj;
516 
517 	if (obj->session != NULL)
518 		map_node->is_session_obj = TRUE;
519 	else
520 		map_node->is_session_obj = FALSE;
521 
522 	// add the new map entry to the list
523 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
524 		return (CKR_FUNCTION_FAILED);
525 	}
526 	object_map = dlist_add_as_first(object_map, map_node);
527 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
528 
529 	*handle = map_node->handle;
530 	return (CKR_OK);
531 }
532 
533 // object_mgr_copy()
534 //
535 // algorithm:
536 //    1) find the old object
537 //    2) get the template from the old object
538 //    3) merge in the new object's template
539 //    4) perform class - specific sanity checks
540 //
541 CK_RV
542 object_mgr_copy(SESSION	  * sess,
543 	CK_ATTRIBUTE	* pTemplate,
544 	CK_ULONG	   ulCount,
545 	CK_OBJECT_HANDLE   old_handle,
546 	CK_OBJECT_HANDLE * new_handle)
547 {
548 	OBJECT	*old_obj = NULL;
549 	OBJECT	*new_obj = NULL;
550 	CK_BBOOL    priv_obj;
551 	CK_BBOOL    sess_obj;
552 	CK_RV	rc;
553 
554 	if (! sess || ! pTemplate || ! new_handle) {
555 		return (CKR_FUNCTION_FAILED);
556 	}
557 
558 	rc = pthread_mutex_lock(&obj_list_mutex);
559 	if (rc != CKR_OK)
560 		return (CKR_FUNCTION_FAILED);
561 
562 	rc = object_mgr_find_in_map1(sess->hContext, old_handle, &old_obj);
563 	if (rc != CKR_OK) {
564 		goto done;
565 	}
566 	rc = object_copy(pTemplate, ulCount, old_obj, &new_obj);
567 	if (rc != CKR_OK) {
568 		goto done;
569 	}
570 
571 	rc = check_object_access(sess, new_obj);
572 	if (rc != CKR_OK)
573 		goto done;
574 
575 	sess_obj = object_is_session_object(new_obj);
576 	priv_obj = object_is_private(new_obj);
577 
578 	if (sess_obj) {
579 		new_obj->session = sess;
580 		(void) memset(&new_obj->name, 0x00, sizeof (CK_BYTE) * 8);
581 
582 		sess_obj_list = dlist_add_as_first(sess_obj_list, new_obj);
583 	} else {
584 		CK_BYTE current[8];
585 		CK_BYTE next[8];
586 
587 		rc = XProcLock(xproclock);
588 		if (rc != CKR_OK) {
589 			goto done;
590 		} else {
591 			if (priv_obj) {
592 				if (global_shm->num_priv_tok_obj >=
593 				    MAX_TOK_OBJS) {
594 					(void) XProcUnLock(xproclock);
595 					rc = CKR_HOST_MEMORY;
596 					goto done;
597 				}
598 			} else {
599 				if (global_shm->num_publ_tok_obj >=
600 				    MAX_TOK_OBJS) {
601 					(void) XProcUnLock(xproclock);
602 					rc = CKR_HOST_MEMORY;
603 					goto done;
604 				}
605 			}
606 			(void) memcpy(current,
607 			    &nv_token_data->next_token_object_name, 8);
608 
609 			new_obj->session = NULL;
610 			(void) memcpy(&new_obj->name, current, 8);
611 
612 			(void) compute_next_token_obj_name(current, next);
613 			(void) memcpy(&nv_token_data->next_token_object_name,
614 			    next, 8);
615 
616 			rc = save_token_object(sess->hContext, new_obj);
617 			if (rc != CKR_OK) {
618 				(void) XProcUnLock(xproclock);
619 				goto done;
620 			}
621 
622 			(void) object_mgr_add_to_shm(new_obj);
623 
624 			(void) XProcUnLock(xproclock);
625 
626 			(void) save_token_data(nv_token_data);
627 		}
628 
629 		if (priv_obj)
630 			priv_token_obj_list = dlist_add_as_last(
631 			    priv_token_obj_list, new_obj);
632 		else
633 			publ_token_obj_list = dlist_add_as_last(
634 			    publ_token_obj_list, new_obj);
635 	}
636 
637 	rc = object_mgr_add_to_map(sess, new_obj, new_handle);
638 	if (rc != CKR_OK) {
639 		DL_NODE *node = NULL;
640 
641 		if (sess_obj) {
642 			node = dlist_find(sess_obj_list, new_obj);
643 			if (node)
644 				sess_obj_list = dlist_remove_node(
645 				    sess_obj_list, node);
646 		} else {
647 			(void) delete_token_object(new_obj);
648 
649 			if (priv_obj) {
650 				node = dlist_find(priv_token_obj_list, new_obj);
651 				if (node)
652 					priv_token_obj_list = dlist_remove_node(
653 					    priv_token_obj_list, node);
654 			} else {
655 				node = dlist_find(publ_token_obj_list, new_obj);
656 				if (node)
657 					publ_token_obj_list = dlist_remove_node(
658 					    publ_token_obj_list, node);
659 			}
660 
661 			rc = XProcLock(xproclock);
662 			if (rc != CKR_OK) {
663 				goto done;
664 			}
665 			(void) object_mgr_del_from_shm(new_obj);
666 
667 			(void) XProcUnLock(xproclock);
668 		}
669 	}
670 
671 done:
672 	(void) pthread_mutex_unlock(&obj_list_mutex);
673 
674 	if ((rc != CKR_OK) && (new_obj != NULL))
675 		(void) object_free(new_obj);
676 
677 	return (rc);
678 }
679 
680 //
681 // determines whether the session is allowed to create an object.  creates
682 // the object but doesn't add the object to any object lists or to the
683 // process' object map.
684 //
685 CK_RV
686 object_mgr_create_skel(SESSION	* sess,
687 	CK_ATTRIBUTE  * pTemplate,
688 	CK_ULONG	ulCount,
689 	CK_ULONG	mode,
690 	CK_ULONG	obj_type,
691 	CK_ULONG	sub_class,
692 	OBJECT	** obj)
693 {
694 	OBJECT	*o = NULL;
695 	CK_RV	rc;
696 	CK_BBOOL    priv_obj;
697 	CK_BBOOL    sess_obj;
698 
699 	if (! sess || ! obj) {
700 		return (CKR_FUNCTION_FAILED);
701 	}
702 	if (! pTemplate && (ulCount != 0)) {
703 		return (CKR_FUNCTION_FAILED);
704 	}
705 	rc = object_create_skel(pTemplate, ulCount,
706 	    mode, obj_type, sub_class, &o);
707 	if (rc != CKR_OK) {
708 		return (rc);
709 	}
710 	sess_obj = object_is_session_object(o);
711 	priv_obj = object_is_private(o);
712 
713 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
714 		if (priv_obj) {
715 			(void) object_free(o);
716 			return (CKR_USER_NOT_LOGGED_IN);
717 		}
718 
719 		if (! sess_obj) {
720 			(void) object_free(o);
721 			return (CKR_SESSION_READ_ONLY);
722 		}
723 	}
724 
725 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
726 		if (! sess_obj) {
727 			(void) object_free(o);
728 			return (CKR_SESSION_READ_ONLY);
729 		}
730 	}
731 
732 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
733 		if (priv_obj) {
734 			(void) object_free(o);
735 			return (CKR_USER_NOT_LOGGED_IN);
736 		}
737 	}
738 
739 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
740 		if (priv_obj) {
741 			(void) object_free(o);
742 			return (CKR_USER_NOT_LOGGED_IN);
743 		}
744 	}
745 
746 	*obj = o;
747 	return (CKR_OK);
748 }
749 
750 CK_RV
751 object_mgr_create_final(SESSION	   * sess,
752 	OBJECT	    * obj,
753 	CK_OBJECT_HANDLE  * handle)
754 {
755 	CK_BBOOL  sess_obj;
756 	CK_BBOOL  priv_obj;
757 	CK_RV	rc;
758 
759 	if (!sess || !obj || !handle)
760 		return (CKR_FUNCTION_FAILED);
761 
762 	rc = pthread_mutex_lock(&obj_list_mutex);
763 	if (rc != CKR_OK)
764 		return (CKR_FUNCTION_FAILED);
765 
766 	sess_obj = object_is_session_object(obj);
767 	priv_obj = object_is_private(obj);
768 
769 	if (sess_obj) {
770 		obj->session = sess;
771 		(void) memset(obj->name, 0x0, sizeof (CK_BYTE) * 8);
772 
773 		sess_obj_list = dlist_add_as_first(sess_obj_list, obj);
774 	} else {
775 		CK_BYTE current[8];
776 		CK_BYTE next[8];
777 
778 		rc = XProcLock(xproclock);
779 		if (rc != CKR_OK) {
780 			goto done;
781 		} else {
782 			if (priv_obj) {
783 				if (global_shm->num_priv_tok_obj >=
784 				    MAX_TOK_OBJS) {
785 					(void) XProcUnLock(xproclock);
786 					rc = CKR_HOST_MEMORY;
787 					goto done;
788 				}
789 			} else {
790 				if (global_shm->num_publ_tok_obj >=
791 				    MAX_TOK_OBJS) {
792 					(void) XProcUnLock(xproclock);
793 					rc = CKR_HOST_MEMORY;
794 					goto done;
795 				}
796 			}
797 			(void) memcpy(current,
798 			    &nv_token_data->next_token_object_name, 8);
799 
800 			obj->session = NULL;
801 			(void) memcpy(&obj->name, current, 8);
802 
803 			(void) compute_next_token_obj_name(current, next);
804 			(void) memcpy(&nv_token_data->next_token_object_name,
805 			    next, 8);
806 
807 			rc = save_token_object(sess->hContext, obj);
808 			if (rc != CKR_OK) {
809 				(void) XProcUnLock(xproclock);
810 				goto done;
811 			}
812 
813 			(void) object_mgr_add_to_shm(obj);
814 
815 			(void) XProcUnLock(xproclock);
816 
817 			(void) save_token_data(nv_token_data);
818 		}
819 
820 		if (priv_obj)
821 			priv_token_obj_list = dlist_add_as_last(
822 			    priv_token_obj_list, obj);
823 		else
824 			publ_token_obj_list = dlist_add_as_last(
825 			    publ_token_obj_list, obj);
826 	}
827 
828 	rc = object_mgr_add_to_map(sess, obj, handle);
829 	if (rc != CKR_OK) {
830 		DL_NODE *node = NULL;
831 
832 		if (sess_obj) {
833 			node = dlist_find(sess_obj_list, obj);
834 			if (node)
835 				sess_obj_list = dlist_remove_node(
836 				    sess_obj_list, node);
837 		} else {
838 			(void) delete_token_object(obj);
839 
840 			if (priv_obj) {
841 				node = dlist_find(priv_token_obj_list, obj);
842 				if (node)
843 					priv_token_obj_list = dlist_remove_node(
844 					    priv_token_obj_list, node);
845 			} else {
846 				node = dlist_find(publ_token_obj_list, obj);
847 				if (node)
848 					publ_token_obj_list = dlist_remove_node(
849 					    publ_token_obj_list, node);
850 			}
851 
852 			rc = XProcLock(xproclock);
853 			if (rc != CKR_OK) {
854 				goto done;
855 			}
856 			(void) object_mgr_del_from_shm(obj);
857 
858 			(void) XProcUnLock(xproclock);
859 		}
860 	}
861 
862 done:
863 	(void) pthread_mutex_unlock(&obj_list_mutex);
864 
865 	return (rc);
866 }
867 
868 CK_RV
869 object_mgr_destroy_object(SESSION	  * sess,
870 	CK_OBJECT_HANDLE   handle)
871 {
872 	OBJECT    * obj = NULL;
873 	CK_BBOOL    sess_obj;
874 	CK_BBOOL    priv_obj;
875 	CK_RV	rc;
876 
877 	if (! sess)
878 		return (CKR_FUNCTION_FAILED);
879 
880 	rc = pthread_mutex_lock(&obj_list_mutex);
881 	if (rc != CKR_OK)
882 		return (CKR_FUNCTION_FAILED);
883 
884 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
885 	if (rc != CKR_OK) {
886 		goto done;
887 	}
888 
889 	rc = check_object_access(sess, obj);
890 	if (rc != CKR_OK)
891 		goto done;
892 
893 	sess_obj = object_is_session_object(obj);
894 	priv_obj = object_is_private(obj);
895 
896 	if (sess_obj) {
897 		DL_NODE *node;
898 
899 		node = dlist_find(sess_obj_list, obj);
900 		if (node) {
901 			(void) object_mgr_remove_from_map(handle);
902 
903 			(void) object_free(obj);
904 			sess_obj_list = dlist_remove_node(
905 			    sess_obj_list, node);
906 
907 			rc = CKR_OK;
908 			goto done;
909 		}
910 	} else {
911 		DL_NODE *node = NULL;
912 
913 		(void) delete_token_object(obj);
914 
915 		if (priv_obj)
916 			node = dlist_find(priv_token_obj_list, obj);
917 		else
918 			node = dlist_find(publ_token_obj_list, obj);
919 
920 		if (node) {
921 			rc = XProcLock(xproclock);
922 			if (rc != CKR_OK) {
923 				goto done;
924 			}
925 			(void) object_mgr_del_from_shm(obj);
926 
927 			(void) XProcUnLock(xproclock);
928 
929 			(void) object_mgr_remove_from_map(handle);
930 
931 			(void) object_free(obj);
932 
933 			if (priv_obj)
934 				priv_token_obj_list = dlist_remove_node(
935 				    priv_token_obj_list, node);
936 			else
937 				publ_token_obj_list = dlist_remove_node(
938 				    publ_token_obj_list, node);
939 
940 			rc = CKR_OK;
941 			goto done;
942 		}
943 	}
944 
945 	rc = CKR_FUNCTION_FAILED;
946 done:
947 	(void) pthread_mutex_unlock(&obj_list_mutex);
948 
949 	return (rc);
950 }
951 
952 CK_RV
953 object_mgr_destroy_token_objects(TSS_HCONTEXT hContext)
954 {
955 	CK_BBOOL locked2 = FALSE;
956 	CK_RV rc;
957 
958 	rc = pthread_mutex_lock(&obj_list_mutex);
959 	if (rc != CKR_OK)
960 		return (CKR_FUNCTION_FAILED);
961 
962 	while (publ_token_obj_list) {
963 		OBJECT *obj = (OBJECT *)publ_token_obj_list->data;
964 
965 		CK_OBJECT_HANDLE handle;
966 
967 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
968 		if (rc == CKR_OK) {
969 			(void) object_mgr_remove_from_map(handle);
970 		}
971 		(void) delete_token_object(obj);
972 		(void) object_free(obj);
973 
974 		publ_token_obj_list = dlist_remove_node(
975 		    publ_token_obj_list, publ_token_obj_list);
976 	}
977 
978 	while (priv_token_obj_list) {
979 		OBJECT *obj = (OBJECT *)priv_token_obj_list->data;
980 
981 		CK_OBJECT_HANDLE handle;
982 
983 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
984 		if (rc == CKR_OK) {
985 			(void) object_mgr_remove_from_map(handle);
986 		}
987 		(void) delete_token_object(obj);
988 		(void) object_free(obj);
989 
990 		priv_token_obj_list = dlist_remove_node(
991 		    priv_token_obj_list, priv_token_obj_list);
992 	}
993 
994 	// now we want to purge the token object list in shared memory
995 	//
996 	rc = XProcLock(xproclock);
997 	if (rc == CKR_OK) {
998 		locked2 = TRUE;
999 
1000 		global_shm->num_priv_tok_obj = 0;
1001 		global_shm->num_publ_tok_obj = 0;
1002 
1003 		(void) memset(&global_shm->publ_tok_objs, 0x0,
1004 		    MAX_TOK_OBJS * sizeof (TOK_OBJ_ENTRY));
1005 		(void) memset(&global_shm->priv_tok_objs, 0x0,
1006 		    MAX_TOK_OBJS * sizeof (TOK_OBJ_ENTRY));
1007 	}
1008 
1009 done:
1010 	(void) pthread_mutex_unlock(&obj_list_mutex);
1011 
1012 	if (locked2 == TRUE) (void) XProcUnLock(xproclock);
1013 
1014 	return (rc);
1015 }
1016 
1017 //
1018 // Locates the specified object in the map
1019 // without going and checking for cache update
1020 //
1021 CK_RV
1022 object_mgr_find_in_map_nocache(CK_OBJECT_HANDLE    handle,
1023 	OBJECT	   ** ptr) {
1024 	DL_NODE   * node = NULL;
1025 	OBJECT    * obj  = NULL;
1026 
1027 	if (! ptr) {
1028 		return (CKR_FUNCTION_FAILED);
1029 	}
1030 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1031 		return (CKR_FUNCTION_FAILED);
1032 	}
1033 	node = object_map;
1034 	while (node) {
1035 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1036 
1037 		if (map->handle == handle) {
1038 			obj = map->ptr;
1039 			break;
1040 		}
1041 
1042 		node = node->next;
1043 	}
1044 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1045 
1046 	if (obj == NULL || node == NULL) {
1047 		return (CKR_OBJECT_HANDLE_INVALID);
1048 	}
1049 
1050 	if (object_is_session_object(obj) == TRUE) {
1051 		 *ptr = obj;
1052 		return (CKR_OK);
1053 	}
1054 
1055 	*ptr = obj;
1056 	return (CKR_OK);
1057 }
1058 
1059 CK_RV
1060 object_mgr_find_in_map1(
1061 	TSS_HCONTEXT hContext,
1062 	CK_OBJECT_HANDLE    handle,
1063 	OBJECT	   ** ptr)
1064 {
1065 	DL_NODE   * node = NULL;
1066 	OBJECT    * obj  = NULL;
1067 
1068 	if (! ptr) {
1069 		return (CKR_FUNCTION_FAILED);
1070 	}
1071 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1072 		return (CKR_FUNCTION_FAILED);
1073 	}
1074 	node = object_map;
1075 	while (node) {
1076 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1077 
1078 		if (map->handle == handle) {
1079 			obj = map->ptr;
1080 			break;
1081 		}
1082 
1083 		node = node->next;
1084 	}
1085 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1086 
1087 	if (obj == NULL || node == NULL) {
1088 		return (CKR_OBJECT_HANDLE_INVALID);
1089 	}
1090 
1091 	if (object_is_session_object(obj) == TRUE) {
1092 		*ptr = obj;
1093 		return (CKR_OK);
1094 	}
1095 
1096 	(void) object_mgr_check_shm(hContext, obj);
1097 
1098 	*ptr = obj;
1099 	return (CKR_OK);
1100 }
1101 
1102 CK_RV
1103 object_mgr_find_in_map2(
1104 	TSS_HCONTEXT hContext,
1105 	OBJECT	   * obj,
1106 	CK_OBJECT_HANDLE * handle)
1107 {
1108 	DL_NODE	   * node = NULL;
1109 	CK_OBJECT_HANDLE    h    = (CK_OBJECT_HANDLE)NULL;
1110 
1111 	if (! obj || ! handle) {
1112 		return (CKR_FUNCTION_FAILED);
1113 	}
1114 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1115 		return (CKR_FUNCTION_FAILED);
1116 	}
1117 	node = object_map;
1118 	while (node) {
1119 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1120 
1121 		if (map->ptr == obj) {
1122 			h = map->handle;
1123 			break;
1124 		}
1125 
1126 		node = node->next;
1127 	}
1128 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1129 
1130 	if (node == NULL) {
1131 		return (CKR_OBJECT_HANDLE_INVALID);
1132 	}
1133 
1134 	if (object_is_session_object(obj) == TRUE) {
1135 		*handle = h;
1136 		return (CKR_OK);
1137 	}
1138 
1139 	(void) object_mgr_check_shm(hContext, obj);
1140 
1141 	*handle = h;
1142 	return (CKR_OK);
1143 }
1144 
1145 CK_RV
1146 object_mgr_find_init(SESSION	* sess,
1147 	CK_ATTRIBUTE * pTemplate,
1148 	CK_ULONG	ulCount)
1149 {
1150 	if (! sess) {
1151 		return (CKR_FUNCTION_FAILED);
1152 	}
1153 	if (sess->find_active != FALSE) {
1154 		return (CKR_OPERATION_ACTIVE);
1155 	}
1156 	// initialize the found object list.  if it doesn't exist, allocate
1157 	// a list big enough for 10 handles.  we'll reallocate if we need more
1158 	//
1159 	if (sess->find_list != NULL) {
1160 		(void) memset(sess->find_list, 0x0,
1161 		    sess->find_len * sizeof (CK_OBJECT_HANDLE));
1162 	} else {
1163 		sess->find_list = (CK_OBJECT_HANDLE *)malloc(
1164 		    10 * sizeof (CK_OBJECT_HANDLE));
1165 		if (! sess->find_list) {
1166 			return (CKR_HOST_MEMORY);
1167 		} else {
1168 			(void) memset(sess->find_list, 0x0,
1169 			    10 * sizeof (CK_OBJECT_HANDLE));
1170 			sess->find_len = 10;
1171 		}
1172 	}
1173 
1174 	sess->find_count = 0;
1175 	sess->find_idx   = 0;
1176 
1177 	//  --- need to grab the object lock here
1178 	if (pthread_mutex_lock(&obj_list_mutex))
1179 		return (CKR_FUNCTION_FAILED);
1180 
1181 	(void) object_mgr_update_from_shm(sess->hContext);
1182 
1183 	// which objects can be return (ed:
1184 	//
1185 	//   Public Session:   public session objects, public token objects
1186 	//   User Session:	all session objects,    all token objects
1187 	//   SO session:	public session objects, public token objects
1188 	//
1189 	switch (sess->session_info.state) {
1190 		case CKS_RO_PUBLIC_SESSION:
1191 		case CKS_RW_PUBLIC_SESSION:
1192 		case CKS_RW_SO_FUNCTIONS:
1193 		(void) object_mgr_find_build_list(sess, pTemplate,
1194 		    ulCount, publ_token_obj_list, TRUE);
1195 		(void) object_mgr_find_build_list(sess, pTemplate,
1196 		    ulCount, sess_obj_list,	TRUE);
1197 		break;
1198 
1199 		case CKS_RO_USER_FUNCTIONS:
1200 		case CKS_RW_USER_FUNCTIONS:
1201 		(void) object_mgr_find_build_list(sess, pTemplate,
1202 		    ulCount, priv_token_obj_list, FALSE);
1203 		(void) object_mgr_find_build_list(sess, pTemplate,
1204 		    ulCount, publ_token_obj_list, FALSE);
1205 		(void) object_mgr_find_build_list(sess, pTemplate,
1206 		    ulCount, sess_obj_list,  FALSE);
1207 		break;
1208 	}
1209 	(void) pthread_mutex_unlock(&obj_list_mutex);
1210 
1211 	sess->find_active = TRUE;
1212 
1213 	return (CKR_OK);
1214 }
1215 
1216 CK_RV
1217 object_mgr_find_build_list(SESSION	* sess,
1218 	CK_ATTRIBUTE * pTemplate,
1219 	CK_ULONG	ulCount,
1220 	DL_NODE	* obj_list,
1221 	CK_BBOOL	public_only)
1222 {
1223 	OBJECT	   * obj  = NULL;
1224 	DL_NODE	  * node = NULL;
1225 	CK_OBJECT_HANDLE   handle;
1226 	CK_BBOOL	   is_priv;
1227 	CK_BBOOL	   match;
1228 	CK_BBOOL	   hw_feature = FALSE;
1229 	CK_BBOOL	   hidden_object = FALSE;
1230 	CK_RV		rc;
1231 	CK_ATTRIBUTE	* attr;
1232 	unsigned int		i;
1233 
1234 	if (! sess) {
1235 		return (CKR_FUNCTION_FAILED);
1236 	}
1237 	if (! obj_list)
1238 		return (CKR_OK);
1239 	// PKCS#11 v2.11 (pg. 79): "When searching using C_FindObjectsInit
1240 	// and C_FindObjects, hardware feature objects are not returned
1241 	// unless the CKA_CLASS attribute in the template has the value
1242 	// CKO_HW_FEATURE." So, we check for CKO_HW_FEATURE and if its set,
1243 	// we'll find these objects below. - KEY
1244 	for (i = 0; i < ulCount; i++) {
1245 		if (pTemplate[i].type == CKA_CLASS) {
1246 			if (*(CK_ULONG *)pTemplate[i].pValue ==
1247 			    CKO_HW_FEATURE) {
1248 				hw_feature = TRUE;
1249 				break;
1250 			}
1251 		}
1252 
1253 		if (pTemplate[i].type == CKA_HIDDEN) {
1254 			if (*(CK_BBOOL *)pTemplate[i].pValue == TRUE) {
1255 				hidden_object = TRUE;
1256 				break;
1257 			}
1258 		}
1259 	}
1260 
1261 	node = obj_list;
1262 	while (node) {
1263 		match   = FALSE;
1264 		obj	= (OBJECT *)node->data;
1265 		is_priv = object_is_private(obj);
1266 
1267 
1268 		if ((is_priv == FALSE) || (public_only == FALSE)) {
1269 			if (pTemplate == NULL || ulCount == 0)
1270 				match = TRUE;
1271 			else
1272 				match = template_compare(pTemplate,
1273 				    ulCount, obj->template);
1274 		}
1275 
1276 		if (match) {
1277 			rc = object_mgr_find_in_map2(sess->hContext, obj,
1278 			    &handle);
1279 			if (rc != CKR_OK) {
1280 				rc = object_mgr_add_to_map(sess, obj, &handle);
1281 				if (rc != CKR_OK) {
1282 					return (CKR_FUNCTION_FAILED);
1283 				}
1284 			}
1285 			if (rc == CKR_OK) {
1286 				if ((hw_feature == FALSE) &&
1287 				    (template_attribute_find(obj->template,
1288 				    CKA_CLASS, &attr) == TRUE)) {
1289 					if (*(CK_OBJECT_CLASS *)attr->pValue ==
1290 					    CKO_HW_FEATURE)
1291 						goto next_loop;
1292 				}
1293 
1294 				if ((hidden_object == FALSE) &&
1295 				    (template_attribute_find(obj->template,
1296 				    CKA_HIDDEN, &attr) == TRUE)) {
1297 					if (*(CK_BBOOL *)attr->pValue == TRUE)
1298 						goto next_loop;
1299 				}
1300 
1301 				sess->find_list[ sess->find_count ] = handle;
1302 				sess->find_count++;
1303 
1304 				if (sess->find_count >= sess->find_len) {
1305 					sess->find_len += 15;
1306 					sess->find_list =
1307 					    (CK_OBJECT_HANDLE *)realloc(
1308 					    sess->find_list, sess->find_len *
1309 					    sizeof (CK_OBJECT_HANDLE));
1310 					if (! sess->find_list) {
1311 						return (CKR_HOST_MEMORY);
1312 					}
1313 				}
1314 			}
1315 		}
1316 		next_loop:
1317 		node = node->next;
1318 	}
1319 
1320 	return (CKR_OK);
1321 }
1322 
1323 CK_RV
1324 object_mgr_find_final(SESSION *sess)
1325 {
1326 	if (! sess) {
1327 		return (CKR_FUNCTION_FAILED);
1328 	}
1329 	if (sess->find_active == FALSE) {
1330 		return (CKR_OPERATION_NOT_INITIALIZED);
1331 	}
1332 	free(sess->find_list);
1333 	sess->find_list   = NULL;
1334 	sess->find_count  = 0;
1335 	sess->find_idx    = 0;
1336 	sess->find_active = FALSE;
1337 
1338 	return (CKR_OK);
1339 }
1340 
1341 CK_RV
1342 object_mgr_get_attribute_values(SESSION	   * sess,
1343 	CK_OBJECT_HANDLE    handle,
1344 	CK_ATTRIBUTE	* pTemplate,
1345 	CK_ULONG	    ulCount)
1346 {
1347 	OBJECT   * obj;
1348 	CK_BBOOL   priv_obj;
1349 	CK_RV	rc;
1350 
1351 	if (! pTemplate) {
1352 		return (CKR_FUNCTION_FAILED);
1353 	}
1354 	rc = pthread_mutex_lock(&obj_list_mutex);
1355 	if (rc != CKR_OK)
1356 		return (CKR_FUNCTION_FAILED);
1357 
1358 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
1359 	if (rc != CKR_OK) {
1360 		goto done;
1361 	}
1362 	priv_obj = object_is_private(obj);
1363 
1364 	if (priv_obj == TRUE) {
1365 		if (sess->session_info.state == CKS_RO_PUBLIC_SESSION ||
1366 		    sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
1367 			rc = CKR_USER_NOT_LOGGED_IN;
1368 			goto done;
1369 		}
1370 	}
1371 
1372 	rc = object_get_attribute_values(obj, pTemplate, ulCount);
1373 done:
1374 	(void) pthread_mutex_unlock(&obj_list_mutex);
1375 
1376 	return (rc);
1377 }
1378 
1379 CK_RV
1380 object_mgr_get_object_size(
1381 	TSS_HCONTEXT hContext,
1382 	CK_OBJECT_HANDLE   handle,
1383 	CK_ULONG	 * size)
1384 {
1385 	OBJECT    * obj;
1386 	CK_RV	rc;
1387 
1388 	rc = pthread_mutex_lock(&obj_list_mutex);
1389 	if (rc != CKR_OK)
1390 		return (CKR_FUNCTION_FAILED);
1391 
1392 	rc = object_mgr_find_in_map1(hContext, handle, &obj);
1393 	if (rc != CKR_OK) {
1394 		rc = CKR_OBJECT_HANDLE_INVALID;
1395 		goto done;
1396 	}
1397 
1398 	*size = object_get_size(obj);
1399 
1400 done:
1401 	(void) pthread_mutex_unlock(&obj_list_mutex);
1402 	return (rc);
1403 }
1404 
1405 
1406 // object_mgr_invalidate_handle1()
1407 //
1408 // Returns:  TRUE  if successfully removes the node
1409 //	   FALSE if cannot remove the node (not found, etc)
1410 //
1411 CK_BBOOL
1412 object_mgr_invalidate_handle1(CK_OBJECT_HANDLE handle)
1413 {
1414 	DL_NODE *node = NULL;
1415 
1416 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1417 		return (CKR_FUNCTION_FAILED);
1418 	}
1419 	node = object_map;
1420 
1421 	while (node) {
1422 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1423 
1424 		if (map->handle == handle) {
1425 			object_map = dlist_remove_node(object_map, node);
1426 			free(map);
1427 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1428 			return (TRUE);
1429 		}
1430 
1431 		node = node->next;
1432 	}
1433 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1434 	return (FALSE);
1435 }
1436 
1437 // object_mgr_invalidate_handle2()
1438 //
1439 // Returns:  TRUE  if successfully removes the node
1440 //	   FALSE if cannot remove the node (not found, etc)
1441 //
1442 CK_BBOOL
1443 object_mgr_invalidate_handle2(OBJECT *obj)
1444 {
1445 	DL_NODE *node = NULL;
1446 
1447 	if (! obj)
1448 		return (FALSE);
1449 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1450 		return (CKR_FUNCTION_FAILED);
1451 	}
1452 	node = object_map;
1453 
1454 	while (node) {
1455 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1456 		if (map->ptr == obj) {
1457 			object_map = dlist_remove_node(object_map, node);
1458 			free(map);
1459 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1460 			return (TRUE);
1461 		}
1462 		node = node->next;
1463 	}
1464 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1465 
1466 	return (FALSE);
1467 }
1468 
1469 // object_mgr_purge_session_objects()
1470 //
1471 // Args:    SESSION *
1472 //	  SESS_OBJ_TYPE:  can be ALL, PRIVATE or PUBLIC
1473 //
1474 // Remove all session objects owned by the specified session satisfying
1475 // the 'type' requirements
1476 //
1477 CK_BBOOL
1478 object_mgr_purge_session_objects(SESSION	* sess,
1479 	SESS_OBJ_TYPE   type)
1480 {
1481 	DL_NODE   *node = NULL;
1482 	DL_NODE   *next = NULL;
1483 	OBJECT    *obj = NULL;
1484 	CK_BBOOL   del;
1485 	CK_RV	rc;
1486 
1487 	if (!sess)
1488 		return (FALSE);
1489 
1490 	rc = pthread_mutex_lock(&obj_list_mutex);
1491 	if (rc != CKR_OK)
1492 		return (FALSE);
1493 
1494 	node = sess_obj_list;
1495 
1496 	while (node) {
1497 		obj = (OBJECT *)node->data;
1498 		del = FALSE;
1499 
1500 		if (obj->session == sess) {
1501 			if (type == PRIVATE) {
1502 				if (object_is_private(obj))
1503 					del = TRUE;
1504 			} else if (type == PUBLIC) {
1505 				if (object_is_public(obj))
1506 					del = TRUE;
1507 			} else if (type == ALL)
1508 				del = TRUE;
1509 		}
1510 		if (del == TRUE) {
1511 
1512 			CK_OBJECT_HANDLE handle;
1513 			CK_RV	    rc;
1514 
1515 			rc = object_mgr_find_in_map2(sess->hContext, obj,
1516 			    &handle);
1517 			if (rc == CKR_OK) {
1518 				(void) object_mgr_invalidate_handle1(handle);
1519 				(void) object_free(obj);
1520 			}
1521 
1522 			next = node->next;
1523 			sess_obj_list = dlist_remove_node(sess_obj_list, node);
1524 			node = next;
1525 		}
1526 		else
1527 			node = node->next;
1528 	}
1529 
1530 	(void) pthread_mutex_unlock(&obj_list_mutex);
1531 
1532 	return (TRUE);
1533 }
1534 
1535 //
1536 // This routine cleans up the list of token objects.  in general, we don't
1537 // need to do this but when tracing memory leaks, it's best that we free
1538 // everything that we've allocated.
1539 //
1540 CK_BBOOL
1541 object_mgr_purge_token_objects(TSS_HCONTEXT hContext)
1542 {
1543 	DL_NODE   *node = NULL;
1544 	DL_NODE   *next = NULL;
1545 	OBJECT    *obj = NULL;
1546 	CK_RV	rc;
1547 
1548 	rc = pthread_mutex_lock(&obj_list_mutex);
1549 	if (rc != CKR_OK)
1550 		return (FALSE);
1551 
1552 	node = publ_token_obj_list;
1553 	while (publ_token_obj_list) {
1554 		CK_OBJECT_HANDLE handle;
1555 		CK_RV	    rc;
1556 
1557 		obj = (OBJECT *)node->data;
1558 
1559 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1560 		if (rc == CKR_OK) {
1561 			(void) object_mgr_invalidate_handle1(handle);
1562 		}
1563 		(void) object_free(obj);
1564 
1565 		next = node->next;
1566 		publ_token_obj_list = dlist_remove_node(
1567 		    publ_token_obj_list, node);
1568 		node = next;
1569 	}
1570 
1571 	node = priv_token_obj_list;
1572 
1573 	while (priv_token_obj_list) {
1574 		CK_OBJECT_HANDLE handle;
1575 		CK_RV	    rc;
1576 
1577 		obj = (OBJECT *)node->data;
1578 
1579 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1580 		if (rc == CKR_OK)
1581 			(void) object_mgr_invalidate_handle1(handle);
1582 		(void) object_free(obj);
1583 
1584 		next = node->next;
1585 		priv_token_obj_list = dlist_remove_node(
1586 		    priv_token_obj_list, node);
1587 		node = next;
1588 	}
1589 
1590 	(void) pthread_mutex_unlock(&obj_list_mutex);
1591 
1592 	return (TRUE);
1593 }
1594 
1595 CK_BBOOL
1596 object_mgr_purge_private_token_objects(TSS_HCONTEXT hContext) {
1597 	OBJECT   * obj  = NULL;
1598 	DL_NODE  * node = NULL;
1599 	DL_NODE  * next = NULL;
1600 	CK_RV	rc;
1601 
1602 	rc = pthread_mutex_lock(&obj_list_mutex);
1603 	if (rc != CKR_OK)
1604 		return (FALSE);
1605 
1606 	node = priv_token_obj_list;
1607 	while (priv_token_obj_list) {
1608 		CK_OBJECT_HANDLE handle;
1609 		CK_RV	    rc;
1610 
1611 		obj = (OBJECT *)node->data;
1612 
1613 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1614 		if (rc == CKR_OK) {
1615 			(void) object_mgr_invalidate_handle1(handle);
1616 		}
1617 
1618 		(void) object_free(obj);
1619 
1620 		next = node->next;
1621 		priv_token_obj_list = dlist_remove_node(
1622 		    priv_token_obj_list, node);
1623 		node = next;
1624 	}
1625 
1626 	(void) pthread_mutex_unlock(&obj_list_mutex);
1627 
1628 	return (TRUE);
1629 }
1630 
1631 CK_RV
1632 object_mgr_remove_from_map(CK_OBJECT_HANDLE  handle)
1633 {
1634 	DL_NODE  *node = NULL;
1635 
1636 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1637 		return (CKR_FUNCTION_FAILED);
1638 	}
1639 	node = object_map;
1640 	while (node) {
1641 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1642 		if (map->handle == handle) {
1643 			object_map = dlist_remove_node(object_map, node);
1644 			free(map);
1645 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1646 			return (CKR_OK);
1647 		}
1648 		node = node->next;
1649 	}
1650 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1651 
1652 	return (CKR_FUNCTION_FAILED);
1653 }
1654 
1655 CK_RV
1656 object_mgr_restore_obj(CK_BYTE *data, OBJECT *oldObj)
1657 {
1658 	OBJECT    * obj  = NULL;
1659 	CK_BBOOL    priv;
1660 	CK_RV	rc;
1661 
1662 	if (! data) {
1663 		return (CKR_FUNCTION_FAILED);
1664 	}
1665 	if (oldObj != NULL) {
1666 		obj = oldObj;
1667 		rc = object_restore(data, &obj, TRUE);
1668 	} else {
1669 		rc = object_restore(data, &obj, FALSE);
1670 		if (rc == CKR_OK) {
1671 			priv = object_is_private(obj);
1672 
1673 			if (priv)
1674 				priv_token_obj_list = dlist_add_as_last(
1675 				    priv_token_obj_list, obj);
1676 			else
1677 				publ_token_obj_list = dlist_add_as_last(
1678 				    publ_token_obj_list, obj);
1679 
1680 			(void) XProcLock(xproclock);
1681 
1682 			if (priv) {
1683 				if (global_shm->priv_loaded == FALSE) {
1684 					if (global_shm->num_priv_tok_obj <
1685 					    MAX_TOK_OBJS)
1686 						(void) object_mgr_add_to_shm(
1687 						    obj);
1688 					else
1689 						rc = CKR_HOST_MEMORY;
1690 				}
1691 			} else {
1692 				if (global_shm->publ_loaded == FALSE) {
1693 					if (global_shm->num_publ_tok_obj <
1694 					    MAX_TOK_OBJS)
1695 						(void) object_mgr_add_to_shm(
1696 						    obj);
1697 					else
1698 						rc = CKR_HOST_MEMORY;
1699 				}
1700 			}
1701 
1702 			(void) XProcUnLock(xproclock);
1703 		}
1704 	}
1705 
1706 	// make the callers have to have the mutes
1707 	// to many grab it now.
1708 	return (rc);
1709 }
1710 
1711 CK_RV
1712 object_mgr_set_attribute_values(SESSION	   * sess,
1713 	CK_OBJECT_HANDLE    handle,
1714 	CK_ATTRIBUTE	* pTemplate,
1715 	CK_ULONG	    ulCount)
1716 {
1717 	OBJECT    * obj;
1718 	CK_BBOOL    sess_obj, priv_obj;
1719 	CK_BBOOL    modifiable;
1720 	CK_RV	rc;
1721 
1722 	if (! pTemplate) {
1723 		return (CKR_FUNCTION_FAILED);
1724 	}
1725 	rc = pthread_mutex_lock(&obj_list_mutex);
1726 	if (rc != CKR_OK)
1727 		return (CKR_FUNCTION_FAILED);
1728 
1729 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
1730 	if (rc != CKR_OK) {
1731 		(void) pthread_mutex_unlock(&obj_list_mutex);
1732 		return (CKR_OBJECT_HANDLE_INVALID);
1733 	}
1734 	(void) pthread_mutex_unlock(&obj_list_mutex);
1735 
1736 	modifiable = object_is_modifiable(obj);
1737 	sess_obj   = object_is_session_object(obj);
1738 	priv_obj   = object_is_private(obj);
1739 
1740 	if (! modifiable) {
1741 		return (CKR_ATTRIBUTE_READ_ONLY);
1742 	}
1743 	rc = check_object_access(sess, obj);
1744 	if (rc != CKR_OK)
1745 		return (rc);
1746 
1747 	rc = object_set_attribute_values(obj, pTemplate, ulCount);
1748 	if (rc != CKR_OK) {
1749 		return (rc);
1750 	}
1751 	if (! sess_obj) {
1752 		TOK_OBJ_ENTRY  *entry = NULL;
1753 		CK_ULONG	index;
1754 
1755 		obj->count_lo++;
1756 		if (obj->count_lo == 0)
1757 			obj->count_hi++;
1758 
1759 		rc = save_token_object(sess->hContext, obj);
1760 		if (rc != CKR_OK)
1761 			return (rc);
1762 
1763 		rc = XProcLock(xproclock);
1764 		if (rc != CKR_OK) {
1765 			return (rc);
1766 		}
1767 		if (priv_obj) {
1768 			rc = object_mgr_search_shm_for_obj(
1769 			    global_shm->priv_tok_objs,
1770 			    0, global_shm->num_priv_tok_obj - 1,
1771 			    obj, &index);
1772 
1773 			if (rc != CKR_OK) {
1774 				(void) XProcUnLock(xproclock);
1775 				return (rc);
1776 			}
1777 
1778 			entry = &global_shm->priv_tok_objs[index];
1779 		} else {
1780 			rc = object_mgr_search_shm_for_obj(
1781 			    global_shm->publ_tok_objs,
1782 			    0, global_shm->num_publ_tok_obj - 1,
1783 			    obj, &index);
1784 			if (rc != CKR_OK) {
1785 				(void) XProcUnLock(xproclock);
1786 				return (rc);
1787 			}
1788 
1789 			entry = &global_shm->publ_tok_objs[index];
1790 		}
1791 
1792 		entry->count_lo = obj->count_lo;
1793 		entry->count_hi = obj->count_hi;
1794 
1795 		(void) XProcUnLock(xproclock);
1796 	}
1797 
1798 	return (rc);
1799 }
1800 
1801 CK_RV
1802 object_mgr_add_to_shm(OBJECT *obj)
1803 {
1804 	TOK_OBJ_ENTRY  * entry  = NULL;
1805 	CK_BBOOL	 priv;
1806 
1807 	priv = object_is_private(obj);
1808 
1809 	if (priv)
1810 		entry = &global_shm->priv_tok_objs[
1811 		    global_shm->num_priv_tok_obj];
1812 	else
1813 		entry = &global_shm->publ_tok_objs[
1814 		    global_shm->num_publ_tok_obj];
1815 
1816 	entry->deleted  = FALSE;
1817 	entry->count_lo = 0;
1818 	entry->count_hi = 0;
1819 	(void) memcpy(entry->name, obj->name, 8);
1820 
1821 	if (priv) {
1822 		global_shm->num_priv_tok_obj++;
1823 	} else {
1824 		global_shm->num_publ_tok_obj++;
1825 	}
1826 
1827 	return (CKR_OK);
1828 }
1829 
1830 CK_RV
1831 object_mgr_del_from_shm(OBJECT *obj)
1832 {
1833 	CK_ULONG	  index, count;
1834 	CK_BBOOL	  priv;
1835 	CK_RV		rc;
1836 
1837 	priv = object_is_private(obj);
1838 
1839 	if (priv) {
1840 		rc = object_mgr_search_shm_for_obj(global_shm->priv_tok_objs,
1841 		    0, global_shm->num_priv_tok_obj - 1, obj, &index);
1842 		if (rc != CKR_OK) {
1843 			return (CKR_FUNCTION_FAILED);
1844 		}
1845 
1846 		global_shm->num_priv_tok_obj--;
1847 		if (index > global_shm->num_priv_tok_obj) {
1848 			count = index - global_shm->num_priv_tok_obj;
1849 		} else {
1850 			count = global_shm->num_priv_tok_obj - index;
1851 		}
1852 
1853 		if (count > 0) {
1854 			(void) memcpy((char *)&global_shm->priv_tok_objs[index],
1855 			    (char *)&global_shm->priv_tok_objs[index + 1],
1856 			    sizeof (TOK_OBJ_ENTRY) * count);
1857 
1858 			(void) memset((char *)&global_shm->priv_tok_objs[
1859 			    global_shm->num_priv_tok_obj + 1], 0,
1860 			    sizeof (TOK_OBJ_ENTRY));
1861 		} else {
1862 			(void) memset((char *)&global_shm->priv_tok_objs[
1863 			    global_shm->num_priv_tok_obj], 0,
1864 			    sizeof (TOK_OBJ_ENTRY));
1865 		}
1866 	} else {
1867 		rc = object_mgr_search_shm_for_obj(global_shm->publ_tok_objs,
1868 		    0, global_shm->num_publ_tok_obj - 1, obj, &index);
1869 		if (rc != CKR_OK) {
1870 			return (CKR_FUNCTION_FAILED);
1871 		}
1872 		global_shm->num_publ_tok_obj--;
1873 
1874 		if (index > global_shm->num_publ_tok_obj) {
1875 			count = index - global_shm->num_publ_tok_obj;
1876 		} else {
1877 			count = global_shm->num_publ_tok_obj - index;
1878 		}
1879 
1880 		if (count > 0) {
1881 			(void) memcpy((char *)&global_shm->publ_tok_objs[index],
1882 			    (char *)&global_shm->publ_tok_objs[index + 1],
1883 			    sizeof (TOK_OBJ_ENTRY) * count);
1884 			(void) memset((char *)&global_shm->publ_tok_objs[
1885 			    global_shm->num_publ_tok_obj + 1], 0,
1886 			    sizeof (TOK_OBJ_ENTRY));
1887 		} else {
1888 			(void) memset((char *)&global_shm->publ_tok_objs[
1889 			    global_shm->num_publ_tok_obj], 0,
1890 			    sizeof (TOK_OBJ_ENTRY));
1891 		}
1892 	}
1893 
1894 	return (CKR_OK);
1895 }
1896 
1897 static CK_RV
1898 object_mgr_check_shm(TSS_HCONTEXT hContext, OBJECT *obj)
1899 {
1900 	TOK_OBJ_ENTRY   * entry = NULL;
1901 	CK_BBOOL	  priv;
1902 	CK_ULONG	  index;
1903 	CK_RV		rc;
1904 
1905 
1906 	priv = object_is_private(obj);
1907 
1908 	if (priv) {
1909 		rc = object_mgr_search_shm_for_obj(
1910 		    global_shm->priv_tok_objs,
1911 		    0, global_shm->num_priv_tok_obj - 1, obj, &index);
1912 		if (rc != CKR_OK) {
1913 			return (CKR_FUNCTION_FAILED);
1914 		}
1915 		entry = &global_shm->priv_tok_objs[index];
1916 	} else {
1917 		rc = object_mgr_search_shm_for_obj(
1918 		    global_shm->publ_tok_objs,
1919 		    0, global_shm->num_publ_tok_obj - 1, obj, &index);
1920 		if (rc != CKR_OK) {
1921 			return (CKR_FUNCTION_FAILED);
1922 		}
1923 		entry = &global_shm->publ_tok_objs[index];
1924 	}
1925 
1926 	if ((obj->count_hi == entry->count_hi) &&
1927 	    (obj->count_lo == entry->count_lo))
1928 		return (CKR_OK);
1929 	rc = reload_token_object(hContext, obj);
1930 	return (rc);
1931 }
1932 
1933 /*ARGSUSED*/
1934 static CK_RV
1935 object_mgr_search_shm_for_obj(
1936 	TOK_OBJ_ENTRY *obj_list,
1937 	CK_ULONG lo,
1938 	CK_ULONG hi,
1939 	OBJECT *obj,
1940 	CK_ULONG *index)
1941 {
1942 	CK_ULONG idx;
1943 	if (obj->index == 0) {
1944 		for (idx = lo; idx <= hi; idx++) {
1945 			if (memcmp(obj->name, obj_list[idx].name, 8) == 0) {
1946 				*index = idx;
1947 				obj->index = idx;
1948 				return (CKR_OK);
1949 			}
1950 		}
1951 	} else {
1952 		if (memcmp(obj->name, obj_list[obj->index].name, 8) == 0) {
1953 			*index = obj->index;
1954 			return (CKR_OK);
1955 		} else {
1956 			for (idx = lo; idx <= hi; idx++) {
1957 				if (memcmp(obj->name,
1958 				    obj_list[idx].name, 8) == 0) {
1959 					*index = idx;
1960 					obj->index = idx;
1961 					return (CKR_OK);
1962 				}
1963 			}
1964 		}
1965 	}
1966 	return (CKR_FUNCTION_FAILED);
1967 }
1968 
1969 static CK_RV
1970 object_mgr_update_publ_tok_obj_from_shm(TSS_HCONTEXT hContext)
1971 {
1972 	DL_NODE	   * node = NULL;
1973 	DL_NODE	   * next = NULL;
1974 	TOK_OBJ_ENTRY	* te   = NULL;
1975 	OBJECT	    * obj  = NULL;
1976 	CK_OBJECT_HANDLE    handle;
1977 	CK_ULONG	    index;
1978 	int		 val;
1979 	CK_RV		rc;
1980 
1981 	node  = publ_token_obj_list;
1982 	index = 0;
1983 
1984 	while ((node != NULL) && (index < global_shm->num_publ_tok_obj)) {
1985 		te = &global_shm->publ_tok_objs[index];
1986 		obj = (OBJECT *)node->data;
1987 
1988 		val = memcmp(obj->name, te->name, 8);
1989 
1990 		// 3 cases:
1991 		//    1) object in local list but not in the global list,
1992 		//	need to remove from local list
1993 		//    2) object in both lists, need to compare counters
1994 		//	and update as needed
1995 		//    3) object in global list but not in the local list,
1996 		//	need to add the object here.
1997 		//
1998 		if (val < 0) {
1999 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2000 			if (rc == CKR_OK) {
2001 				(void) object_mgr_remove_from_map(handle);
2002 			}
2003 			(void) object_free(obj);
2004 
2005 			next = node->next;
2006 			publ_token_obj_list = dlist_remove_node(
2007 			    publ_token_obj_list, node);
2008 
2009 		} else if (val == 0) {
2010 			if ((te->count_hi != obj->count_hi) ||
2011 			    (te->count_lo != obj->count_lo)) {
2012 				(void) reload_token_object(hContext, obj);
2013 				obj->count_hi = te->count_hi;
2014 				obj->count_lo = te->count_lo;
2015 			}
2016 
2017 			next = node->next;
2018 			index++;
2019 		} else {
2020 			DL_NODE  *new_node = NULL;
2021 			OBJECT   *new_obj  = NULL;
2022 
2023 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2024 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2025 
2026 			(void) memcpy(new_obj->name, te->name, 8);
2027 			(void) reload_token_object(hContext, new_obj);
2028 
2029 			new_node = (DL_NODE *)malloc(sizeof (DL_NODE));
2030 			new_node->data = new_obj;
2031 
2032 			new_node->next = node->next;
2033 			node->next	= new_node;
2034 			new_node->prev = node;
2035 
2036 			next = new_node->next;
2037 			index++;
2038 		}
2039 
2040 		node = next;
2041 	}
2042 
2043 	if ((node == NULL) && (index < global_shm->num_publ_tok_obj)) {
2044 		OBJECT   *new_obj  = NULL;
2045 		unsigned int i;
2046 
2047 		for (i = index; i < global_shm->num_publ_tok_obj; i++) {
2048 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2049 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2050 
2051 			te = &global_shm->publ_tok_objs[index];
2052 
2053 			(void) memcpy(new_obj->name, te->name, 8);
2054 			(void) reload_token_object(hContext, new_obj);
2055 
2056 			publ_token_obj_list = dlist_add_as_last(
2057 			    publ_token_obj_list, new_obj);
2058 		}
2059 	} else if ((node != NULL) && (index >= global_shm->num_publ_tok_obj)) {
2060 		while (node) {
2061 			obj = (OBJECT *)node->data;
2062 
2063 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2064 			if (rc == CKR_OK) {
2065 				(void) object_mgr_remove_from_map(handle);
2066 			}
2067 			(void) object_free(obj);
2068 
2069 			next = node->next;
2070 			publ_token_obj_list = dlist_remove_node(
2071 			    publ_token_obj_list, node);
2072 
2073 			node = next;
2074 		}
2075 	}
2076 
2077 	return (CKR_OK);
2078 }
2079 
2080 static CK_RV
2081 object_mgr_update_priv_tok_obj_from_shm(TSS_HCONTEXT hContext)
2082 {
2083 	DL_NODE	   * node = NULL;
2084 	DL_NODE	   * next = NULL;
2085 	TOK_OBJ_ENTRY	* te   = NULL;
2086 	OBJECT	    * obj  = NULL;
2087 	CK_OBJECT_HANDLE    handle;
2088 	CK_ULONG	    index;
2089 	int		 val;
2090 	CK_RV		rc;
2091 
2092 	node  = priv_token_obj_list;
2093 	index = 0;
2094 
2095 	if (! (global_login_state == CKS_RW_USER_FUNCTIONS ||
2096 	    global_login_state == CKS_RO_USER_FUNCTIONS)) {
2097 		return (CKR_OK);
2098 	}
2099 
2100 	while ((node != NULL) && (index < global_shm->num_priv_tok_obj)) {
2101 		te = &global_shm->priv_tok_objs[index];
2102 		obj = (OBJECT *)node->data;
2103 
2104 		val = memcmp(obj->name, te->name, 8);
2105 
2106 		if (val < 0) {
2107 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2108 			if (rc == CKR_OK) {
2109 				(void) object_mgr_remove_from_map(handle);
2110 			}
2111 			(void) object_free(obj);
2112 
2113 			next = node->next;
2114 			priv_token_obj_list = dlist_remove_node(
2115 			    priv_token_obj_list, node);
2116 
2117 		} else if (val == 0) {
2118 			if ((te->count_hi != obj->count_hi) ||
2119 			    (te->count_lo != obj->count_lo)) {
2120 				(void) reload_token_object(hContext, obj);
2121 				obj->count_hi = te->count_hi;
2122 				obj->count_lo = te->count_lo;
2123 			}
2124 
2125 			next = node->next;
2126 			index++;
2127 		} else {
2128 			DL_NODE  *new_node = NULL;
2129 			OBJECT   *new_obj  = NULL;
2130 
2131 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2132 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2133 
2134 			(void) memcpy(new_obj->name, te->name, 8);
2135 			(void) reload_token_object(hContext, new_obj);
2136 
2137 			new_node = (DL_NODE *)malloc(sizeof (DL_NODE));
2138 			new_node->data = new_obj;
2139 
2140 			new_node->next = node->next;
2141 			node->next	= new_node;
2142 			new_node->prev = node;
2143 
2144 			next = new_node->next;
2145 			index++;
2146 		}
2147 
2148 		node = next;
2149 	}
2150 
2151 	if ((node == NULL) && (index < global_shm->num_priv_tok_obj)) {
2152 		OBJECT   *new_obj  = NULL;
2153 		unsigned int i;
2154 
2155 		for (i = index; i < global_shm->num_priv_tok_obj; i++) {
2156 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2157 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2158 
2159 			te = &global_shm->priv_tok_objs[index];
2160 
2161 			(void) memcpy(new_obj->name, te->name, 8);
2162 			(void) reload_token_object(hContext, new_obj);
2163 
2164 			priv_token_obj_list = dlist_add_as_last(
2165 			    priv_token_obj_list, new_obj);
2166 		}
2167 	} else if ((node != NULL) && (index >= global_shm->num_priv_tok_obj)) {
2168 		while (node) {
2169 			obj = (OBJECT *)node->data;
2170 
2171 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2172 			if (rc == CKR_OK) {
2173 				(void) object_mgr_remove_from_map(handle);
2174 			}
2175 			(void) object_free(obj);
2176 
2177 			next = node->next;
2178 			priv_token_obj_list = dlist_remove_node(
2179 			    priv_token_obj_list, node);
2180 
2181 			node = next;
2182 		}
2183 	}
2184 
2185 	return (CKR_OK);
2186 }
2187 
2188 static CK_RV
2189 object_mgr_update_from_shm(TSS_HCONTEXT hContext)
2190 {
2191 	(void) object_mgr_update_publ_tok_obj_from_shm(hContext);
2192 	(void) object_mgr_update_priv_tok_obj_from_shm(hContext);
2193 
2194 	return (CKR_OK);
2195 }
2196 
2197 /*ARGSUSED*/
2198 CK_BBOOL
2199 object_mgr_purge_map(
2200 	SESSION	*sess,
2201 	SESS_OBJ_TYPE type)
2202 {
2203 	DL_NODE *node = NULL;
2204 	DL_NODE *next = NULL;
2205 
2206 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
2207 		return (CKR_FUNCTION_FAILED);
2208 	}
2209 	node = object_map;
2210 	while (node) {
2211 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
2212 		OBJECT	*obj = (OBJECT *)map->ptr;
2213 		next = node->next;
2214 		if (type == PRIVATE) {
2215 			if (object_is_private(obj)) {
2216 				object_map = dlist_remove_node(
2217 				    object_map, node);
2218 				free(map);
2219 			}
2220 		}
2221 		if (type == PUBLIC) {
2222 			if (object_is_public(obj)) {
2223 				object_map = dlist_remove_node(
2224 				    object_map, node);
2225 				free(map);
2226 			}
2227 		}
2228 		node = next;
2229 	}
2230 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
2231 
2232 	return (TRUE);
2233 }
2234