1178825Sdfr/*
2178825Sdfr * Copyright (c) 2005, PADL Software Pty Ltd.
3178825Sdfr * All rights reserved.
4178825Sdfr *
5178825Sdfr * Redistribution and use in source and binary forms, with or without
6178825Sdfr * modification, are permitted provided that the following conditions
7178825Sdfr * are met:
8178825Sdfr *
9178825Sdfr * 1. Redistributions of source code must retain the above copyright
10178825Sdfr *    notice, this list of conditions and the following disclaimer.
11178825Sdfr *
12178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
13178825Sdfr *    notice, this list of conditions and the following disclaimer in the
14178825Sdfr *    documentation and/or other materials provided with the distribution.
15178825Sdfr *
16178825Sdfr * 3. Neither the name of PADL Software nor the names of its contributors
17178825Sdfr *    may be used to endorse or promote products derived from this software
18178825Sdfr *    without specific prior written permission.
19178825Sdfr *
20178825Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23178825Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30178825Sdfr * SUCH DAMAGE.
31178825Sdfr */
32178825Sdfr
33178825Sdfr#include "kcm_locl.h"
34178825Sdfr
35178825SdfrRCSID("$Id: cursor.c 17447 2006-05-05 10:52:01Z lha $");
36178825Sdfr
37178825Sdfrkrb5_error_code
38178825Sdfrkcm_cursor_new(krb5_context context,
39178825Sdfr	       pid_t pid,
40178825Sdfr	       kcm_ccache ccache,
41178825Sdfr	       uint32_t *cursor)
42178825Sdfr{
43178825Sdfr    kcm_cursor **p;
44178825Sdfr    krb5_error_code ret;
45178825Sdfr
46178825Sdfr    *cursor = 0;
47178825Sdfr
48178825Sdfr    KCM_ASSERT_VALID(ccache);
49178825Sdfr
50178825Sdfr    HEIMDAL_MUTEX_lock(&ccache->mutex);
51178825Sdfr    for (p = &ccache->cursors; *p != NULL; p = &(*p)->next)
52178825Sdfr	;
53178825Sdfr
54178825Sdfr    *p = (kcm_cursor *)malloc(sizeof(kcm_cursor));
55178825Sdfr    if (*p == NULL) {
56178825Sdfr	ret = KRB5_CC_NOMEM;
57178825Sdfr	goto out;
58178825Sdfr    }
59178825Sdfr
60178825Sdfr    (*p)->pid = pid;
61178825Sdfr    (*p)->key = ++ccache->n_cursor;
62178825Sdfr    (*p)->credp = ccache->creds;
63178825Sdfr    (*p)->next = NULL;
64178825Sdfr
65178825Sdfr    *cursor = (*p)->key;
66178825Sdfr
67178825Sdfr    ret = 0;
68178825Sdfr
69178825Sdfrout:
70178825Sdfr    HEIMDAL_MUTEX_unlock(&ccache->mutex);
71178825Sdfr
72178825Sdfr    return ret;
73178825Sdfr}
74178825Sdfr
75178825Sdfrkrb5_error_code
76178825Sdfrkcm_cursor_find(krb5_context context,
77178825Sdfr		pid_t pid,
78178825Sdfr		kcm_ccache ccache,
79178825Sdfr		uint32_t key,
80178825Sdfr		kcm_cursor **cursor)
81178825Sdfr{
82178825Sdfr    kcm_cursor *p;
83178825Sdfr    krb5_error_code ret;
84178825Sdfr
85178825Sdfr    KCM_ASSERT_VALID(ccache);
86178825Sdfr
87178825Sdfr    if (key == 0)
88178825Sdfr	return KRB5_CC_NOTFOUND;
89178825Sdfr
90178825Sdfr    ret = KRB5_CC_END;
91178825Sdfr
92178825Sdfr    HEIMDAL_MUTEX_lock(&ccache->mutex);
93178825Sdfr
94178825Sdfr    for (p = ccache->cursors; p != NULL; p = p->next) {
95178825Sdfr	if (p->key == key) {
96178825Sdfr	    if (p->pid != pid)
97178825Sdfr		ret = KRB5_FCC_PERM;
98178825Sdfr	    else
99178825Sdfr		ret = 0;
100178825Sdfr	    break;
101178825Sdfr	}
102178825Sdfr    }
103178825Sdfr
104178825Sdfr    if (ret == 0)
105178825Sdfr	*cursor = p;
106178825Sdfr
107178825Sdfr    HEIMDAL_MUTEX_unlock(&ccache->mutex);
108178825Sdfr
109178825Sdfr    return ret;
110178825Sdfr}
111178825Sdfr
112178825Sdfrkrb5_error_code
113178825Sdfrkcm_cursor_delete(krb5_context context,
114178825Sdfr	     	  pid_t pid,
115178825Sdfr		  kcm_ccache ccache,
116178825Sdfr		  uint32_t key)
117178825Sdfr{
118178825Sdfr    kcm_cursor **p;
119178825Sdfr    krb5_error_code ret;
120178825Sdfr
121178825Sdfr    KCM_ASSERT_VALID(ccache);
122178825Sdfr
123178825Sdfr    if (key == 0)
124178825Sdfr	return KRB5_CC_NOTFOUND;
125178825Sdfr
126178825Sdfr    ret = KRB5_CC_END;
127178825Sdfr
128178825Sdfr    HEIMDAL_MUTEX_lock(&ccache->mutex);
129178825Sdfr
130178825Sdfr    for (p = &ccache->cursors; *p != NULL; p = &(*p)->next) {
131178825Sdfr	if ((*p)->key == key) {
132178825Sdfr	    if ((*p)->pid != pid)
133178825Sdfr		ret = KRB5_FCC_PERM;
134178825Sdfr	    else
135178825Sdfr		ret = 0;
136178825Sdfr	    break;
137178825Sdfr	}
138178825Sdfr    }
139178825Sdfr
140178825Sdfr    if (ret == 0) {
141178825Sdfr	kcm_cursor *x = *p;
142178825Sdfr
143178825Sdfr	*p = x->next;
144178825Sdfr	free(x);
145178825Sdfr    }
146178825Sdfr
147178825Sdfr    HEIMDAL_MUTEX_unlock(&ccache->mutex);
148178825Sdfr
149178825Sdfr    return ret;
150178825Sdfr}
151178825Sdfr
152