xref: /freebsd/crypto/heimdal/lib/hdb/hdb.h (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34*ae771770SStanislav Sedov /* $Id$ */
35b528cefcSMark Murray 
36b528cefcSMark Murray #ifndef __HDB_H__
37b528cefcSMark Murray #define __HDB_H__
38b528cefcSMark Murray 
39*ae771770SStanislav Sedov #include <krb5.h>
40*ae771770SStanislav Sedov 
41b528cefcSMark Murray #include <hdb_err.h>
42b528cefcSMark Murray 
43c19800e8SDoug Rabson #include <heim_asn1.h>
44b528cefcSMark Murray #include <hdb_asn1.h>
45b528cefcSMark Murray 
46c19800e8SDoug Rabson struct hdb_dbinfo;
47c19800e8SDoug Rabson 
48b528cefcSMark Murray enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
49b528cefcSMark Murray 
50b528cefcSMark Murray /* flags for various functions */
51b528cefcSMark Murray #define HDB_F_DECRYPT		1	/* decrypt keys */
52b528cefcSMark Murray #define HDB_F_REPLACE		2	/* replace entry */
53c19800e8SDoug Rabson #define HDB_F_GET_CLIENT	4	/* fetch client */
54c19800e8SDoug Rabson #define HDB_F_GET_SERVER	8	/* fetch server */
55c19800e8SDoug Rabson #define HDB_F_GET_KRBTGT	16	/* fetch krbtgt */
56c19800e8SDoug Rabson #define HDB_F_GET_ANY		28	/* fetch any of client,server,krbtgt */
57c19800e8SDoug Rabson #define HDB_F_CANON		32	/* want canonicalition */
58*ae771770SStanislav Sedov #define HDB_F_ADMIN_DATA	64	/* want data that kdc don't use  */
59*ae771770SStanislav Sedov #define HDB_F_KVNO_SPECIFIED	128	/* we want a particular KVNO */
60*ae771770SStanislav Sedov #define HDB_F_CURRENT_KVNO	256	/* we want the current KVNO */
61*ae771770SStanislav Sedov /* 512, 1024, 2048 are reserved for kvno operations that is not part of the 1.5 branch */
62*ae771770SStanislav Sedov #define HDB_F_ALL_KVNOS		2048	/* we want all the keys, live or not */
63*ae771770SStanislav Sedov #define HDB_F_FOR_AS_REQ	4096	/* fetch is for a AS REQ */
64*ae771770SStanislav Sedov #define HDB_F_FOR_TGS_REQ	8192	/* fetch is for a TGS REQ */
65*ae771770SStanislav Sedov 
66*ae771770SStanislav Sedov /* hdb_capability_flags */
67*ae771770SStanislav Sedov #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
68*ae771770SStanislav Sedov #define HDB_CAP_F_HANDLE_PASSWORDS	2
69*ae771770SStanislav Sedov #define HDB_CAP_F_PASSWORD_UPDATE_KEYS	4
70*ae771770SStanislav Sedov 
71*ae771770SStanislav Sedov /* auth status values */
72*ae771770SStanislav Sedov #define HDB_AUTH_SUCCESS		0
73*ae771770SStanislav Sedov #define HDB_AUTH_WRONG_PASSWORD		1
74*ae771770SStanislav Sedov #define HDB_AUTH_INVALID_SIGNATURE	2
75b528cefcSMark Murray 
765e9cd1aeSAssar Westerlund /* key usage for master key */
775e9cd1aeSAssar Westerlund #define HDB_KU_MKEY	0x484442
785e9cd1aeSAssar Westerlund 
795e9cd1aeSAssar Westerlund typedef struct hdb_master_key_data *hdb_master_key;
805e9cd1aeSAssar Westerlund 
81*ae771770SStanislav Sedov /**
82*ae771770SStanislav Sedov  * hdb_entry_ex is a wrapper structure around the hdb_entry structure
83*ae771770SStanislav Sedov  * that allows backends to keep a pointer to the backing store, ie in
84*ae771770SStanislav Sedov  * ->hdb_fetch_kvno(), so that we the kadmin/kpasswd backend gets around to
85*ae771770SStanislav Sedov  * ->hdb_store(), the backend doesn't need to lookup the entry again.
86*ae771770SStanislav Sedov  */
87*ae771770SStanislav Sedov 
88c19800e8SDoug Rabson typedef struct hdb_entry_ex {
89c19800e8SDoug Rabson     void *ctx;
90c19800e8SDoug Rabson     hdb_entry entry;
91c19800e8SDoug Rabson     void (*free_entry)(krb5_context, struct hdb_entry_ex *);
92c19800e8SDoug Rabson } hdb_entry_ex;
93b528cefcSMark Murray 
94c19800e8SDoug Rabson 
95*ae771770SStanislav Sedov /**
96*ae771770SStanislav Sedov  * HDB backend function pointer structure
97*ae771770SStanislav Sedov  *
98*ae771770SStanislav Sedov  * The HDB structure is what the KDC and kadmind framework uses to
99*ae771770SStanislav Sedov  * query the backend database when talking about principals.
100*ae771770SStanislav Sedov  */
101*ae771770SStanislav Sedov 
102c19800e8SDoug Rabson typedef struct HDB{
103c19800e8SDoug Rabson     void *hdb_db;
104*ae771770SStanislav Sedov     void *hdb_dbc; /** don't use, only for DB3 */
105c19800e8SDoug Rabson     char *hdb_name;
106c19800e8SDoug Rabson     int hdb_master_key_set;
107c19800e8SDoug Rabson     hdb_master_key hdb_master_key;
108c19800e8SDoug Rabson     int hdb_openp;
109*ae771770SStanislav Sedov     int hdb_capability_flags;
110*ae771770SStanislav Sedov     /**
111*ae771770SStanislav Sedov      * Open (or create) the a Kerberos database.
112*ae771770SStanislav Sedov      *
113*ae771770SStanislav Sedov      * Open (or create) the a Kerberos database that was resolved with
114*ae771770SStanislav Sedov      * hdb_create(). The third and fourth flag to the function are the
115*ae771770SStanislav Sedov      * same as open(), thus passing O_CREAT will create the data base
116*ae771770SStanislav Sedov      * if it doesn't exists.
117*ae771770SStanislav Sedov      *
118*ae771770SStanislav Sedov      * Then done the caller should call hdb_close(), and to release
119*ae771770SStanislav Sedov      * all resources hdb_destroy().
120*ae771770SStanislav Sedov      */
121*ae771770SStanislav Sedov     krb5_error_code (*hdb_open)(krb5_context, struct HDB*, int, mode_t);
122*ae771770SStanislav Sedov     /**
123*ae771770SStanislav Sedov      * Close the database for transaction
124*ae771770SStanislav Sedov      *
125*ae771770SStanislav Sedov      * Closes the database for further transactions, wont release any
126*ae771770SStanislav Sedov      * permanant resources. the database can be ->hdb_open-ed again.
127*ae771770SStanislav Sedov      */
128*ae771770SStanislav Sedov     krb5_error_code (*hdb_close)(krb5_context, struct HDB*);
129*ae771770SStanislav Sedov     /**
130*ae771770SStanislav Sedov      * Free an entry after use.
131*ae771770SStanislav Sedov      */
132*ae771770SStanislav Sedov     void	    (*hdb_free)(krb5_context, struct HDB*, hdb_entry_ex*);
133*ae771770SStanislav Sedov     /**
134*ae771770SStanislav Sedov      * Fetch an entry from the backend
135*ae771770SStanislav Sedov      *
136*ae771770SStanislav Sedov      * Fetch an entry from the backend, flags are what type of entry
137*ae771770SStanislav Sedov      * should be fetch: client, server, krbtgt.
138*ae771770SStanislav Sedov      * knvo (if specified and flags HDB_F_KVNO_SPECIFIED set) is the kvno to get
139*ae771770SStanislav Sedov      */
140*ae771770SStanislav Sedov     krb5_error_code (*hdb_fetch_kvno)(krb5_context, struct HDB*,
141*ae771770SStanislav Sedov 				      krb5_const_principal, unsigned, krb5_kvno,
142c19800e8SDoug Rabson 				      hdb_entry_ex*);
143*ae771770SStanislav Sedov     /**
144*ae771770SStanislav Sedov      * Store an entry to database
145*ae771770SStanislav Sedov      */
146*ae771770SStanislav Sedov     krb5_error_code (*hdb_store)(krb5_context, struct HDB*,
147*ae771770SStanislav Sedov 				 unsigned, hdb_entry_ex*);
148*ae771770SStanislav Sedov     /**
149*ae771770SStanislav Sedov      * Remove an entry from the database.
150*ae771770SStanislav Sedov      */
151*ae771770SStanislav Sedov     krb5_error_code (*hdb_remove)(krb5_context, struct HDB*,
152c19800e8SDoug Rabson 				  krb5_const_principal);
153*ae771770SStanislav Sedov     /**
154*ae771770SStanislav Sedov      * As part of iteration, fetch one entry
155*ae771770SStanislav Sedov      */
156*ae771770SStanislav Sedov     krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*,
157*ae771770SStanislav Sedov 				    unsigned, hdb_entry_ex*);
158*ae771770SStanislav Sedov     /**
159*ae771770SStanislav Sedov      * As part of iteration, fetch next entry
160*ae771770SStanislav Sedov      */
161*ae771770SStanislav Sedov     krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*,
162*ae771770SStanislav Sedov 				   unsigned, hdb_entry_ex*);
163*ae771770SStanislav Sedov     /**
164*ae771770SStanislav Sedov      * Lock database
165*ae771770SStanislav Sedov      *
166*ae771770SStanislav Sedov      * A lock can only be held by one consumers. Transaction can still
167*ae771770SStanislav Sedov      * happen on the database while the lock is held, so the entry is
168*ae771770SStanislav Sedov      * only useful for syncroning creation of the database and renaming of the database.
169*ae771770SStanislav Sedov      */
170*ae771770SStanislav Sedov     krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int);
171*ae771770SStanislav Sedov     /**
172*ae771770SStanislav Sedov      * Unlock database
173*ae771770SStanislav Sedov      */
174*ae771770SStanislav Sedov     krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
175*ae771770SStanislav Sedov     /**
176*ae771770SStanislav Sedov      * Rename the data base.
177*ae771770SStanislav Sedov      *
178*ae771770SStanislav Sedov      * Assume that the database is not hdb_open'ed and not locked.
179*ae771770SStanislav Sedov      */
180*ae771770SStanislav Sedov     krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
181*ae771770SStanislav Sedov     /**
182*ae771770SStanislav Sedov      * Get an hdb_entry from a classical DB backend
183*ae771770SStanislav Sedov      *
184*ae771770SStanislav Sedov      * If the database is a classical DB (ie BDB, NDBM, GDBM, etc)
185*ae771770SStanislav Sedov      * backend, this function will take a principal key (krb5_data)
186*ae771770SStanislav Sedov      * and return all data related to principal in the return
187*ae771770SStanislav Sedov      * krb5_data. The returned encoded entry is of type hdb_entry or
188*ae771770SStanislav Sedov      * hdb_entry_alias.
189*ae771770SStanislav Sedov      */
190*ae771770SStanislav Sedov     krb5_error_code (*hdb__get)(krb5_context, struct HDB*,
191*ae771770SStanislav Sedov 				krb5_data, krb5_data*);
192*ae771770SStanislav Sedov     /**
193*ae771770SStanislav Sedov      * Store an hdb_entry from a classical DB backend
194*ae771770SStanislav Sedov      *
195*ae771770SStanislav Sedov      * Same discussion as in @ref HDB::hdb__get
196*ae771770SStanislav Sedov      */
197*ae771770SStanislav Sedov     krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int,
198*ae771770SStanislav Sedov 				krb5_data, krb5_data);
199*ae771770SStanislav Sedov     /**
200*ae771770SStanislav Sedov      * Delete and hdb_entry from a classical DB backend
201*ae771770SStanislav Sedov      *
202*ae771770SStanislav Sedov      * Same discussion as in @ref HDB::hdb__get
203*ae771770SStanislav Sedov      */
204*ae771770SStanislav Sedov     krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data);
205*ae771770SStanislav Sedov     /**
206*ae771770SStanislav Sedov      * Destroy the handle to the database.
207*ae771770SStanislav Sedov      *
208*ae771770SStanislav Sedov      * Destroy the handle to the database, deallocate all memory and
209*ae771770SStanislav Sedov      * related resources. Does not remove any permanent data. Its the
210*ae771770SStanislav Sedov      * logical reverse of hdb_create() function that is the entry
211*ae771770SStanislav Sedov      * point for the module.
212*ae771770SStanislav Sedov      */
213*ae771770SStanislav Sedov     krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
214*ae771770SStanislav Sedov     /**
215*ae771770SStanislav Sedov      * Get the list of realms this backend handles.
216*ae771770SStanislav Sedov      * This call is optional to support. The returned realms are used
217*ae771770SStanislav Sedov      * for announcing the realms over bonjour. Free returned array
218*ae771770SStanislav Sedov      * with krb5_free_host_realm().
219*ae771770SStanislav Sedov      */
220*ae771770SStanislav Sedov     krb5_error_code (*hdb_get_realms)(krb5_context, struct HDB *, krb5_realm **);
221*ae771770SStanislav Sedov     /**
222*ae771770SStanislav Sedov      * Change password.
223*ae771770SStanislav Sedov      *
224*ae771770SStanislav Sedov      * Will update keys for the entry when given password.  The new
225*ae771770SStanislav Sedov      * keys must be written into the entry and will then later be
226*ae771770SStanislav Sedov      * ->hdb_store() into the database. The backend will still perform
227*ae771770SStanislav Sedov      * all other operations, increasing the kvno, and update
228*ae771770SStanislav Sedov      * modification timestamp.
229*ae771770SStanislav Sedov      *
230*ae771770SStanislav Sedov      * The backend needs to call _kadm5_set_keys() and perform password
231*ae771770SStanislav Sedov      * quality checks.
232*ae771770SStanislav Sedov      */
233*ae771770SStanislav Sedov     krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int);
234*ae771770SStanislav Sedov 
235*ae771770SStanislav Sedov     /**
236*ae771770SStanislav Sedov      * Auth feedback
237*ae771770SStanislav Sedov      *
238*ae771770SStanislav Sedov      * This is a feedback call that allows backends that provides
239*ae771770SStanislav Sedov      * lockout functionality to register failure and/or successes.
240*ae771770SStanislav Sedov      *
241*ae771770SStanislav Sedov      * In case the entry is locked out, the backend should set the
242*ae771770SStanislav Sedov      * hdb_entry.flags.locked-out flag.
243*ae771770SStanislav Sedov      */
244*ae771770SStanislav Sedov     krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int);
245*ae771770SStanislav Sedov     /**
246*ae771770SStanislav Sedov      * Check if delegation is allowed.
247*ae771770SStanislav Sedov      */
248*ae771770SStanislav Sedov     krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
249*ae771770SStanislav Sedov 
250*ae771770SStanislav Sedov     /**
251*ae771770SStanislav Sedov      * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins
252*ae771770SStanislav Sedov      */
253*ae771770SStanislav Sedov     krb5_error_code (*hdb_check_pkinit_ms_upn_match)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
254*ae771770SStanislav Sedov 
255*ae771770SStanislav Sedov     /**
256*ae771770SStanislav Sedov      * Check if s4u2self is allowed from this client to this server
257*ae771770SStanislav Sedov      */
258*ae771770SStanislav Sedov     krb5_error_code (*hdb_check_s4u2self)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
259b528cefcSMark Murray }HDB;
260b528cefcSMark Murray 
261*ae771770SStanislav Sedov #define HDB_INTERFACE_VERSION	7
262c19800e8SDoug Rabson 
263c19800e8SDoug Rabson struct hdb_so_method {
264c19800e8SDoug Rabson     int version;
265c19800e8SDoug Rabson     const char *prefix;
266c19800e8SDoug Rabson     krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
267c19800e8SDoug Rabson };
268b528cefcSMark Murray 
269b528cefcSMark Murray typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*,
270c19800e8SDoug Rabson 					      hdb_entry_ex*, void*);
271b528cefcSMark Murray extern krb5_kt_ops hdb_kt_ops;
272b528cefcSMark Murray 
273*ae771770SStanislav Sedov struct hdb_method {
274*ae771770SStanislav Sedov     int interface_version;
275*ae771770SStanislav Sedov     const char *prefix;
276*ae771770SStanislav Sedov     krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
277*ae771770SStanislav Sedov };
278*ae771770SStanislav Sedov 
279*ae771770SStanislav Sedov extern const int hdb_interface_version;
280*ae771770SStanislav Sedov 
281b528cefcSMark Murray #include <hdb-protos.h>
282b528cefcSMark Murray 
283b528cefcSMark Murray #endif /* __HDB_H__ */
284