155682Smarkm/*
2233294Sstas * Copyright (c) 1997 - 2007 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2055682Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
34233294Sstas/* $Id$ */
3555682Smarkm
3655682Smarkm#ifndef __HDB_H__
3755682Smarkm#define __HDB_H__
3855682Smarkm
39233294Sstas#include <krb5.h>
40233294Sstas
4155682Smarkm#include <hdb_err.h>
4255682Smarkm
43178825Sdfr#include <heim_asn1.h>
4455682Smarkm#include <hdb_asn1.h>
4555682Smarkm
46178825Sdfrstruct hdb_dbinfo;
47178825Sdfr
4855682Smarkmenum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
4955682Smarkm
5055682Smarkm/* flags for various functions */
51178825Sdfr#define HDB_F_DECRYPT		1	/* decrypt keys */
52178825Sdfr#define HDB_F_REPLACE		2	/* replace entry */
53178825Sdfr#define HDB_F_GET_CLIENT	4	/* fetch client */
54178825Sdfr#define HDB_F_GET_SERVER	8	/* fetch server */
55178825Sdfr#define HDB_F_GET_KRBTGT	16	/* fetch krbtgt */
56178825Sdfr#define HDB_F_GET_ANY		28	/* fetch any of client,server,krbtgt */
57178825Sdfr#define HDB_F_CANON		32	/* want canonicalition */
58233294Sstas#define HDB_F_ADMIN_DATA	64	/* want data that kdc don't use  */
59233294Sstas#define HDB_F_KVNO_SPECIFIED	128	/* we want a particular KVNO */
60233294Sstas#define HDB_F_CURRENT_KVNO	256	/* we want the current KVNO */
61233294Sstas/* 512, 1024, 2048 are reserved for kvno operations that is not part of the 1.5 branch */
62233294Sstas#define HDB_F_ALL_KVNOS		2048	/* we want all the keys, live or not */
63233294Sstas#define HDB_F_FOR_AS_REQ	4096	/* fetch is for a AS REQ */
64233294Sstas#define HDB_F_FOR_TGS_REQ	8192	/* fetch is for a TGS REQ */
6555682Smarkm
66233294Sstas/* hdb_capability_flags */
67233294Sstas#define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
68233294Sstas#define HDB_CAP_F_HANDLE_PASSWORDS	2
69233294Sstas#define HDB_CAP_F_PASSWORD_UPDATE_KEYS	4
70233294Sstas
71233294Sstas/* auth status values */
72233294Sstas#define HDB_AUTH_SUCCESS		0
73233294Sstas#define HDB_AUTH_WRONG_PASSWORD		1
74233294Sstas#define HDB_AUTH_INVALID_SIGNATURE	2
75233294Sstas
7672445Sassar/* key usage for master key */
7772445Sassar#define HDB_KU_MKEY	0x484442
7872445Sassar
7972445Sassartypedef struct hdb_master_key_data *hdb_master_key;
8072445Sassar
81233294Sstas/**
82233294Sstas * hdb_entry_ex is a wrapper structure around the hdb_entry structure
83233294Sstas * that allows backends to keep a pointer to the backing store, ie in
84233294Sstas * ->hdb_fetch_kvno(), so that we the kadmin/kpasswd backend gets around to
85233294Sstas * ->hdb_store(), the backend doesn't need to lookup the entry again.
86233294Sstas */
87233294Sstas
88178825Sdfrtypedef struct hdb_entry_ex {
89178825Sdfr    void *ctx;
90178825Sdfr    hdb_entry entry;
91178825Sdfr    void (*free_entry)(krb5_context, struct hdb_entry_ex *);
92178825Sdfr} hdb_entry_ex;
93178825Sdfr
94178825Sdfr
95233294Sstas/**
96233294Sstas * HDB backend function pointer structure
97233294Sstas *
98233294Sstas * The HDB structure is what the KDC and kadmind framework uses to
99233294Sstas * query the backend database when talking about principals.
100233294Sstas */
101233294Sstas
10255682Smarkmtypedef struct HDB{
103178825Sdfr    void *hdb_db;
104233294Sstas    void *hdb_dbc; /** don't use, only for DB3 */
105178825Sdfr    char *hdb_name;
106178825Sdfr    int hdb_master_key_set;
107178825Sdfr    hdb_master_key hdb_master_key;
108178825Sdfr    int hdb_openp;
109233294Sstas    int hdb_capability_flags;
110233294Sstas    /**
111233294Sstas     * Open (or create) the a Kerberos database.
112233294Sstas     *
113233294Sstas     * Open (or create) the a Kerberos database that was resolved with
114233294Sstas     * hdb_create(). The third and fourth flag to the function are the
115233294Sstas     * same as open(), thus passing O_CREAT will create the data base
116233294Sstas     * if it doesn't exists.
117233294Sstas     *
118233294Sstas     * Then done the caller should call hdb_close(), and to release
119233294Sstas     * all resources hdb_destroy().
120233294Sstas     */
121233294Sstas    krb5_error_code (*hdb_open)(krb5_context, struct HDB*, int, mode_t);
122233294Sstas    /**
123233294Sstas     * Close the database for transaction
124233294Sstas     *
125233294Sstas     * Closes the database for further transactions, wont release any
126233294Sstas     * permanant resources. the database can be ->hdb_open-ed again.
127233294Sstas     */
128233294Sstas    krb5_error_code (*hdb_close)(krb5_context, struct HDB*);
129233294Sstas    /**
130233294Sstas     * Free an entry after use.
131233294Sstas     */
132233294Sstas    void	    (*hdb_free)(krb5_context, struct HDB*, hdb_entry_ex*);
133233294Sstas    /**
134233294Sstas     * Fetch an entry from the backend
135233294Sstas     *
136233294Sstas     * Fetch an entry from the backend, flags are what type of entry
137233294Sstas     * should be fetch: client, server, krbtgt.
138233294Sstas     * knvo (if specified and flags HDB_F_KVNO_SPECIFIED set) is the kvno to get
139233294Sstas     */
140233294Sstas    krb5_error_code (*hdb_fetch_kvno)(krb5_context, struct HDB*,
141233294Sstas				      krb5_const_principal, unsigned, krb5_kvno,
142233294Sstas				      hdb_entry_ex*);
143233294Sstas    /**
144233294Sstas     * Store an entry to database
145233294Sstas     */
146233294Sstas    krb5_error_code (*hdb_store)(krb5_context, struct HDB*,
147233294Sstas				 unsigned, hdb_entry_ex*);
148233294Sstas    /**
149233294Sstas     * Remove an entry from the database.
150233294Sstas     */
151233294Sstas    krb5_error_code (*hdb_remove)(krb5_context, struct HDB*,
152233294Sstas				  krb5_const_principal);
153233294Sstas    /**
154233294Sstas     * As part of iteration, fetch one entry
155233294Sstas     */
156233294Sstas    krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*,
157233294Sstas				    unsigned, hdb_entry_ex*);
158233294Sstas    /**
159233294Sstas     * As part of iteration, fetch next entry
160233294Sstas     */
161233294Sstas    krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*,
162233294Sstas				   unsigned, hdb_entry_ex*);
163233294Sstas    /**
164233294Sstas     * Lock database
165233294Sstas     *
166233294Sstas     * A lock can only be held by one consumers. Transaction can still
167233294Sstas     * happen on the database while the lock is held, so the entry is
168233294Sstas     * only useful for syncroning creation of the database and renaming of the database.
169233294Sstas     */
170233294Sstas    krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int);
171233294Sstas    /**
172233294Sstas     * Unlock database
173233294Sstas     */
174233294Sstas    krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
175233294Sstas    /**
176233294Sstas     * Rename the data base.
177233294Sstas     *
178233294Sstas     * Assume that the database is not hdb_open'ed and not locked.
179233294Sstas     */
180233294Sstas    krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
181233294Sstas    /**
182233294Sstas     * Get an hdb_entry from a classical DB backend
183233294Sstas     *
184233294Sstas     * If the database is a classical DB (ie BDB, NDBM, GDBM, etc)
185233294Sstas     * backend, this function will take a principal key (krb5_data)
186233294Sstas     * and return all data related to principal in the return
187233294Sstas     * krb5_data. The returned encoded entry is of type hdb_entry or
188233294Sstas     * hdb_entry_alias.
189233294Sstas     */
190233294Sstas    krb5_error_code (*hdb__get)(krb5_context, struct HDB*,
191233294Sstas				krb5_data, krb5_data*);
192233294Sstas    /**
193233294Sstas     * Store an hdb_entry from a classical DB backend
194233294Sstas     *
195233294Sstas     * Same discussion as in @ref HDB::hdb__get
196233294Sstas     */
197233294Sstas    krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int,
198233294Sstas				krb5_data, krb5_data);
199233294Sstas    /**
200233294Sstas     * Delete and hdb_entry from a classical DB backend
201233294Sstas     *
202233294Sstas     * Same discussion as in @ref HDB::hdb__get
203233294Sstas     */
204233294Sstas    krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data);
205233294Sstas    /**
206233294Sstas     * Destroy the handle to the database.
207233294Sstas     *
208233294Sstas     * Destroy the handle to the database, deallocate all memory and
209233294Sstas     * related resources. Does not remove any permanent data. Its the
210233294Sstas     * logical reverse of hdb_create() function that is the entry
211233294Sstas     * point for the module.
212233294Sstas     */
213233294Sstas    krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
214233294Sstas    /**
215233294Sstas     * Get the list of realms this backend handles.
216233294Sstas     * This call is optional to support. The returned realms are used
217233294Sstas     * for announcing the realms over bonjour. Free returned array
218233294Sstas     * with krb5_free_host_realm().
219233294Sstas     */
220233294Sstas    krb5_error_code (*hdb_get_realms)(krb5_context, struct HDB *, krb5_realm **);
221233294Sstas    /**
222233294Sstas     * Change password.
223233294Sstas     *
224233294Sstas     * Will update keys for the entry when given password.  The new
225233294Sstas     * keys must be written into the entry and will then later be
226233294Sstas     * ->hdb_store() into the database. The backend will still perform
227233294Sstas     * all other operations, increasing the kvno, and update
228233294Sstas     * modification timestamp.
229233294Sstas     *
230233294Sstas     * The backend needs to call _kadm5_set_keys() and perform password
231233294Sstas     * quality checks.
232233294Sstas     */
233233294Sstas    krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int);
23455682Smarkm
235233294Sstas    /**
236233294Sstas     * Auth feedback
237233294Sstas     *
238233294Sstas     * This is a feedback call that allows backends that provides
239233294Sstas     * lockout functionality to register failure and/or successes.
240233294Sstas     *
241233294Sstas     * In case the entry is locked out, the backend should set the
242233294Sstas     * hdb_entry.flags.locked-out flag.
243233294Sstas     */
244233294Sstas    krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int);
245233294Sstas    /**
246233294Sstas     * Check if delegation is allowed.
247233294Sstas     */
248233294Sstas    krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
249233294Sstas
250233294Sstas    /**
251233294Sstas     * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins
252233294Sstas     */
253233294Sstas    krb5_error_code (*hdb_check_pkinit_ms_upn_match)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
254233294Sstas
255233294Sstas    /**
256233294Sstas     * Check if s4u2self is allowed from this client to this server
257233294Sstas     */
258233294Sstas    krb5_error_code (*hdb_check_s4u2self)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
25955682Smarkm}HDB;
26055682Smarkm
261233294Sstas#define HDB_INTERFACE_VERSION	7
26255682Smarkm
263178825Sdfrstruct hdb_so_method {
264178825Sdfr    int version;
265178825Sdfr    const char *prefix;
266178825Sdfr    krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
267178825Sdfr};
268178825Sdfr
26955682Smarkmtypedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*,
270178825Sdfr					      hdb_entry_ex*, void*);
27155682Smarkmextern krb5_kt_ops hdb_kt_ops;
27255682Smarkm
273233294Sstasstruct hdb_method {
274233294Sstas    int interface_version;
275233294Sstas    const char *prefix;
276233294Sstas    krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
277233294Sstas};
278233294Sstas
279233294Sstasextern const int hdb_interface_version;
280233294Sstas
28155682Smarkm#include <hdb-protos.h>
28255682Smarkm
28355682Smarkm#endif /* __HDB_H__ */
284