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 CK_RV
305 object_mgr_add(SESSION	  * sess,
306 	CK_ATTRIBUTE	* pTemplate,
307 	CK_ULONG	   ulCount,
308 	CK_OBJECT_HANDLE * handle)
309 {
310 	OBJECT    * o = NULL;
311 	CK_BBOOL    priv_obj, sess_obj;
312 	CK_RV	rc;
313 
314 	if (! sess || ! pTemplate || ! handle) {
315 		return (CKR_FUNCTION_FAILED);
316 	}
317 
318 	rc = pthread_mutex_lock(&obj_list_mutex);
319 	if (rc != CKR_OK)
320 		return (CKR_FUNCTION_FAILED);
321 
322 	rc = object_create(pTemplate, ulCount, &o);
323 	if (rc != CKR_OK) {
324 		goto done;
325 	}
326 	// check whether session has permissions to create the object, etc
327 	//
328 	// Object		  R/O	R/W	R/O	R/W    R/W
329 	// Type		   Public   Public    User    User   SO
330 	// -------------------------------------------------------------
331 	// Public session	  R/W	R/W	R/W	R/W    R/W
332 	// Private session			   R/W	R/W
333 	// Public token	    R/O	R/W	R/O	R/W    R/W
334 	// Private token				R/O	R/W
335 	//
336 	sess_obj = object_is_session_object(o);
337 	priv_obj = object_is_private(o);
338 
339 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
340 		if (priv_obj) {
341 			rc = CKR_USER_NOT_LOGGED_IN;
342 			goto done;
343 		}
344 
345 		if (! sess_obj) {
346 			rc = CKR_SESSION_READ_ONLY;
347 			goto done;
348 		}
349 	}
350 
351 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
352 		if (! sess_obj) {
353 			rc = CKR_SESSION_READ_ONLY;
354 			goto done;
355 		}
356 	}
357 
358 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
359 		if (priv_obj) {
360 			rc = CKR_USER_NOT_LOGGED_IN;
361 			goto done;
362 		}
363 	}
364 
365 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
366 		if (priv_obj) {
367 			rc = CKR_USER_NOT_LOGGED_IN;
368 			goto done;
369 		}
370 	}
371 
372 	// okay, object is created and the session permissions look okay.
373 	// add the object to the appropriate list and assign an object handle
374 	//
375 
376 	if (sess_obj) {
377 		o->session = sess;
378 		(void) memset(o->name, 0x00, sizeof (CK_BYTE) * 8);
379 
380 		sess_obj_list = dlist_add_as_first(sess_obj_list, o);
381 	} else {
382 		CK_BYTE current[8];
383 		CK_BYTE next[8];
384 
385 		rc = XProcLock(xproclock);
386 		if (rc != CKR_OK) {
387 			goto done;
388 		} else {
389 
390 			if (priv_obj) {
391 				if (global_shm->num_priv_tok_obj >=
392 				    MAX_TOK_OBJS) {
393 					rc = CKR_HOST_MEMORY;
394 					(void) XProcUnLock(xproclock);
395 					goto done;
396 				}
397 			} else {
398 				if (global_shm->num_publ_tok_obj >=
399 				    MAX_TOK_OBJS) {
400 					rc = CKR_HOST_MEMORY;
401 					(void) XProcUnLock(xproclock);
402 					goto done;
403 				}
404 			}
405 
406 			(void) memcpy(current,
407 			    &nv_token_data->next_token_object_name, 8);
408 
409 			o->session = NULL;
410 			(void) memcpy(&o->name, current, 8);
411 
412 			(void) compute_next_token_obj_name(current, next);
413 
414 			(void) memcpy(&nv_token_data->next_token_object_name,
415 			    next, 8);
416 
417 			rc = save_token_object(sess->hContext, o);
418 			if (rc != CKR_OK) {
419 				(void) XProcUnLock(xproclock);
420 				goto done;
421 			}
422 
423 			(void) object_mgr_add_to_shm(o);
424 			(void) XProcUnLock(xproclock);
425 
426 			(void) save_token_data(nv_token_data);
427 		}
428 
429 		if (priv_obj)
430 			priv_token_obj_list =
431 			    dlist_add_as_last(priv_token_obj_list, o);
432 		else
433 			publ_token_obj_list =
434 			    dlist_add_as_last(publ_token_obj_list, o);
435 	}
436 
437 	rc = object_mgr_add_to_map(sess, o, handle);
438 	if (rc != CKR_OK) {
439 		DL_NODE *node = NULL;
440 
441 		if (sess_obj) {
442 			node = dlist_find(sess_obj_list, o);
443 			if (node)
444 				sess_obj_list =
445 				    dlist_remove_node(sess_obj_list, node);
446 		} else {
447 			(void) delete_token_object(o);
448 
449 			if (priv_obj) {
450 				node = dlist_find(priv_token_obj_list, o);
451 				if (node)
452 					priv_token_obj_list =
453 					    dlist_remove_node(
454 					    priv_token_obj_list, node);
455 			} else {
456 				node = dlist_find(publ_token_obj_list, o);
457 				if (node)
458 					publ_token_obj_list =
459 					    dlist_remove_node(
460 					    publ_token_obj_list, node);
461 			}
462 
463 			rc = XProcLock(xproclock);
464 			if (rc != CKR_OK) {
465 				goto done;
466 			}
467 			(void) object_mgr_del_from_shm(o);
468 
469 			(void) XProcUnLock(xproclock);
470 		}
471 	}
472 
473 done:
474 	(void) pthread_mutex_unlock(&obj_list_mutex);
475 
476 	if ((rc != CKR_OK) && (o != NULL))
477 		(void) object_free(o);
478 
479 	return (rc);
480 }
481 
482 CK_RV
483 object_mgr_add_to_map(SESSION	  * sess,
484 	OBJECT	   * obj,
485 	CK_OBJECT_HANDLE * handle) {
486 	OBJECT_MAP  *map_node = NULL;
487 
488 	if (! sess || ! obj || ! handle) {
489 		return (CKR_FUNCTION_FAILED);
490 	}
491 
492 	map_node = (OBJECT_MAP *)malloc(sizeof (OBJECT_MAP));
493 	if (! map_node) {
494 		return (CKR_HOST_MEMORY);
495 	}
496 	map_node->handle   = next_object_handle++;
497 	map_node->session  = sess;
498 	map_node->ptr	= obj;
499 
500 	if (obj->session != NULL)
501 		map_node->is_session_obj = TRUE;
502 	else
503 		map_node->is_session_obj = FALSE;
504 
505 	// add the new map entry to the list
506 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
507 		return (CKR_FUNCTION_FAILED);
508 	}
509 	object_map = dlist_add_as_first(object_map, map_node);
510 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
511 
512 	*handle = map_node->handle;
513 	return (CKR_OK);
514 }
515 
516 // object_mgr_copy()
517 //
518 // algorithm:
519 //    1) find the old object
520 //    2) get the template from the old object
521 //    3) merge in the new object's template
522 //    4) perform class - specific sanity checks
523 //
524 CK_RV
525 object_mgr_copy(SESSION	  * sess,
526 	CK_ATTRIBUTE	* pTemplate,
527 	CK_ULONG	   ulCount,
528 	CK_OBJECT_HANDLE   old_handle,
529 	CK_OBJECT_HANDLE * new_handle)
530 {
531 	OBJECT	*old_obj = NULL;
532 	OBJECT	*new_obj = NULL;
533 	CK_BBOOL    priv_obj;
534 	CK_BBOOL    sess_obj;
535 	CK_RV	rc;
536 
537 	if (! sess || ! pTemplate || ! new_handle) {
538 		return (CKR_FUNCTION_FAILED);
539 	}
540 
541 	rc = pthread_mutex_lock(&obj_list_mutex);
542 	if (rc != CKR_OK)
543 		return (CKR_FUNCTION_FAILED);
544 
545 	rc = object_mgr_find_in_map1(sess->hContext, old_handle, &old_obj);
546 	if (rc != CKR_OK) {
547 		goto done;
548 	}
549 	rc = object_copy(pTemplate, ulCount, old_obj, &new_obj);
550 	if (rc != CKR_OK) {
551 		goto done;
552 	}
553 
554 	sess_obj = object_is_session_object(new_obj);
555 	priv_obj = object_is_private(new_obj);
556 
557 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
558 		if (priv_obj) {
559 			rc = CKR_USER_NOT_LOGGED_IN;
560 			goto done;
561 		}
562 
563 		if (! sess_obj) {
564 			rc = CKR_SESSION_READ_ONLY;
565 			goto done;
566 		}
567 	}
568 
569 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
570 		if (! sess_obj) {
571 			rc = CKR_SESSION_READ_ONLY;
572 			goto done;
573 		}
574 	}
575 
576 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
577 		if (priv_obj) {
578 			rc = CKR_USER_NOT_LOGGED_IN;
579 			goto done;
580 		}
581 	}
582 
583 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
584 		if (priv_obj) {
585 			rc = CKR_USER_NOT_LOGGED_IN;
586 			goto done;
587 		}
588 	}
589 
590 	if (sess_obj) {
591 		new_obj->session = sess;
592 		(void) memset(&new_obj->name, 0x00, sizeof (CK_BYTE) * 8);
593 
594 		sess_obj_list = dlist_add_as_first(sess_obj_list, new_obj);
595 	} else {
596 		CK_BYTE current[8];
597 		CK_BYTE next[8];
598 
599 		rc = XProcLock(xproclock);
600 		if (rc != CKR_OK) {
601 			goto done;
602 		} else {
603 			if (priv_obj) {
604 				if (global_shm->num_priv_tok_obj >=
605 				    MAX_TOK_OBJS) {
606 					(void) XProcUnLock(xproclock);
607 					rc = CKR_HOST_MEMORY;
608 					goto done;
609 				}
610 			} else {
611 				if (global_shm->num_publ_tok_obj >=
612 				    MAX_TOK_OBJS) {
613 					(void) XProcUnLock(xproclock);
614 					rc = CKR_HOST_MEMORY;
615 					goto done;
616 				}
617 			}
618 			(void) memcpy(current,
619 			    &nv_token_data->next_token_object_name, 8);
620 
621 			new_obj->session = NULL;
622 			(void) memcpy(&new_obj->name, current, 8);
623 
624 			(void) compute_next_token_obj_name(current, next);
625 			(void) memcpy(&nv_token_data->next_token_object_name,
626 			    next, 8);
627 
628 			rc = save_token_object(sess->hContext, new_obj);
629 			if (rc != CKR_OK) {
630 				(void) XProcUnLock(xproclock);
631 				goto done;
632 			}
633 
634 			(void) object_mgr_add_to_shm(new_obj);
635 
636 			(void) XProcUnLock(xproclock);
637 
638 			(void) save_token_data(nv_token_data);
639 		}
640 
641 		if (priv_obj)
642 			priv_token_obj_list = dlist_add_as_last(
643 			    priv_token_obj_list, new_obj);
644 		else
645 			publ_token_obj_list = dlist_add_as_last(
646 			    publ_token_obj_list, new_obj);
647 	}
648 
649 	rc = object_mgr_add_to_map(sess, new_obj, new_handle);
650 	if (rc != CKR_OK) {
651 		DL_NODE *node = NULL;
652 
653 		if (sess_obj) {
654 			node = dlist_find(sess_obj_list, new_obj);
655 			if (node)
656 				sess_obj_list = dlist_remove_node(
657 				    sess_obj_list, node);
658 		} else {
659 			(void) delete_token_object(new_obj);
660 
661 			if (priv_obj) {
662 				node = dlist_find(priv_token_obj_list, new_obj);
663 				if (node)
664 					priv_token_obj_list = dlist_remove_node(
665 					    priv_token_obj_list, node);
666 			} else {
667 				node = dlist_find(publ_token_obj_list, new_obj);
668 				if (node)
669 					publ_token_obj_list = dlist_remove_node(
670 					    publ_token_obj_list, node);
671 			}
672 
673 			rc = XProcLock(xproclock);
674 			if (rc != CKR_OK) {
675 				goto done;
676 			}
677 			(void) object_mgr_del_from_shm(new_obj);
678 
679 			(void) XProcUnLock(xproclock);
680 		}
681 	}
682 
683 done:
684 	(void) pthread_mutex_unlock(&obj_list_mutex);
685 
686 	if ((rc != CKR_OK) && (new_obj != NULL))
687 		(void) object_free(new_obj);
688 
689 	return (rc);
690 }
691 
692 //
693 // determines whether the session is allowed to create an object.  creates
694 // the object but doesn't add the object to any object lists or to the
695 // process' object map.
696 //
697 CK_RV
698 object_mgr_create_skel(SESSION	* sess,
699 	CK_ATTRIBUTE  * pTemplate,
700 	CK_ULONG	ulCount,
701 	CK_ULONG	mode,
702 	CK_ULONG	obj_type,
703 	CK_ULONG	sub_class,
704 	OBJECT	** obj)
705 {
706 	OBJECT	*o = NULL;
707 	CK_RV	rc;
708 	CK_BBOOL    priv_obj;
709 	CK_BBOOL    sess_obj;
710 
711 	if (! sess || ! obj) {
712 		return (CKR_FUNCTION_FAILED);
713 	}
714 	if (! pTemplate && (ulCount != 0)) {
715 		return (CKR_FUNCTION_FAILED);
716 	}
717 	rc = object_create_skel(pTemplate, ulCount,
718 	    mode, obj_type, sub_class, &o);
719 	if (rc != CKR_OK) {
720 		return (rc);
721 	}
722 	sess_obj = object_is_session_object(o);
723 	priv_obj = object_is_private(o);
724 
725 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
726 		if (priv_obj) {
727 			(void) object_free(o);
728 			return (CKR_USER_NOT_LOGGED_IN);
729 		}
730 
731 		if (! sess_obj) {
732 			(void) object_free(o);
733 			return (CKR_SESSION_READ_ONLY);
734 		}
735 	}
736 
737 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
738 		if (! sess_obj) {
739 			(void) object_free(o);
740 			return (CKR_SESSION_READ_ONLY);
741 		}
742 	}
743 
744 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
745 		if (priv_obj) {
746 			(void) object_free(o);
747 			return (CKR_USER_NOT_LOGGED_IN);
748 		}
749 	}
750 
751 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
752 		if (priv_obj) {
753 			(void) object_free(o);
754 			return (CKR_USER_NOT_LOGGED_IN);
755 		}
756 	}
757 
758 	*obj = o;
759 	return (CKR_OK);
760 }
761 
762 CK_RV
763 object_mgr_create_final(SESSION	   * sess,
764 	OBJECT	    * obj,
765 	CK_OBJECT_HANDLE  * handle)
766 {
767 	CK_BBOOL  sess_obj;
768 	CK_BBOOL  priv_obj;
769 	CK_RV	rc;
770 
771 	if (!sess || !obj || !handle)
772 		return (CKR_FUNCTION_FAILED);
773 
774 	rc = pthread_mutex_lock(&obj_list_mutex);
775 	if (rc != CKR_OK)
776 		return (CKR_FUNCTION_FAILED);
777 
778 	sess_obj = object_is_session_object(obj);
779 	priv_obj = object_is_private(obj);
780 
781 	if (sess_obj) {
782 		obj->session = sess;
783 		(void) memset(obj->name, 0x0, sizeof (CK_BYTE) * 8);
784 
785 		sess_obj_list = dlist_add_as_first(sess_obj_list, obj);
786 	} else {
787 		CK_BYTE current[8];
788 		CK_BYTE next[8];
789 
790 		rc = XProcLock(xproclock);
791 		if (rc != CKR_OK) {
792 			goto done;
793 		} else {
794 			if (priv_obj) {
795 				if (global_shm->num_priv_tok_obj >=
796 				    MAX_TOK_OBJS) {
797 					(void) XProcUnLock(xproclock);
798 					rc = CKR_HOST_MEMORY;
799 					goto done;
800 				}
801 			} else {
802 				if (global_shm->num_publ_tok_obj >=
803 				    MAX_TOK_OBJS) {
804 					(void) XProcUnLock(xproclock);
805 					rc = CKR_HOST_MEMORY;
806 					goto done;
807 				}
808 			}
809 			(void) memcpy(current,
810 			    &nv_token_data->next_token_object_name, 8);
811 
812 			obj->session = NULL;
813 			(void) memcpy(&obj->name, current, 8);
814 
815 			(void) compute_next_token_obj_name(current, next);
816 			(void) memcpy(&nv_token_data->next_token_object_name,
817 			    next, 8);
818 
819 			rc = save_token_object(sess->hContext, obj);
820 			if (rc != CKR_OK) {
821 				(void) XProcUnLock(xproclock);
822 				goto done;
823 			}
824 
825 			(void) object_mgr_add_to_shm(obj);
826 
827 			(void) XProcUnLock(xproclock);
828 
829 			(void) save_token_data(nv_token_data);
830 		}
831 
832 		if (priv_obj)
833 			priv_token_obj_list = dlist_add_as_last(
834 			    priv_token_obj_list, obj);
835 		else
836 			publ_token_obj_list = dlist_add_as_last(
837 			    publ_token_obj_list, obj);
838 	}
839 
840 	rc = object_mgr_add_to_map(sess, obj, handle);
841 	if (rc != CKR_OK) {
842 		DL_NODE *node = NULL;
843 
844 		if (sess_obj) {
845 			node = dlist_find(sess_obj_list, obj);
846 			if (node)
847 				sess_obj_list = dlist_remove_node(
848 				    sess_obj_list, node);
849 		} else {
850 			(void) delete_token_object(obj);
851 
852 			if (priv_obj) {
853 				node = dlist_find(priv_token_obj_list, obj);
854 				if (node)
855 					priv_token_obj_list = dlist_remove_node(
856 					    priv_token_obj_list, node);
857 			} else {
858 				node = dlist_find(publ_token_obj_list, obj);
859 				if (node)
860 					publ_token_obj_list = dlist_remove_node(
861 					    publ_token_obj_list, node);
862 			}
863 
864 			rc = XProcLock(xproclock);
865 			if (rc != CKR_OK) {
866 				goto done;
867 			}
868 			(void) object_mgr_del_from_shm(obj);
869 
870 			(void) XProcUnLock(xproclock);
871 		}
872 	}
873 
874 done:
875 	(void) pthread_mutex_unlock(&obj_list_mutex);
876 
877 	return (rc);
878 }
879 
880 CK_RV
881 object_mgr_destroy_object(SESSION	  * sess,
882 	CK_OBJECT_HANDLE   handle)
883 {
884 	OBJECT    * obj = NULL;
885 	CK_BBOOL    sess_obj;
886 	CK_BBOOL    priv_obj;
887 	CK_RV	rc;
888 
889 	if (! sess)
890 		return (CKR_FUNCTION_FAILED);
891 
892 	rc = pthread_mutex_lock(&obj_list_mutex);
893 	if (rc != CKR_OK)
894 		return (CKR_FUNCTION_FAILED);
895 
896 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
897 	if (rc != CKR_OK) {
898 		goto done;
899 	}
900 	sess_obj = object_is_session_object(obj);
901 	priv_obj = object_is_private(obj);
902 
903 	if (sess_obj) {
904 		DL_NODE *node;
905 
906 		node = dlist_find(sess_obj_list, obj);
907 		if (node) {
908 			(void) object_mgr_remove_from_map(handle);
909 
910 			(void) object_free(obj);
911 			sess_obj_list = dlist_remove_node(
912 			    sess_obj_list, node);
913 
914 			rc = CKR_OK;
915 			goto done;
916 		}
917 	} else {
918 		DL_NODE *node = NULL;
919 
920 		(void) delete_token_object(obj);
921 
922 		if (priv_obj)
923 			node = dlist_find(priv_token_obj_list, obj);
924 		else
925 			node = dlist_find(publ_token_obj_list, obj);
926 
927 		if (node) {
928 			rc = XProcLock(xproclock);
929 			if (rc != CKR_OK) {
930 				goto done;
931 			}
932 			(void) object_mgr_del_from_shm(obj);
933 
934 			(void) XProcUnLock(xproclock);
935 
936 			(void) object_mgr_remove_from_map(handle);
937 
938 			(void) object_free(obj);
939 
940 			if (priv_obj)
941 				priv_token_obj_list = dlist_remove_node(
942 				    priv_token_obj_list, node);
943 			else
944 				publ_token_obj_list = dlist_remove_node(
945 				    publ_token_obj_list, node);
946 
947 			rc = CKR_OK;
948 			goto done;
949 		}
950 	}
951 
952 	rc = CKR_FUNCTION_FAILED;
953 done:
954 	(void) pthread_mutex_unlock(&obj_list_mutex);
955 
956 	return (rc);
957 }
958 
959 CK_RV
960 object_mgr_destroy_token_objects(TSS_HCONTEXT hContext)
961 {
962 	CK_BBOOL locked2 = FALSE;
963 	CK_RV rc;
964 
965 	rc = pthread_mutex_lock(&obj_list_mutex);
966 	if (rc != CKR_OK)
967 		return (CKR_FUNCTION_FAILED);
968 
969 	while (publ_token_obj_list) {
970 		OBJECT *obj = (OBJECT *)publ_token_obj_list->data;
971 
972 		CK_OBJECT_HANDLE handle;
973 
974 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
975 		if (rc == CKR_OK) {
976 			(void) object_mgr_remove_from_map(handle);
977 		}
978 		(void) delete_token_object(obj);
979 		(void) object_free(obj);
980 
981 		publ_token_obj_list = dlist_remove_node(
982 		    publ_token_obj_list, publ_token_obj_list);
983 	}
984 
985 	while (priv_token_obj_list) {
986 		OBJECT *obj = (OBJECT *)priv_token_obj_list->data;
987 
988 		CK_OBJECT_HANDLE handle;
989 
990 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
991 		if (rc == CKR_OK) {
992 			(void) object_mgr_remove_from_map(handle);
993 		}
994 		(void) delete_token_object(obj);
995 		(void) object_free(obj);
996 
997 		priv_token_obj_list = dlist_remove_node(
998 		    priv_token_obj_list, priv_token_obj_list);
999 	}
1000 
1001 	// now we want to purge the token object list in shared memory
1002 	//
1003 	rc = XProcLock(xproclock);
1004 	if (rc == CKR_OK) {
1005 		locked2 = TRUE;
1006 
1007 		global_shm->num_priv_tok_obj = 0;
1008 		global_shm->num_publ_tok_obj = 0;
1009 
1010 		(void) memset(&global_shm->publ_tok_objs, 0x0,
1011 		    MAX_TOK_OBJS * sizeof (TOK_OBJ_ENTRY));
1012 		(void) memset(&global_shm->priv_tok_objs, 0x0,
1013 		    MAX_TOK_OBJS * sizeof (TOK_OBJ_ENTRY));
1014 	}
1015 
1016 done:
1017 	(void) pthread_mutex_unlock(&obj_list_mutex);
1018 
1019 	if (locked2 == TRUE) (void) XProcUnLock(xproclock);
1020 
1021 	return (rc);
1022 }
1023 
1024 //
1025 // Locates the specified object in the map
1026 // without going and checking for cache update
1027 //
1028 CK_RV
1029 object_mgr_find_in_map_nocache(CK_OBJECT_HANDLE    handle,
1030 	OBJECT	   ** ptr) {
1031 	DL_NODE   * node = NULL;
1032 	OBJECT    * obj  = NULL;
1033 
1034 	if (! ptr) {
1035 		return (CKR_FUNCTION_FAILED);
1036 	}
1037 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1038 		return (CKR_FUNCTION_FAILED);
1039 	}
1040 	node = object_map;
1041 	while (node) {
1042 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1043 
1044 		if (map->handle == handle) {
1045 			obj = map->ptr;
1046 			break;
1047 		}
1048 
1049 		node = node->next;
1050 	}
1051 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1052 
1053 	if (obj == NULL || node == NULL) {
1054 		return (CKR_OBJECT_HANDLE_INVALID);
1055 	}
1056 
1057 	if (object_is_session_object(obj) == TRUE) {
1058 		 *ptr = obj;
1059 		return (CKR_OK);
1060 	}
1061 
1062 	*ptr = obj;
1063 	return (CKR_OK);
1064 }
1065 
1066 CK_RV
1067 object_mgr_find_in_map1(
1068 	TSS_HCONTEXT hContext,
1069 	CK_OBJECT_HANDLE    handle,
1070 	OBJECT	   ** ptr)
1071 {
1072 	DL_NODE   * node = NULL;
1073 	OBJECT    * obj  = NULL;
1074 
1075 	if (! ptr) {
1076 		return (CKR_FUNCTION_FAILED);
1077 	}
1078 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1079 		return (CKR_FUNCTION_FAILED);
1080 	}
1081 	node = object_map;
1082 	while (node) {
1083 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1084 
1085 		if (map->handle == handle) {
1086 			obj = map->ptr;
1087 			break;
1088 		}
1089 
1090 		node = node->next;
1091 	}
1092 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1093 
1094 	if (obj == NULL || node == NULL) {
1095 		return (CKR_OBJECT_HANDLE_INVALID);
1096 	}
1097 
1098 	if (object_is_session_object(obj) == TRUE) {
1099 		*ptr = obj;
1100 		return (CKR_OK);
1101 	}
1102 
1103 	(void) object_mgr_check_shm(hContext, obj);
1104 
1105 	*ptr = obj;
1106 	return (CKR_OK);
1107 }
1108 
1109 CK_RV
1110 object_mgr_find_in_map2(
1111 	TSS_HCONTEXT hContext,
1112 	OBJECT	   * obj,
1113 	CK_OBJECT_HANDLE * handle)
1114 {
1115 	DL_NODE	   * node = NULL;
1116 	CK_OBJECT_HANDLE    h    = (CK_OBJECT_HANDLE)NULL;
1117 
1118 	if (! obj || ! handle) {
1119 		return (CKR_FUNCTION_FAILED);
1120 	}
1121 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1122 		return (CKR_FUNCTION_FAILED);
1123 	}
1124 	node = object_map;
1125 	while (node) {
1126 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1127 
1128 		if (map->ptr == obj) {
1129 			h = map->handle;
1130 			break;
1131 		}
1132 
1133 		node = node->next;
1134 	}
1135 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1136 
1137 	if (node == NULL) {
1138 		return (CKR_OBJECT_HANDLE_INVALID);
1139 	}
1140 
1141 	if (object_is_session_object(obj) == TRUE) {
1142 		*handle = h;
1143 		return (CKR_OK);
1144 	}
1145 
1146 	(void) object_mgr_check_shm(hContext, obj);
1147 
1148 	*handle = h;
1149 	return (CKR_OK);
1150 }
1151 
1152 CK_RV
1153 object_mgr_find_init(SESSION	* sess,
1154 	CK_ATTRIBUTE * pTemplate,
1155 	CK_ULONG	ulCount)
1156 {
1157 	if (! sess) {
1158 		return (CKR_FUNCTION_FAILED);
1159 	}
1160 	if (sess->find_active != FALSE) {
1161 		return (CKR_OPERATION_ACTIVE);
1162 	}
1163 	// initialize the found object list.  if it doesn't exist, allocate
1164 	// a list big enough for 10 handles.  we'll reallocate if we need more
1165 	//
1166 	if (sess->find_list != NULL) {
1167 		(void) memset(sess->find_list, 0x0,
1168 		    sess->find_len * sizeof (CK_OBJECT_HANDLE));
1169 	} else {
1170 		sess->find_list = (CK_OBJECT_HANDLE *)malloc(
1171 		    10 * sizeof (CK_OBJECT_HANDLE));
1172 		if (! sess->find_list) {
1173 			return (CKR_HOST_MEMORY);
1174 		} else {
1175 			(void) memset(sess->find_list, 0x0,
1176 			    10 * sizeof (CK_OBJECT_HANDLE));
1177 			sess->find_len = 10;
1178 		}
1179 	}
1180 
1181 	sess->find_count = 0;
1182 	sess->find_idx   = 0;
1183 
1184 	//  --- need to grab the object lock here
1185 	if (pthread_mutex_lock(&obj_list_mutex))
1186 		return (CKR_FUNCTION_FAILED);
1187 
1188 	(void) object_mgr_update_from_shm(sess->hContext);
1189 
1190 	// which objects can be return (ed:
1191 	//
1192 	//   Public Session:   public session objects, public token objects
1193 	//   User Session:	all session objects,    all token objects
1194 	//   SO session:	public session objects, public token objects
1195 	//
1196 	switch (sess->session_info.state) {
1197 		case CKS_RO_PUBLIC_SESSION:
1198 		case CKS_RW_PUBLIC_SESSION:
1199 		case CKS_RW_SO_FUNCTIONS:
1200 		(void) object_mgr_find_build_list(sess, pTemplate,
1201 		    ulCount, publ_token_obj_list, TRUE);
1202 		(void) object_mgr_find_build_list(sess, pTemplate,
1203 		    ulCount, sess_obj_list,	TRUE);
1204 		break;
1205 
1206 		case CKS_RO_USER_FUNCTIONS:
1207 		case CKS_RW_USER_FUNCTIONS:
1208 		(void) object_mgr_find_build_list(sess, pTemplate,
1209 		    ulCount, priv_token_obj_list, FALSE);
1210 		(void) object_mgr_find_build_list(sess, pTemplate,
1211 		    ulCount, publ_token_obj_list, FALSE);
1212 		(void) object_mgr_find_build_list(sess, pTemplate,
1213 		    ulCount, sess_obj_list,  FALSE);
1214 		break;
1215 	}
1216 	(void) pthread_mutex_unlock(&obj_list_mutex);
1217 
1218 	sess->find_active = TRUE;
1219 
1220 	return (CKR_OK);
1221 }
1222 
1223 CK_RV
1224 object_mgr_find_build_list(SESSION	* sess,
1225 	CK_ATTRIBUTE * pTemplate,
1226 	CK_ULONG	ulCount,
1227 	DL_NODE	* obj_list,
1228 	CK_BBOOL	public_only)
1229 {
1230 	OBJECT	   * obj  = NULL;
1231 	DL_NODE	  * node = NULL;
1232 	CK_OBJECT_HANDLE   handle;
1233 	CK_BBOOL	   is_priv;
1234 	CK_BBOOL	   match;
1235 	CK_BBOOL	   hw_feature = FALSE;
1236 	CK_BBOOL	   hidden_object = FALSE;
1237 	CK_RV		rc;
1238 	CK_ATTRIBUTE	* attr;
1239 	unsigned int		i;
1240 
1241 	if (! sess) {
1242 		return (CKR_FUNCTION_FAILED);
1243 	}
1244 	if (! obj_list)
1245 		return (CKR_OK);
1246 	// PKCS#11 v2.11 (pg. 79): "When searching using C_FindObjectsInit
1247 	// and C_FindObjects, hardware feature objects are not returned
1248 	// unless the CKA_CLASS attribute in the template has the value
1249 	// CKO_HW_FEATURE." So, we check for CKO_HW_FEATURE and if its set,
1250 	// we'll find these objects below. - KEY
1251 	for (i = 0; i < ulCount; i++) {
1252 		if (pTemplate[i].type == CKA_CLASS) {
1253 			if (*(CK_ULONG *)pTemplate[i].pValue ==
1254 			    CKO_HW_FEATURE) {
1255 				hw_feature = TRUE;
1256 				break;
1257 			}
1258 		}
1259 
1260 		if (pTemplate[i].type == CKA_HIDDEN) {
1261 			if (*(CK_BBOOL *)pTemplate[i].pValue == TRUE) {
1262 				hidden_object = TRUE;
1263 				break;
1264 			}
1265 		}
1266 	}
1267 
1268 	node = obj_list;
1269 	while (node) {
1270 		match   = FALSE;
1271 		obj	= (OBJECT *)node->data;
1272 		is_priv = object_is_private(obj);
1273 
1274 
1275 		if ((is_priv == FALSE) || (public_only == FALSE)) {
1276 			if (pTemplate == NULL || ulCount == 0)
1277 				match = TRUE;
1278 			else
1279 				match = template_compare(pTemplate,
1280 				    ulCount, obj->template);
1281 		}
1282 
1283 		if (match) {
1284 			rc = object_mgr_find_in_map2(sess->hContext, obj,
1285 			    &handle);
1286 			if (rc != CKR_OK) {
1287 				rc = object_mgr_add_to_map(sess, obj, &handle);
1288 				if (rc != CKR_OK) {
1289 					return (CKR_FUNCTION_FAILED);
1290 				}
1291 			}
1292 			if (rc == CKR_OK) {
1293 				if ((hw_feature == FALSE) &&
1294 				    (template_attribute_find(obj->template,
1295 				    CKA_CLASS, &attr) == TRUE)) {
1296 					if (*(CK_OBJECT_CLASS *)attr->pValue ==
1297 					    CKO_HW_FEATURE)
1298 						goto next_loop;
1299 				}
1300 
1301 				if ((hidden_object == FALSE) &&
1302 				    (template_attribute_find(obj->template,
1303 				    CKA_HIDDEN, &attr) == TRUE)) {
1304 					if (*(CK_BBOOL *)attr->pValue == TRUE)
1305 						goto next_loop;
1306 				}
1307 
1308 				sess->find_list[ sess->find_count ] = handle;
1309 				sess->find_count++;
1310 
1311 				if (sess->find_count >= sess->find_len) {
1312 					sess->find_len += 15;
1313 					sess->find_list =
1314 					    (CK_OBJECT_HANDLE *)realloc(
1315 					    sess->find_list, sess->find_len *
1316 					    sizeof (CK_OBJECT_HANDLE));
1317 					if (! sess->find_list) {
1318 						return (CKR_HOST_MEMORY);
1319 					}
1320 				}
1321 			}
1322 		}
1323 		next_loop:
1324 		node = node->next;
1325 	}
1326 
1327 	return (CKR_OK);
1328 }
1329 
1330 CK_RV
1331 object_mgr_find_final(SESSION *sess)
1332 {
1333 	if (! sess) {
1334 		return (CKR_FUNCTION_FAILED);
1335 	}
1336 	if (sess->find_active == FALSE) {
1337 		return (CKR_OPERATION_NOT_INITIALIZED);
1338 	}
1339 	free(sess->find_list);
1340 	sess->find_list   = NULL;
1341 	sess->find_count  = 0;
1342 	sess->find_idx    = 0;
1343 	sess->find_active = FALSE;
1344 
1345 	return (CKR_OK);
1346 }
1347 
1348 CK_RV
1349 object_mgr_get_attribute_values(SESSION	   * sess,
1350 	CK_OBJECT_HANDLE    handle,
1351 	CK_ATTRIBUTE	* pTemplate,
1352 	CK_ULONG	    ulCount)
1353 {
1354 	OBJECT   * obj;
1355 	CK_BBOOL   priv_obj;
1356 	CK_RV	rc;
1357 
1358 	if (! pTemplate) {
1359 		return (CKR_FUNCTION_FAILED);
1360 	}
1361 	rc = pthread_mutex_lock(&obj_list_mutex);
1362 	if (rc != CKR_OK)
1363 		return (CKR_FUNCTION_FAILED);
1364 
1365 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
1366 	if (rc != CKR_OK) {
1367 		goto done;
1368 	}
1369 	priv_obj = object_is_private(obj);
1370 
1371 	if (priv_obj == TRUE) {
1372 		if (sess->session_info.state == CKS_RO_PUBLIC_SESSION ||
1373 		    sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
1374 			rc = CKR_USER_NOT_LOGGED_IN;
1375 			goto done;
1376 		}
1377 	}
1378 
1379 	rc = object_get_attribute_values(obj, pTemplate, ulCount);
1380 done:
1381 	(void) pthread_mutex_unlock(&obj_list_mutex);
1382 
1383 	return (rc);
1384 }
1385 
1386 CK_RV
1387 object_mgr_get_object_size(
1388 	TSS_HCONTEXT hContext,
1389 	CK_OBJECT_HANDLE   handle,
1390 	CK_ULONG	 * size)
1391 {
1392 	OBJECT    * obj;
1393 	CK_RV	rc;
1394 
1395 	rc = pthread_mutex_lock(&obj_list_mutex);
1396 	if (rc != CKR_OK)
1397 		return (CKR_FUNCTION_FAILED);
1398 
1399 	rc = object_mgr_find_in_map1(hContext, handle, &obj);
1400 	if (rc != CKR_OK) {
1401 		rc = CKR_OBJECT_HANDLE_INVALID;
1402 		goto done;
1403 	}
1404 
1405 	*size = object_get_size(obj);
1406 
1407 done:
1408 	(void) pthread_mutex_unlock(&obj_list_mutex);
1409 	return (rc);
1410 }
1411 
1412 
1413 // object_mgr_invalidate_handle1()
1414 //
1415 // Returns:  TRUE  if successfully removes the node
1416 //	   FALSE if cannot remove the node (not found, etc)
1417 //
1418 CK_BBOOL
1419 object_mgr_invalidate_handle1(CK_OBJECT_HANDLE handle)
1420 {
1421 	DL_NODE *node = NULL;
1422 
1423 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1424 		return (CKR_FUNCTION_FAILED);
1425 	}
1426 	node = object_map;
1427 
1428 	while (node) {
1429 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1430 
1431 		if (map->handle == handle) {
1432 			object_map = dlist_remove_node(object_map, node);
1433 			free(map);
1434 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1435 			return (TRUE);
1436 		}
1437 
1438 		node = node->next;
1439 	}
1440 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1441 	return (FALSE);
1442 }
1443 
1444 // object_mgr_invalidate_handle2()
1445 //
1446 // Returns:  TRUE  if successfully removes the node
1447 //	   FALSE if cannot remove the node (not found, etc)
1448 //
1449 CK_BBOOL
1450 object_mgr_invalidate_handle2(OBJECT *obj)
1451 {
1452 	DL_NODE *node = NULL;
1453 
1454 	if (! obj)
1455 		return (FALSE);
1456 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1457 		return (CKR_FUNCTION_FAILED);
1458 	}
1459 	node = object_map;
1460 
1461 	while (node) {
1462 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1463 		if (map->ptr == obj) {
1464 			object_map = dlist_remove_node(object_map, node);
1465 			free(map);
1466 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1467 			return (TRUE);
1468 		}
1469 		node = node->next;
1470 	}
1471 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1472 
1473 	return (FALSE);
1474 }
1475 
1476 // object_mgr_purge_session_objects()
1477 //
1478 // Args:    SESSION *
1479 //	  SESS_OBJ_TYPE:  can be ALL, PRIVATE or PUBLIC
1480 //
1481 // Remove all session objects owned by the specified session satisfying
1482 // the 'type' requirements
1483 //
1484 CK_BBOOL
1485 object_mgr_purge_session_objects(SESSION	* sess,
1486 	SESS_OBJ_TYPE   type)
1487 {
1488 	DL_NODE   *node = NULL;
1489 	DL_NODE   *next = NULL;
1490 	OBJECT    *obj = NULL;
1491 	CK_BBOOL   del;
1492 	CK_RV	rc;
1493 
1494 	if (!sess)
1495 		return (FALSE);
1496 
1497 	rc = pthread_mutex_lock(&obj_list_mutex);
1498 	if (rc != CKR_OK)
1499 		return (FALSE);
1500 
1501 	node = sess_obj_list;
1502 
1503 	while (node) {
1504 		obj = (OBJECT *)node->data;
1505 		del = FALSE;
1506 
1507 		if (obj->session == sess) {
1508 			if (type == PRIVATE) {
1509 				if (object_is_private(obj))
1510 					del = TRUE;
1511 			} else if (type == PUBLIC) {
1512 				if (object_is_public(obj))
1513 					del = TRUE;
1514 			} else if (type == ALL)
1515 				del = TRUE;
1516 		}
1517 		if (del == TRUE) {
1518 
1519 			CK_OBJECT_HANDLE handle;
1520 			CK_RV	    rc;
1521 
1522 			rc = object_mgr_find_in_map2(sess->hContext, obj,
1523 			    &handle);
1524 			if (rc == CKR_OK) {
1525 				(void) object_mgr_invalidate_handle1(handle);
1526 				(void) object_free(obj);
1527 			}
1528 
1529 			next = node->next;
1530 			sess_obj_list = dlist_remove_node(sess_obj_list, node);
1531 			node = next;
1532 		}
1533 		else
1534 			node = node->next;
1535 	}
1536 
1537 	(void) pthread_mutex_unlock(&obj_list_mutex);
1538 
1539 	return (TRUE);
1540 }
1541 
1542 //
1543 // This routine cleans up the list of token objects.  in general, we don't
1544 // need to do this but when tracing memory leaks, it's best that we free
1545 // everything that we've allocated.
1546 //
1547 CK_BBOOL
1548 object_mgr_purge_token_objects(TSS_HCONTEXT hContext)
1549 {
1550 	DL_NODE   *node = NULL;
1551 	DL_NODE   *next = NULL;
1552 	OBJECT    *obj = NULL;
1553 	CK_RV	rc;
1554 
1555 	rc = pthread_mutex_lock(&obj_list_mutex);
1556 	if (rc != CKR_OK)
1557 		return (FALSE);
1558 
1559 	node = publ_token_obj_list;
1560 	while (publ_token_obj_list) {
1561 		CK_OBJECT_HANDLE handle;
1562 		CK_RV	    rc;
1563 
1564 		obj = (OBJECT *)node->data;
1565 
1566 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1567 		if (rc == CKR_OK) {
1568 			(void) object_mgr_invalidate_handle1(handle);
1569 		}
1570 		(void) object_free(obj);
1571 
1572 		next = node->next;
1573 		publ_token_obj_list = dlist_remove_node(
1574 		    publ_token_obj_list, node);
1575 		node = next;
1576 	}
1577 
1578 	node = priv_token_obj_list;
1579 
1580 	while (priv_token_obj_list) {
1581 		CK_OBJECT_HANDLE handle;
1582 		CK_RV	    rc;
1583 
1584 		obj = (OBJECT *)node->data;
1585 
1586 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1587 		if (rc == CKR_OK)
1588 			(void) object_mgr_invalidate_handle1(handle);
1589 		(void) object_free(obj);
1590 
1591 		next = node->next;
1592 		priv_token_obj_list = dlist_remove_node(
1593 		    priv_token_obj_list, node);
1594 		node = next;
1595 	}
1596 
1597 	(void) pthread_mutex_unlock(&obj_list_mutex);
1598 
1599 	return (TRUE);
1600 }
1601 
1602 CK_BBOOL
1603 object_mgr_purge_private_token_objects(TSS_HCONTEXT hContext) {
1604 	OBJECT   * obj  = NULL;
1605 	DL_NODE  * node = NULL;
1606 	DL_NODE  * next = NULL;
1607 	CK_RV	rc;
1608 
1609 	rc = pthread_mutex_lock(&obj_list_mutex);
1610 	if (rc != CKR_OK)
1611 		return (FALSE);
1612 
1613 	node = priv_token_obj_list;
1614 	while (priv_token_obj_list) {
1615 		CK_OBJECT_HANDLE handle;
1616 		CK_RV	    rc;
1617 
1618 		obj = (OBJECT *)node->data;
1619 
1620 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1621 		if (rc == CKR_OK) {
1622 			(void) object_mgr_invalidate_handle1(handle);
1623 		}
1624 
1625 		(void) object_free(obj);
1626 
1627 		next = node->next;
1628 		priv_token_obj_list = dlist_remove_node(
1629 		    priv_token_obj_list, node);
1630 		node = next;
1631 	}
1632 
1633 	(void) pthread_mutex_unlock(&obj_list_mutex);
1634 
1635 	return (TRUE);
1636 }
1637 
1638 CK_RV
1639 object_mgr_remove_from_map(CK_OBJECT_HANDLE  handle)
1640 {
1641 	DL_NODE  *node = NULL;
1642 
1643 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1644 		return (CKR_FUNCTION_FAILED);
1645 	}
1646 	node = object_map;
1647 	while (node) {
1648 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1649 		if (map->handle == handle) {
1650 			object_map = dlist_remove_node(object_map, node);
1651 			free(map);
1652 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1653 			return (CKR_OK);
1654 		}
1655 		node = node->next;
1656 	}
1657 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1658 
1659 	return (CKR_FUNCTION_FAILED);
1660 }
1661 
1662 CK_RV
1663 object_mgr_restore_obj(CK_BYTE *data, OBJECT *oldObj)
1664 {
1665 	OBJECT    * obj  = NULL;
1666 	CK_BBOOL    priv;
1667 	CK_RV	rc;
1668 
1669 	if (! data) {
1670 		return (CKR_FUNCTION_FAILED);
1671 	}
1672 	if (oldObj != NULL) {
1673 		obj = oldObj;
1674 		rc = object_restore(data, &obj, TRUE);
1675 	} else {
1676 		rc = object_restore(data, &obj, FALSE);
1677 		if (rc == CKR_OK) {
1678 			priv = object_is_private(obj);
1679 
1680 			if (priv)
1681 				priv_token_obj_list = dlist_add_as_last(
1682 				    priv_token_obj_list, obj);
1683 			else
1684 				publ_token_obj_list = dlist_add_as_last(
1685 				    publ_token_obj_list, obj);
1686 
1687 			(void) (void) XProcLock(xproclock);
1688 
1689 			if (priv) {
1690 				if (global_shm->priv_loaded == FALSE) {
1691 					if (global_shm->num_priv_tok_obj <
1692 					    MAX_TOK_OBJS)
1693 						(void) object_mgr_add_to_shm(
1694 						    obj);
1695 					else
1696 						rc = CKR_HOST_MEMORY;
1697 				}
1698 			} else {
1699 				if (global_shm->publ_loaded == FALSE) {
1700 					if (global_shm->num_publ_tok_obj <
1701 					    MAX_TOK_OBJS)
1702 						(void) object_mgr_add_to_shm(
1703 						    obj);
1704 					else
1705 						rc = CKR_HOST_MEMORY;
1706 				}
1707 			}
1708 
1709 			(void) XProcUnLock(xproclock);
1710 		}
1711 	}
1712 
1713 	// make the callers have to have the mutes
1714 	// to many grab it now.
1715 	return (rc);
1716 }
1717 
1718 CK_RV
1719 object_mgr_set_attribute_values(SESSION	   * sess,
1720 	CK_OBJECT_HANDLE    handle,
1721 	CK_ATTRIBUTE	* pTemplate,
1722 	CK_ULONG	    ulCount)
1723 {
1724 	OBJECT    * obj;
1725 	CK_BBOOL    sess_obj, priv_obj;
1726 	CK_BBOOL    modifiable;
1727 	CK_RV	rc;
1728 
1729 	if (! pTemplate) {
1730 		return (CKR_FUNCTION_FAILED);
1731 	}
1732 	rc = pthread_mutex_lock(&obj_list_mutex);
1733 	if (rc != CKR_OK)
1734 		return (CKR_FUNCTION_FAILED);
1735 
1736 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
1737 	if (rc != CKR_OK) {
1738 		(void) pthread_mutex_unlock(&obj_list_mutex);
1739 		return (CKR_OBJECT_HANDLE_INVALID);
1740 	}
1741 	(void) pthread_mutex_unlock(&obj_list_mutex);
1742 
1743 	modifiable = object_is_modifiable(obj);
1744 	sess_obj   = object_is_session_object(obj);
1745 	priv_obj   = object_is_private(obj);
1746 
1747 	if (! modifiable) {
1748 		return (CKR_ATTRIBUTE_READ_ONLY);
1749 	}
1750 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
1751 		if (priv_obj) {
1752 			return (CKR_USER_NOT_LOGGED_IN);
1753 		}
1754 		if (! sess_obj) {
1755 			return (CKR_SESSION_READ_ONLY);
1756 		}
1757 	}
1758 
1759 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
1760 		if (! sess_obj) {
1761 			return (CKR_SESSION_READ_ONLY);
1762 		}
1763 	}
1764 
1765 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
1766 		if (priv_obj) {
1767 			return (CKR_USER_NOT_LOGGED_IN);
1768 		}
1769 	}
1770 
1771 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
1772 		if (priv_obj) {
1773 			return (CKR_USER_NOT_LOGGED_IN);
1774 		}
1775 	}
1776 
1777 	rc = object_set_attribute_values(obj, pTemplate, ulCount);
1778 	if (rc != CKR_OK) {
1779 		return (rc);
1780 	}
1781 	if (! sess_obj) {
1782 		TOK_OBJ_ENTRY  *entry = NULL;
1783 		CK_ULONG	index;
1784 
1785 		obj->count_lo++;
1786 		if (obj->count_lo == 0)
1787 			obj->count_hi++;
1788 
1789 		rc = save_token_object(sess->hContext, obj);
1790 		if (rc != CKR_OK)
1791 			return (rc);
1792 
1793 		rc = XProcLock(xproclock);
1794 		if (rc != CKR_OK) {
1795 			return (rc);
1796 		}
1797 		if (priv_obj) {
1798 			rc = object_mgr_search_shm_for_obj(
1799 			    global_shm->priv_tok_objs,
1800 			    0, global_shm->num_priv_tok_obj - 1,
1801 			    obj, &index);
1802 
1803 			if (rc != CKR_OK) {
1804 				(void) XProcUnLock(xproclock);
1805 				return (rc);
1806 			}
1807 
1808 			entry = &global_shm->priv_tok_objs[index];
1809 		} else {
1810 			rc = object_mgr_search_shm_for_obj(
1811 			    global_shm->publ_tok_objs,
1812 			    0, global_shm->num_publ_tok_obj - 1,
1813 			    obj, &index);
1814 			if (rc != CKR_OK) {
1815 				(void) XProcUnLock(xproclock);
1816 				return (rc);
1817 			}
1818 
1819 			entry = &global_shm->publ_tok_objs[index];
1820 		}
1821 
1822 		entry->count_lo = obj->count_lo;
1823 		entry->count_hi = obj->count_hi;
1824 
1825 		(void) XProcUnLock(xproclock);
1826 	}
1827 
1828 	return (rc);
1829 }
1830 
1831 CK_RV
1832 object_mgr_add_to_shm(OBJECT *obj)
1833 {
1834 	TOK_OBJ_ENTRY  * entry  = NULL;
1835 	CK_BBOOL	 priv;
1836 
1837 	priv = object_is_private(obj);
1838 
1839 	if (priv)
1840 		entry = &global_shm->priv_tok_objs[
1841 		    global_shm->num_priv_tok_obj];
1842 	else
1843 		entry = &global_shm->publ_tok_objs[
1844 		    global_shm->num_publ_tok_obj];
1845 
1846 	entry->deleted  = FALSE;
1847 	entry->count_lo = 0;
1848 	entry->count_hi = 0;
1849 	(void) memcpy(entry->name, obj->name, 8);
1850 
1851 	if (priv) {
1852 		global_shm->num_priv_tok_obj++;
1853 	} else {
1854 		global_shm->num_publ_tok_obj++;
1855 	}
1856 
1857 	return (CKR_OK);
1858 }
1859 
1860 CK_RV
1861 object_mgr_del_from_shm(OBJECT *obj)
1862 {
1863 	CK_ULONG	  index, count;
1864 	CK_BBOOL	  priv;
1865 	CK_RV		rc;
1866 
1867 	priv = object_is_private(obj);
1868 
1869 	if (priv) {
1870 		rc = object_mgr_search_shm_for_obj(global_shm->priv_tok_objs,
1871 		    0, global_shm->num_priv_tok_obj - 1, obj, &index);
1872 		if (rc != CKR_OK) {
1873 			return (CKR_FUNCTION_FAILED);
1874 		}
1875 
1876 		global_shm->num_priv_tok_obj--;
1877 		if (index > global_shm->num_priv_tok_obj) {
1878 			count = index - global_shm->num_priv_tok_obj;
1879 		} else {
1880 			count = global_shm->num_priv_tok_obj - index;
1881 		}
1882 
1883 		if (count > 0) {
1884 			(void) memcpy((char *)&global_shm->priv_tok_objs[index],
1885 			    (char *)&global_shm->priv_tok_objs[index + 1],
1886 			    sizeof (TOK_OBJ_ENTRY) * count);
1887 
1888 			(void) memset((char *)&global_shm->priv_tok_objs[
1889 			    global_shm->num_priv_tok_obj + 1], 0,
1890 			    sizeof (TOK_OBJ_ENTRY));
1891 		} else {
1892 			(void) memset((char *)&global_shm->priv_tok_objs[
1893 			    global_shm->num_priv_tok_obj], 0,
1894 			    sizeof (TOK_OBJ_ENTRY));
1895 		}
1896 	} else {
1897 		rc = object_mgr_search_shm_for_obj(global_shm->publ_tok_objs,
1898 		    0, global_shm->num_publ_tok_obj - 1, obj, &index);
1899 		if (rc != CKR_OK) {
1900 			return (CKR_FUNCTION_FAILED);
1901 		}
1902 		global_shm->num_publ_tok_obj--;
1903 
1904 		if (index > global_shm->num_publ_tok_obj) {
1905 			count = index - global_shm->num_publ_tok_obj;
1906 		} else {
1907 			count = global_shm->num_publ_tok_obj - index;
1908 		}
1909 
1910 		if (count > 0) {
1911 			(void) memcpy((char *)&global_shm->publ_tok_objs[index],
1912 			    (char *)&global_shm->publ_tok_objs[index + 1],
1913 			    sizeof (TOK_OBJ_ENTRY) * count);
1914 			(void) memset((char *)&global_shm->publ_tok_objs[
1915 			    global_shm->num_publ_tok_obj + 1], 0,
1916 			    sizeof (TOK_OBJ_ENTRY));
1917 		} else {
1918 			(void) memset((char *)&global_shm->publ_tok_objs[
1919 			    global_shm->num_publ_tok_obj], 0,
1920 			    sizeof (TOK_OBJ_ENTRY));
1921 		}
1922 	}
1923 
1924 	return (CKR_OK);
1925 }
1926 
1927 static CK_RV
1928 object_mgr_check_shm(TSS_HCONTEXT hContext, OBJECT *obj)
1929 {
1930 	TOK_OBJ_ENTRY   * entry = NULL;
1931 	CK_BBOOL	  priv;
1932 	CK_ULONG	  index;
1933 	CK_RV		rc;
1934 
1935 
1936 	priv = object_is_private(obj);
1937 
1938 	if (priv) {
1939 		rc = object_mgr_search_shm_for_obj(
1940 		    global_shm->priv_tok_objs,
1941 		    0, global_shm->num_priv_tok_obj - 1, obj, &index);
1942 		if (rc != CKR_OK) {
1943 			return (CKR_FUNCTION_FAILED);
1944 		}
1945 		entry = &global_shm->priv_tok_objs[index];
1946 	} else {
1947 		rc = object_mgr_search_shm_for_obj(
1948 		    global_shm->publ_tok_objs,
1949 		    0, global_shm->num_publ_tok_obj - 1, obj, &index);
1950 		if (rc != CKR_OK) {
1951 			return (CKR_FUNCTION_FAILED);
1952 		}
1953 		entry = &global_shm->publ_tok_objs[index];
1954 	}
1955 
1956 	if ((obj->count_hi == entry->count_hi) &&
1957 	    (obj->count_lo == entry->count_lo))
1958 		return (CKR_OK);
1959 	rc = reload_token_object(hContext, obj);
1960 	return (rc);
1961 }
1962 
1963 /*ARGSUSED*/
1964 static CK_RV
1965 object_mgr_search_shm_for_obj(
1966 	TOK_OBJ_ENTRY *obj_list,
1967 	CK_ULONG lo,
1968 	CK_ULONG hi,
1969 	OBJECT *obj,
1970 	CK_ULONG *index)
1971 {
1972 	CK_ULONG idx;
1973 	if (obj->index == 0) {
1974 		for (idx = lo; idx <= hi; idx++) {
1975 			if (memcmp(obj->name, obj_list[idx].name, 8) == 0) {
1976 				*index = idx;
1977 				obj->index = idx;
1978 				return (CKR_OK);
1979 			}
1980 		}
1981 	} else {
1982 		if (memcmp(obj->name, obj_list[obj->index].name, 8) == 0) {
1983 			*index = obj->index;
1984 			return (CKR_OK);
1985 		} else {
1986 			for (idx = lo; idx <= hi; idx++) {
1987 				if (memcmp(obj->name,
1988 				    obj_list[idx].name, 8) == 0) {
1989 					*index = idx;
1990 					obj->index = idx;
1991 					return (CKR_OK);
1992 				}
1993 			}
1994 		}
1995 	}
1996 	return (CKR_FUNCTION_FAILED);
1997 }
1998 
1999 static CK_RV
2000 object_mgr_update_publ_tok_obj_from_shm(TSS_HCONTEXT hContext)
2001 {
2002 	DL_NODE	   * node = NULL;
2003 	DL_NODE	   * next = NULL;
2004 	TOK_OBJ_ENTRY	* te   = NULL;
2005 	OBJECT	    * obj  = NULL;
2006 	CK_OBJECT_HANDLE    handle;
2007 	CK_ULONG	    index;
2008 	int		 val;
2009 	CK_RV		rc;
2010 
2011 	node  = publ_token_obj_list;
2012 	index = 0;
2013 
2014 	while ((node != NULL) && (index < global_shm->num_publ_tok_obj)) {
2015 		te = &global_shm->publ_tok_objs[index];
2016 		obj = (OBJECT *)node->data;
2017 
2018 		val = memcmp(obj->name, te->name, 8);
2019 
2020 		// 3 cases:
2021 		//    1) object in local list but not in the global list,
2022 		//	need to remove from local list
2023 		//    2) object in both lists, need to compare counters
2024 		//	and update as needed
2025 		//    3) object in global list but not in the local list,
2026 		//	need to add the object here.
2027 		//
2028 		if (val < 0) {
2029 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2030 			if (rc == CKR_OK) {
2031 				(void) object_mgr_remove_from_map(handle);
2032 			}
2033 			(void) object_free(obj);
2034 
2035 			next = node->next;
2036 			publ_token_obj_list = dlist_remove_node(
2037 			    publ_token_obj_list, node);
2038 
2039 		} else if (val == 0) {
2040 			if ((te->count_hi != obj->count_hi) ||
2041 			    (te->count_lo != obj->count_lo)) {
2042 				(void) reload_token_object(hContext, obj);
2043 				obj->count_hi = te->count_hi;
2044 				obj->count_lo = te->count_lo;
2045 			}
2046 
2047 			next = node->next;
2048 			index++;
2049 		} else {
2050 			DL_NODE  *new_node = NULL;
2051 			OBJECT   *new_obj  = NULL;
2052 
2053 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2054 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2055 
2056 			(void) memcpy(new_obj->name, te->name, 8);
2057 			(void) reload_token_object(hContext, new_obj);
2058 
2059 			new_node = (DL_NODE *)malloc(sizeof (DL_NODE));
2060 			new_node->data = new_obj;
2061 
2062 			new_node->next = node->next;
2063 			node->next	= new_node;
2064 			new_node->prev = node;
2065 
2066 			next = new_node->next;
2067 			index++;
2068 		}
2069 
2070 		node = next;
2071 	}
2072 
2073 	if ((node == NULL) && (index < global_shm->num_publ_tok_obj)) {
2074 		OBJECT   *new_obj  = NULL;
2075 		unsigned int i;
2076 
2077 		for (i = index; i < global_shm->num_publ_tok_obj; i++) {
2078 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2079 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2080 
2081 			te = &global_shm->publ_tok_objs[index];
2082 
2083 			(void) memcpy(new_obj->name, te->name, 8);
2084 			(void) reload_token_object(hContext, new_obj);
2085 
2086 			publ_token_obj_list = dlist_add_as_last(
2087 			    publ_token_obj_list, new_obj);
2088 		}
2089 	} else if ((node != NULL) && (index >= global_shm->num_publ_tok_obj)) {
2090 		while (node) {
2091 			obj = (OBJECT *)node->data;
2092 
2093 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2094 			if (rc == CKR_OK) {
2095 				(void) object_mgr_remove_from_map(handle);
2096 			}
2097 			(void) object_free(obj);
2098 
2099 			next = node->next;
2100 			publ_token_obj_list = dlist_remove_node(
2101 			    publ_token_obj_list, node);
2102 
2103 			node = next;
2104 		}
2105 	}
2106 
2107 	return (CKR_OK);
2108 }
2109 
2110 static CK_RV
2111 object_mgr_update_priv_tok_obj_from_shm(TSS_HCONTEXT hContext)
2112 {
2113 	DL_NODE	   * node = NULL;
2114 	DL_NODE	   * next = NULL;
2115 	TOK_OBJ_ENTRY	* te   = NULL;
2116 	OBJECT	    * obj  = NULL;
2117 	CK_OBJECT_HANDLE    handle;
2118 	CK_ULONG	    index;
2119 	int		 val;
2120 	CK_RV		rc;
2121 
2122 	node  = priv_token_obj_list;
2123 	index = 0;
2124 
2125 	if (! (global_login_state == CKS_RW_USER_FUNCTIONS ||
2126 	    global_login_state == CKS_RO_USER_FUNCTIONS)) {
2127 		return (CKR_OK);
2128 	}
2129 
2130 	while ((node != NULL) && (index < global_shm->num_priv_tok_obj)) {
2131 		te = &global_shm->priv_tok_objs[index];
2132 		obj = (OBJECT *)node->data;
2133 
2134 		val = memcmp(obj->name, te->name, 8);
2135 
2136 		if (val < 0) {
2137 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2138 			if (rc == CKR_OK) {
2139 				(void) object_mgr_remove_from_map(handle);
2140 			}
2141 			(void) object_free(obj);
2142 
2143 			next = node->next;
2144 			priv_token_obj_list = dlist_remove_node(
2145 			    priv_token_obj_list, node);
2146 
2147 		} else if (val == 0) {
2148 			if ((te->count_hi != obj->count_hi) ||
2149 			    (te->count_lo != obj->count_lo)) {
2150 				(void) reload_token_object(hContext, obj);
2151 				obj->count_hi = te->count_hi;
2152 				obj->count_lo = te->count_lo;
2153 			}
2154 
2155 			next = node->next;
2156 			index++;
2157 		} else {
2158 			DL_NODE  *new_node = NULL;
2159 			OBJECT   *new_obj  = NULL;
2160 
2161 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2162 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2163 
2164 			(void) memcpy(new_obj->name, te->name, 8);
2165 			(void) reload_token_object(hContext, new_obj);
2166 
2167 			new_node = (DL_NODE *)malloc(sizeof (DL_NODE));
2168 			new_node->data = new_obj;
2169 
2170 			new_node->next = node->next;
2171 			node->next	= new_node;
2172 			new_node->prev = node;
2173 
2174 			next = new_node->next;
2175 			index++;
2176 		}
2177 
2178 		node = next;
2179 	}
2180 
2181 	if ((node == NULL) && (index < global_shm->num_priv_tok_obj)) {
2182 		OBJECT   *new_obj  = NULL;
2183 		unsigned int i;
2184 
2185 		for (i = index; i < global_shm->num_priv_tok_obj; i++) {
2186 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2187 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2188 
2189 			te = &global_shm->priv_tok_objs[index];
2190 
2191 			(void) memcpy(new_obj->name, te->name, 8);
2192 			(void) reload_token_object(hContext, new_obj);
2193 
2194 			priv_token_obj_list = dlist_add_as_last(
2195 			    priv_token_obj_list, new_obj);
2196 		}
2197 	} else if ((node != NULL) && (index >= global_shm->num_priv_tok_obj)) {
2198 		while (node) {
2199 			obj = (OBJECT *)node->data;
2200 
2201 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2202 			if (rc == CKR_OK) {
2203 				(void) object_mgr_remove_from_map(handle);
2204 			}
2205 			(void) object_free(obj);
2206 
2207 			next = node->next;
2208 			priv_token_obj_list = dlist_remove_node(
2209 			    priv_token_obj_list, node);
2210 
2211 			node = next;
2212 		}
2213 	}
2214 
2215 	return (CKR_OK);
2216 }
2217 
2218 static CK_RV
2219 object_mgr_update_from_shm(TSS_HCONTEXT hContext)
2220 {
2221 	(void) object_mgr_update_publ_tok_obj_from_shm(hContext);
2222 	(void) object_mgr_update_priv_tok_obj_from_shm(hContext);
2223 
2224 	return (CKR_OK);
2225 }
2226 
2227 /*ARGSUSED*/
2228 CK_BBOOL
2229 object_mgr_purge_map(
2230 	SESSION	*sess,
2231 	SESS_OBJ_TYPE type)
2232 {
2233 	DL_NODE *node = NULL;
2234 	DL_NODE *next = NULL;
2235 
2236 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
2237 		return (CKR_FUNCTION_FAILED);
2238 	}
2239 	node = object_map;
2240 	while (node) {
2241 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
2242 		OBJECT	*obj = (OBJECT *)map->ptr;
2243 		next = node->next;
2244 		if (type == PRIVATE) {
2245 			if (object_is_private(obj)) {
2246 				object_map = dlist_remove_node(
2247 				    object_map, node);
2248 				free(map);
2249 			}
2250 		}
2251 		if (type == PUBLIC) {
2252 			if (object_is_public(obj)) {
2253 				object_map = dlist_remove_node(
2254 				    object_map, node);
2255 				free(map);
2256 			}
2257 		}
2258 		node = next;
2259 	}
2260 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
2261 
2262 	return (TRUE);
2263 }
2264