xref: /minix3/crypto/external/bsd/heimdal/dist/lib/kadm5/get_s.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: get_s.c,v 1.1.1.2 2014/04/24 12:45:48 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc  * are met:
11ebfedea0SLionel Sambuc  *
12ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc  *
15ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc  *
19ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc  *    without specific prior written permission.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc  * SUCH DAMAGE.
34ebfedea0SLionel Sambuc  */
35ebfedea0SLionel Sambuc 
36ebfedea0SLionel Sambuc #include "kadm5_locl.h"
37ebfedea0SLionel Sambuc 
38*0a6a1f1dSLionel Sambuc __RCSID("NetBSD");
39ebfedea0SLionel Sambuc 
40ebfedea0SLionel Sambuc static kadm5_ret_t
add_tl_data(kadm5_principal_ent_t ent,int16_t type,const void * data,size_t size)41ebfedea0SLionel Sambuc add_tl_data(kadm5_principal_ent_t ent, int16_t type,
42ebfedea0SLionel Sambuc 	    const void *data, size_t size)
43ebfedea0SLionel Sambuc {
44ebfedea0SLionel Sambuc     krb5_tl_data *tl;
45ebfedea0SLionel Sambuc 
46ebfedea0SLionel Sambuc     tl = calloc(1, sizeof(*tl));
47ebfedea0SLionel Sambuc     if (tl == NULL)
48ebfedea0SLionel Sambuc 	return _kadm5_error_code(ENOMEM);
49ebfedea0SLionel Sambuc 
50ebfedea0SLionel Sambuc     tl->tl_data_type = type;
51ebfedea0SLionel Sambuc     tl->tl_data_length = size;
52ebfedea0SLionel Sambuc     tl->tl_data_contents = malloc(size);
53ebfedea0SLionel Sambuc     if (tl->tl_data_contents == NULL && size != 0) {
54ebfedea0SLionel Sambuc 	free(tl);
55ebfedea0SLionel Sambuc 	return _kadm5_error_code(ENOMEM);
56ebfedea0SLionel Sambuc     }
57ebfedea0SLionel Sambuc     memcpy(tl->tl_data_contents, data, size);
58ebfedea0SLionel Sambuc 
59ebfedea0SLionel Sambuc     tl->tl_data_next = ent->tl_data;
60ebfedea0SLionel Sambuc     ent->tl_data = tl;
61ebfedea0SLionel Sambuc     ent->n_tl_data++;
62ebfedea0SLionel Sambuc 
63ebfedea0SLionel Sambuc     return 0;
64ebfedea0SLionel Sambuc }
65ebfedea0SLionel Sambuc 
66ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
67ebfedea0SLionel Sambuc _krb5_put_int(void *buffer, unsigned long value, size_t size); /* XXX */
68ebfedea0SLionel Sambuc 
69ebfedea0SLionel Sambuc kadm5_ret_t
kadm5_s_get_principal(void * server_handle,krb5_principal princ,kadm5_principal_ent_t out,uint32_t mask)70ebfedea0SLionel Sambuc kadm5_s_get_principal(void *server_handle,
71ebfedea0SLionel Sambuc 		      krb5_principal princ,
72ebfedea0SLionel Sambuc 		      kadm5_principal_ent_t out,
73ebfedea0SLionel Sambuc 		      uint32_t mask)
74ebfedea0SLionel Sambuc {
75ebfedea0SLionel Sambuc     kadm5_server_context *context = server_handle;
76ebfedea0SLionel Sambuc     kadm5_ret_t ret;
77ebfedea0SLionel Sambuc     hdb_entry_ex ent;
78ebfedea0SLionel Sambuc 
79ebfedea0SLionel Sambuc     memset(&ent, 0, sizeof(ent));
80ebfedea0SLionel Sambuc     ret = context->db->hdb_open(context->context, context->db, O_RDONLY, 0);
81ebfedea0SLionel Sambuc     if(ret)
82ebfedea0SLionel Sambuc 	return ret;
83ebfedea0SLionel Sambuc     ret = context->db->hdb_fetch_kvno(context->context, context->db, princ,
84ebfedea0SLionel Sambuc 				      HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent);
85ebfedea0SLionel Sambuc     context->db->hdb_close(context->context, context->db);
86ebfedea0SLionel Sambuc     if(ret)
87ebfedea0SLionel Sambuc 	return _kadm5_error_code(ret);
88ebfedea0SLionel Sambuc 
89ebfedea0SLionel Sambuc     memset(out, 0, sizeof(*out));
90ebfedea0SLionel Sambuc     if(mask & KADM5_PRINCIPAL)
91ebfedea0SLionel Sambuc 	ret  = krb5_copy_principal(context->context, ent.entry.principal,
92ebfedea0SLionel Sambuc 				   &out->principal);
93ebfedea0SLionel Sambuc     if(ret)
94ebfedea0SLionel Sambuc 	goto out;
95ebfedea0SLionel Sambuc     if(mask & KADM5_PRINC_EXPIRE_TIME && ent.entry.valid_end)
96ebfedea0SLionel Sambuc 	out->princ_expire_time = *ent.entry.valid_end;
97ebfedea0SLionel Sambuc     if(mask & KADM5_PW_EXPIRATION && ent.entry.pw_end)
98ebfedea0SLionel Sambuc 	out->pw_expiration = *ent.entry.pw_end;
99ebfedea0SLionel Sambuc     if(mask & KADM5_LAST_PWD_CHANGE)
100ebfedea0SLionel Sambuc 	hdb_entry_get_pw_change_time(&ent.entry, &out->last_pwd_change);
101ebfedea0SLionel Sambuc     if(mask & KADM5_ATTRIBUTES){
102ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.postdate ? 0 : KRB5_KDB_DISALLOW_POSTDATED;
103ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.forwardable ? 0 : KRB5_KDB_DISALLOW_FORWARDABLE;
104ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.initial ? KRB5_KDB_DISALLOW_TGT_BASED : 0;
105ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.renewable ? 0 : KRB5_KDB_DISALLOW_RENEWABLE;
106ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.proxiable ? 0 : KRB5_KDB_DISALLOW_PROXIABLE;
107ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.invalid ? KRB5_KDB_DISALLOW_ALL_TIX : 0;
108ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.require_preauth ? KRB5_KDB_REQUIRES_PRE_AUTH : 0;
109ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.server ? 0 : KRB5_KDB_DISALLOW_SVR;
110ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.change_pw ? KRB5_KDB_PWCHANGE_SERVICE : 0;
111ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.ok_as_delegate ? KRB5_KDB_OK_AS_DELEGATE : 0;
112ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.trusted_for_delegation ? KRB5_KDB_TRUSTED_FOR_DELEGATION : 0;
113ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.allow_kerberos4 ? KRB5_KDB_ALLOW_KERBEROS4 : 0;
114ebfedea0SLionel Sambuc 	out->attributes |= ent.entry.flags.allow_digest ? KRB5_KDB_ALLOW_DIGEST : 0;
115ebfedea0SLionel Sambuc     }
116ebfedea0SLionel Sambuc     if(mask & KADM5_MAX_LIFE) {
117ebfedea0SLionel Sambuc 	if(ent.entry.max_life)
118ebfedea0SLionel Sambuc 	    out->max_life = *ent.entry.max_life;
119ebfedea0SLionel Sambuc 	else
120ebfedea0SLionel Sambuc 	    out->max_life = INT_MAX;
121ebfedea0SLionel Sambuc     }
122ebfedea0SLionel Sambuc     if(mask & KADM5_MOD_TIME) {
123ebfedea0SLionel Sambuc 	if(ent.entry.modified_by)
124ebfedea0SLionel Sambuc 	    out->mod_date = ent.entry.modified_by->time;
125ebfedea0SLionel Sambuc 	else
126ebfedea0SLionel Sambuc 	    out->mod_date = ent.entry.created_by.time;
127ebfedea0SLionel Sambuc     }
128ebfedea0SLionel Sambuc     if(mask & KADM5_MOD_NAME) {
129ebfedea0SLionel Sambuc 	if(ent.entry.modified_by) {
130ebfedea0SLionel Sambuc 	    if (ent.entry.modified_by->principal != NULL)
131ebfedea0SLionel Sambuc 		ret = krb5_copy_principal(context->context,
132ebfedea0SLionel Sambuc 					  ent.entry.modified_by->principal,
133ebfedea0SLionel Sambuc 					  &out->mod_name);
134ebfedea0SLionel Sambuc 	} else if(ent.entry.created_by.principal != NULL)
135ebfedea0SLionel Sambuc 	    ret = krb5_copy_principal(context->context,
136ebfedea0SLionel Sambuc 				      ent.entry.created_by.principal,
137ebfedea0SLionel Sambuc 				      &out->mod_name);
138ebfedea0SLionel Sambuc 	else
139ebfedea0SLionel Sambuc 	    out->mod_name = NULL;
140ebfedea0SLionel Sambuc     }
141ebfedea0SLionel Sambuc     if(ret)
142ebfedea0SLionel Sambuc 	goto out;
143ebfedea0SLionel Sambuc 
144ebfedea0SLionel Sambuc     if(mask & KADM5_KVNO)
145ebfedea0SLionel Sambuc 	out->kvno = ent.entry.kvno;
146ebfedea0SLionel Sambuc     if(mask & KADM5_MKVNO) {
147*0a6a1f1dSLionel Sambuc 	size_t n;
148ebfedea0SLionel Sambuc 	out->mkvno = 0; /* XXX */
149ebfedea0SLionel Sambuc 	for(n = 0; n < ent.entry.keys.len; n++)
150ebfedea0SLionel Sambuc 	    if(ent.entry.keys.val[n].mkvno) {
151ebfedea0SLionel Sambuc 		out->mkvno = *ent.entry.keys.val[n].mkvno; /* XXX this isn't right */
152ebfedea0SLionel Sambuc 		break;
153ebfedea0SLionel Sambuc 	    }
154ebfedea0SLionel Sambuc     }
155ebfedea0SLionel Sambuc #if 0 /* XXX implement */
156ebfedea0SLionel Sambuc     if(mask & KADM5_AUX_ATTRIBUTES)
157ebfedea0SLionel Sambuc 	;
158ebfedea0SLionel Sambuc     if(mask & KADM5_LAST_SUCCESS)
159ebfedea0SLionel Sambuc 	;
160ebfedea0SLionel Sambuc     if(mask & KADM5_LAST_FAILED)
161ebfedea0SLionel Sambuc 	;
162ebfedea0SLionel Sambuc     if(mask & KADM5_FAIL_AUTH_COUNT)
163ebfedea0SLionel Sambuc 	;
164ebfedea0SLionel Sambuc #endif
165ebfedea0SLionel Sambuc     if(mask & KADM5_POLICY)
166ebfedea0SLionel Sambuc 	out->policy = NULL;
167ebfedea0SLionel Sambuc     if(mask & KADM5_MAX_RLIFE) {
168ebfedea0SLionel Sambuc 	if(ent.entry.max_renew)
169ebfedea0SLionel Sambuc 	    out->max_renewable_life = *ent.entry.max_renew;
170ebfedea0SLionel Sambuc 	else
171ebfedea0SLionel Sambuc 	    out->max_renewable_life = INT_MAX;
172ebfedea0SLionel Sambuc     }
173ebfedea0SLionel Sambuc     if(mask & KADM5_KEY_DATA){
174*0a6a1f1dSLionel Sambuc 	size_t i;
175ebfedea0SLionel Sambuc 	Key *key;
176ebfedea0SLionel Sambuc 	krb5_key_data *kd;
177ebfedea0SLionel Sambuc 	krb5_salt salt;
178ebfedea0SLionel Sambuc 	krb5_data *sp;
179ebfedea0SLionel Sambuc 	krb5_get_pw_salt(context->context, ent.entry.principal, &salt);
180ebfedea0SLionel Sambuc 	out->key_data = malloc(ent.entry.keys.len * sizeof(*out->key_data));
181ebfedea0SLionel Sambuc 	if (out->key_data == NULL && ent.entry.keys.len != 0) {
182ebfedea0SLionel Sambuc 	    ret = ENOMEM;
183ebfedea0SLionel Sambuc 	    goto out;
184ebfedea0SLionel Sambuc 	}
185ebfedea0SLionel Sambuc 	for(i = 0; i < ent.entry.keys.len; i++){
186ebfedea0SLionel Sambuc 	    key = &ent.entry.keys.val[i];
187ebfedea0SLionel Sambuc 	    kd = &out->key_data[i];
188ebfedea0SLionel Sambuc 	    kd->key_data_ver = 2;
189ebfedea0SLionel Sambuc 	    kd->key_data_kvno = ent.entry.kvno;
190ebfedea0SLionel Sambuc 	    kd->key_data_type[0] = key->key.keytype;
191ebfedea0SLionel Sambuc 	    if(key->salt)
192ebfedea0SLionel Sambuc 		kd->key_data_type[1] = key->salt->type;
193ebfedea0SLionel Sambuc 	    else
194ebfedea0SLionel Sambuc 		kd->key_data_type[1] = KRB5_PADATA_PW_SALT;
195ebfedea0SLionel Sambuc 	    /* setup key */
196ebfedea0SLionel Sambuc 	    kd->key_data_length[0] = key->key.keyvalue.length;
197ebfedea0SLionel Sambuc 	    kd->key_data_contents[0] = malloc(kd->key_data_length[0]);
198ebfedea0SLionel Sambuc 	    if(kd->key_data_contents[0] == NULL && kd->key_data_length[0] != 0){
199ebfedea0SLionel Sambuc 		ret = ENOMEM;
200ebfedea0SLionel Sambuc 		break;
201ebfedea0SLionel Sambuc 	    }
202ebfedea0SLionel Sambuc 	    memcpy(kd->key_data_contents[0], key->key.keyvalue.data,
203ebfedea0SLionel Sambuc 		   kd->key_data_length[0]);
204ebfedea0SLionel Sambuc 	    /* setup salt */
205ebfedea0SLionel Sambuc 	    if(key->salt)
206ebfedea0SLionel Sambuc 		sp = &key->salt->salt;
207ebfedea0SLionel Sambuc 	    else
208ebfedea0SLionel Sambuc 		sp = &salt.saltvalue;
209ebfedea0SLionel Sambuc 	    kd->key_data_length[1] = sp->length;
210ebfedea0SLionel Sambuc 	    kd->key_data_contents[1] = malloc(kd->key_data_length[1]);
211ebfedea0SLionel Sambuc 	    if(kd->key_data_length[1] != 0
212ebfedea0SLionel Sambuc 	       && kd->key_data_contents[1] == NULL) {
213ebfedea0SLionel Sambuc 		memset(kd->key_data_contents[0], 0, kd->key_data_length[0]);
214ebfedea0SLionel Sambuc 		ret = ENOMEM;
215ebfedea0SLionel Sambuc 		break;
216ebfedea0SLionel Sambuc 	    }
217ebfedea0SLionel Sambuc 	    memcpy(kd->key_data_contents[1], sp->data, kd->key_data_length[1]);
218ebfedea0SLionel Sambuc 	    out->n_key_data = i + 1;
219ebfedea0SLionel Sambuc 	}
220ebfedea0SLionel Sambuc 	krb5_free_salt(context->context, salt);
221ebfedea0SLionel Sambuc     }
222ebfedea0SLionel Sambuc     if(ret){
223ebfedea0SLionel Sambuc 	kadm5_free_principal_ent(context, out);
224ebfedea0SLionel Sambuc 	goto out;
225ebfedea0SLionel Sambuc     }
226ebfedea0SLionel Sambuc     if(mask & KADM5_TL_DATA) {
227ebfedea0SLionel Sambuc 	time_t last_pw_expire;
228ebfedea0SLionel Sambuc 	const HDB_Ext_PKINIT_acl *acl;
229ebfedea0SLionel Sambuc 	const HDB_Ext_Aliases *aliases;
230ebfedea0SLionel Sambuc 
231ebfedea0SLionel Sambuc 	ret = hdb_entry_get_pw_change_time(&ent.entry, &last_pw_expire);
232ebfedea0SLionel Sambuc 	if (ret == 0 && last_pw_expire) {
233ebfedea0SLionel Sambuc 	    unsigned char buf[4];
234ebfedea0SLionel Sambuc 	    _krb5_put_int(buf, last_pw_expire, sizeof(buf));
235ebfedea0SLionel Sambuc 	    ret = add_tl_data(out, KRB5_TL_LAST_PWD_CHANGE, buf, sizeof(buf));
236ebfedea0SLionel Sambuc 	}
237ebfedea0SLionel Sambuc 	if(ret){
238ebfedea0SLionel Sambuc 	    kadm5_free_principal_ent(context, out);
239ebfedea0SLionel Sambuc 	    goto out;
240ebfedea0SLionel Sambuc 	}
241ebfedea0SLionel Sambuc 	/*
242ebfedea0SLionel Sambuc 	 * If the client was allowed to get key data, let it have the
243ebfedea0SLionel Sambuc 	 * password too.
244ebfedea0SLionel Sambuc 	 */
245ebfedea0SLionel Sambuc 	if(mask & KADM5_KEY_DATA) {
246ebfedea0SLionel Sambuc 	    heim_utf8_string pw;
247ebfedea0SLionel Sambuc 
248ebfedea0SLionel Sambuc 	    ret = hdb_entry_get_password(context->context,
249ebfedea0SLionel Sambuc 					 context->db, &ent.entry, &pw);
250ebfedea0SLionel Sambuc 	    if (ret == 0) {
251ebfedea0SLionel Sambuc 		ret = add_tl_data(out, KRB5_TL_PASSWORD, pw, strlen(pw) + 1);
252ebfedea0SLionel Sambuc 		free(pw);
253ebfedea0SLionel Sambuc 	    }
254ebfedea0SLionel Sambuc 	    krb5_clear_error_message(context->context);
255ebfedea0SLionel Sambuc 	}
256ebfedea0SLionel Sambuc 
257ebfedea0SLionel Sambuc 	ret = hdb_entry_get_pkinit_acl(&ent.entry, &acl);
258ebfedea0SLionel Sambuc 	if (ret == 0 && acl) {
259ebfedea0SLionel Sambuc 	    krb5_data buf;
260ebfedea0SLionel Sambuc 	    size_t len;
261ebfedea0SLionel Sambuc 
262ebfedea0SLionel Sambuc 	    ASN1_MALLOC_ENCODE(HDB_Ext_PKINIT_acl, buf.data, buf.length,
263ebfedea0SLionel Sambuc 				acl, &len, ret);
264ebfedea0SLionel Sambuc 	    if (ret) {
265ebfedea0SLionel Sambuc 		kadm5_free_principal_ent(context, out);
266ebfedea0SLionel Sambuc 		goto out;
267ebfedea0SLionel Sambuc 	    }
268ebfedea0SLionel Sambuc 	    if (len != buf.length)
269ebfedea0SLionel Sambuc 		krb5_abortx(context->context,
270ebfedea0SLionel Sambuc 			    "internal ASN.1 encoder error");
271ebfedea0SLionel Sambuc 	    ret = add_tl_data(out, KRB5_TL_PKINIT_ACL, buf.data, buf.length);
272ebfedea0SLionel Sambuc 	    free(buf.data);
273ebfedea0SLionel Sambuc 	    if (ret) {
274ebfedea0SLionel Sambuc 		kadm5_free_principal_ent(context, out);
275ebfedea0SLionel Sambuc 		goto out;
276ebfedea0SLionel Sambuc 	    }
277ebfedea0SLionel Sambuc 	}
278ebfedea0SLionel Sambuc 	if(ret){
279ebfedea0SLionel Sambuc 	    kadm5_free_principal_ent(context, out);
280ebfedea0SLionel Sambuc 	    goto out;
281ebfedea0SLionel Sambuc 	}
282ebfedea0SLionel Sambuc 
283ebfedea0SLionel Sambuc 	ret = hdb_entry_get_aliases(&ent.entry, &aliases);
284ebfedea0SLionel Sambuc 	if (ret == 0 && aliases) {
285ebfedea0SLionel Sambuc 	    krb5_data buf;
286ebfedea0SLionel Sambuc 	    size_t len;
287ebfedea0SLionel Sambuc 
288ebfedea0SLionel Sambuc 	    ASN1_MALLOC_ENCODE(HDB_Ext_Aliases, buf.data, buf.length,
289ebfedea0SLionel Sambuc 			       aliases, &len, ret);
290ebfedea0SLionel Sambuc 	    if (ret) {
291ebfedea0SLionel Sambuc 		kadm5_free_principal_ent(context, out);
292ebfedea0SLionel Sambuc 		goto out;
293ebfedea0SLionel Sambuc 	    }
294ebfedea0SLionel Sambuc 	    if (len != buf.length)
295ebfedea0SLionel Sambuc 		krb5_abortx(context->context,
296ebfedea0SLionel Sambuc 			    "internal ASN.1 encoder error");
297ebfedea0SLionel Sambuc 	    ret = add_tl_data(out, KRB5_TL_ALIASES, buf.data, buf.length);
298ebfedea0SLionel Sambuc 	    free(buf.data);
299ebfedea0SLionel Sambuc 	    if (ret) {
300ebfedea0SLionel Sambuc 		kadm5_free_principal_ent(context, out);
301ebfedea0SLionel Sambuc 		goto out;
302ebfedea0SLionel Sambuc 	    }
303ebfedea0SLionel Sambuc 	}
304ebfedea0SLionel Sambuc 	if(ret){
305ebfedea0SLionel Sambuc 	    kadm5_free_principal_ent(context, out);
306ebfedea0SLionel Sambuc 	    goto out;
307ebfedea0SLionel Sambuc 	}
308ebfedea0SLionel Sambuc 
309ebfedea0SLionel Sambuc     }
310ebfedea0SLionel Sambuc out:
311ebfedea0SLionel Sambuc     hdb_free_entry(context->context, &ent);
312ebfedea0SLionel Sambuc 
313ebfedea0SLionel Sambuc     return _kadm5_error_code(ret);
314ebfedea0SLionel Sambuc }
315