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
296pthread_rwlock_t obj_list_rw_mutex = PTHREAD_RWLOCK_INITIALIZER;
297
298static CK_RV
299object_mgr_search_shm_for_obj(TOK_OBJ_ENTRY *,
300	CK_ULONG, CK_ULONG, OBJECT *, CK_ULONG *);
301static CK_RV object_mgr_update_from_shm(TSS_HCONTEXT);
302static CK_RV object_mgr_check_shm(TSS_HCONTEXT, OBJECT *);
303
304static CK_RV
305check_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	}
356done:
357	return (rc);
358}
359
360CK_RV
361object_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
490done:
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
499CK_RV
500object_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//
541CK_RV
542object_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
671done:
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//
685CK_RV
686object_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
750CK_RV
751object_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
862done:
863	(void) pthread_mutex_unlock(&obj_list_mutex);
864
865	return (rc);
866}
867
868CK_RV
869object_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;
946done:
947	(void) pthread_mutex_unlock(&obj_list_mutex);
948
949	return (rc);
950}
951
952CK_RV
953object_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
1009done:
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//
1021CK_RV
1022object_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
1059CK_RV
1060object_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
1102CK_RV
1103object_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
1145CK_RV
1146object_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
1216CK_RV
1217object_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
1323CK_RV
1324object_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
1341CK_RV
1342object_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);
1373done:
1374	(void) pthread_mutex_unlock(&obj_list_mutex);
1375
1376	return (rc);
1377}
1378
1379CK_RV
1380object_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
1400done:
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//
1411CK_BBOOL
1412object_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//
1442CK_BBOOL
1443object_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//
1477CK_BBOOL
1478object_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//
1540CK_BBOOL
1541object_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
1595CK_BBOOL
1596object_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
1631CK_RV
1632object_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
1655CK_RV
1656object_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
1711CK_RV
1712object_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
1801CK_RV
1802object_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
1830CK_RV
1831object_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
1897static CK_RV
1898object_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*/
1934static CK_RV
1935object_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
1969static CK_RV
1970object_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
2080static CK_RV
2081object_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
2188static CK_RV
2189object_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*/
2198CK_BBOOL
2199object_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