*** empty log message ***
[heimdal.git] / kadmin / server.c
blob7212df5ff9b438287193d7f4d2ad3e7db6557b86
1 /*
2 * Copyright (c) 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #include "kadm5_locl.h"
41 RCSID("$Id$");
43 kadm5_ret_t
44 kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
46 kadm5_ret_t ret;
47 int32_t cmd, mask, tmp;
48 kadm5_server_context *context = kadm_handle;
49 char client[128], name[128], name2[128];
50 char *op = "";
51 krb5_principal princ, princ2;
52 kadm5_principal_ent_rec ent;
53 char *password, *exp;
54 krb5_keyblock *new_keys;
55 int n_keys;
56 char **princs;
57 int n_princs;
59 krb5_unparse_name_fixed(context->context, context->caller,
60 client, sizeof(client));
62 krb5_ret_int32(sp, &cmd);
63 switch(cmd){
64 case kadm_get:{
65 op = "GET";
66 ret = krb5_ret_principal(sp, &princ);
67 if(ret)
68 goto fail;
69 ret = krb5_ret_int32(sp, &mask);
70 if(ret){
71 krb5_free_principal(context->context, princ);
72 goto fail;
74 krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
75 krb5_warnx(context->context, "%s: %s %s", client, op, name);
76 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_GET);
77 if(ret){
78 krb5_free_principal(context->context, princ);
79 goto fail;
81 ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
82 sp->seek(sp, 0, SEEK_SET);
83 krb5_store_int32(sp, ret);
84 if(ret == 0){
85 kadm5_store_principal_ent(sp, &ent);
86 kadm5_free_principal_ent(kadm_handle, &ent);
88 krb5_free_principal(context->context, princ);
89 break;
91 case kadm_delete:{
92 op = "DELETE";
93 ret = krb5_ret_principal(sp, &princ);
94 if(ret)
95 goto fail;
96 krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
97 krb5_warnx(context->context, "%s: %s %s", client, op, name);
98 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_DELETE);
99 if(ret){
100 krb5_free_principal(context->context, princ);
101 goto fail;
103 ret = kadm5_delete_principal(kadm_handle, princ);
104 krb5_free_principal(context->context, princ);
105 sp->seek(sp, 0, SEEK_SET);
106 krb5_store_int32(sp, ret);
107 break;
109 case kadm_create:{
110 op = "CREATE";
111 ret = kadm5_ret_principal_ent(sp, &ent);
112 if(ret)
113 goto fail;
114 ret = krb5_ret_int32(sp, &mask);
115 if(ret){
116 kadm5_free_principal_ent(context->context, &ent);
117 goto fail;
119 ret = krb5_ret_string(sp, &password);
120 if(ret){
121 kadm5_free_principal_ent(context->context, &ent);
122 goto fail;
124 krb5_unparse_name_fixed(context->context, ent.principal,
125 name, sizeof(name));
126 krb5_warnx(context->context, "%s: %s %s", client, op, name);
127 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_ADD);
128 if(ret){
129 kadm5_free_principal_ent(context->context, &ent);
130 memset(password, 0, strlen(password));
131 free(password);
132 goto fail;
134 ret = kadm5_create_principal(kadm_handle, &ent,
135 mask, password);
136 kadm5_free_principal_ent(kadm_handle, &ent);
137 memset(password, 0, strlen(password));
138 free(password);
139 sp->seek(sp, 0, SEEK_SET);
140 krb5_store_int32(sp, ret);
141 break;
143 case kadm_modify:{
144 op = "MODIFY";
145 ret = kadm5_ret_principal_ent(sp, &ent);
146 if(ret)
147 goto fail;
148 ret = krb5_ret_int32(sp, &mask);
149 if(ret){
150 kadm5_free_principal_ent(context, &ent);
151 goto fail;
153 krb5_unparse_name_fixed(context->context, ent.principal,
154 name, sizeof(name));
155 krb5_warnx(context->context, "%s: %s %s", client, op, name);
156 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_MODIFY);
157 if(ret){
158 kadm5_free_principal_ent(context, &ent);
159 goto fail;
161 ret = kadm5_modify_principal(kadm_handle, &ent, mask);
162 kadm5_free_principal_ent(kadm_handle, &ent);
163 sp->seek(sp, 0, SEEK_SET);
164 krb5_store_int32(sp, ret);
165 break;
167 case kadm_rename:{
168 op = "RENAME";
169 ret = krb5_ret_principal(sp, &princ);
170 if(ret)
171 goto fail;
172 ret = krb5_ret_principal(sp, &princ2);
173 if(ret){
174 krb5_free_principal(context->context, princ);
175 goto fail;
177 krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
178 krb5_unparse_name_fixed(context->context, princ2, name2, sizeof(name2));
179 krb5_warnx(context->context, "%s: %s %s -> %s",
180 client, op, name, name2);
181 ret = _kadm5_acl_check_permission(context,
182 KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
183 if(ret){
184 krb5_free_principal(context->context, princ);
185 goto fail;
187 ret = kadm5_rename_principal(kadm_handle, princ, princ2);
188 krb5_free_principal(context->context, princ);
189 krb5_free_principal(context->context, princ2);
190 sp->seek(sp, 0, SEEK_SET);
191 krb5_store_int32(sp, ret);
192 break;
194 case kadm_chpass:{
195 op = "CHPASS";
196 ret = krb5_ret_principal(sp, &princ);
197 if(ret)
198 goto fail;
199 ret = krb5_ret_string(sp, &password);
200 if(ret){
201 krb5_free_principal(context->context, princ);
202 goto fail;
204 krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
205 krb5_warnx(context->context, "%s: %s %s", client, op, name);
206 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW);
207 if(ret){
208 krb5_free_principal(context->context, princ);
209 goto fail;
211 ret = kadm5_chpass_principal(kadm_handle, princ, password);
212 krb5_free_principal(context->context, princ);
213 memset(password, 0, strlen(password));
214 free(password);
215 sp->seek(sp, 0, SEEK_SET);
216 krb5_store_int32(sp, ret);
217 break;
219 case kadm_randkey:{
220 op = "RANDKEY";
221 ret = krb5_ret_principal(sp, &princ);
222 if(ret)
223 goto fail;
224 krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
225 krb5_warnx(context->context, "%s: %s %s", client, op, name);
226 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW);
227 if(ret){
228 krb5_free_principal(context->context, princ);
229 goto fail;
231 ret = kadm5_randkey_principal(kadm_handle, princ,
232 &new_keys, &n_keys);
233 krb5_free_principal(context->context, princ);
234 sp->seek(sp, 0, SEEK_SET);
235 krb5_store_int32(sp, ret);
236 if(ret == 0){
237 int i;
238 krb5_store_int32(sp, n_keys);
239 for(i = 0; i < n_keys; i++){
240 krb5_store_keyblock(sp, new_keys[i]);
241 krb5_free_keyblock_contents(context->context, &new_keys[i]);
244 break;
246 case kadm_get_privs:{
247 ret = kadm5_get_privs(kadm_handle, &mask);
248 sp->seek(sp, 0, SEEK_SET);
249 krb5_store_int32(sp, ret);
250 if(ret == 0)
251 krb5_store_int32(sp, mask);
252 break;
254 case kadm_get_princs:{
255 op = "LIST";
256 ret = krb5_ret_int32(sp, &tmp);
257 if(ret)
258 goto fail;
259 if(tmp){
260 ret = krb5_ret_string(sp, &exp);
261 if(ret)
262 goto fail;
263 }else
264 exp = NULL;
265 krb5_warnx(context->context, "%s: %s %s", client, op, exp ? exp : "*");
266 ret = _kadm5_acl_check_permission(context, KADM5_PRIV_LIST);
267 if(ret){
268 free(exp);
269 goto fail;
271 ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
272 free(exp);
273 sp->seek(sp, 0, SEEK_SET);
274 krb5_store_int32(sp, ret);
275 if(ret == 0){
276 int i;
277 krb5_store_int32(sp, n_princs);
278 for(i = 0; i < n_princs; i++)
279 krb5_store_string(sp, princs[i]);
280 kadm5_free_name_list(kadm_handle, princs, &n_princs);
282 break;
284 default:
285 krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
286 sp->seek(sp, 0, SEEK_SET);
287 krb5_store_int32(sp, KADM5_FAILURE);
288 break;
290 return 0;
291 fail:
292 krb5_warnx(context->context, "%s", op);
293 sp->seek(sp, 0, SEEK_SET);
294 krb5_store_int32(sp, ret);
295 return 0;