1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
4  *
5  * $Header$
6  */
7 
8 #include    <gssrpc/rpc.h>
9 #include    <kadm5/admin.h>
10 #include    <kadm5/kadm_rpc.h>
11 #ifdef HAVE_MEMORY_H
12 #include    <memory.h>
13 #endif
14 #include    <string.h>
15 #include    <errno.h>
16 #include    "client_internal.h"
17 
18 #ifdef DEBUG
19 #define eret() do { clnt_perror(handle->clnt, "null ret"); return KADM5_RPC_ERROR; } while (0)
20 #else
21 #define eret() do { return KADM5_RPC_ERROR; } while (0)
22 #endif
23 
24 kadm5_ret_t
kadm5_create_principal(void * server_handle,kadm5_principal_ent_t princ,long mask,char * pw)25 kadm5_create_principal(void *server_handle,
26                        kadm5_principal_ent_t princ, long mask,
27                        char *pw)
28 {
29     generic_ret         r = { 0, 0 };
30     cprinc_arg          arg;
31     kadm5_server_handle_t handle = server_handle;
32 
33     CHECK_HANDLE(server_handle);
34 
35     memset(&arg, 0, sizeof(arg));
36     arg.mask = mask;
37     arg.passwd = pw;
38     arg.api_version = handle->api_version;
39 
40     if(princ == NULL)
41         return EINVAL;
42 
43     memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
44     arg.rec.mod_name = NULL;
45 
46     if(!(mask & KADM5_POLICY))
47         arg.rec.policy = NULL;
48     if (! (mask & KADM5_KEY_DATA)) {
49         arg.rec.n_key_data = 0;
50         arg.rec.key_data = NULL;
51     }
52     if (! (mask & KADM5_TL_DATA)) {
53         arg.rec.n_tl_data = 0;
54         arg.rec.tl_data = NULL;
55     }
56 
57     if (create_principal_2(&arg, &r, handle->clnt))
58         eret();
59     return r.code;
60 }
61 
62 kadm5_ret_t
kadm5_create_principal_3(void * server_handle,kadm5_principal_ent_t princ,long mask,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,char * pw)63 kadm5_create_principal_3(void *server_handle,
64                          kadm5_principal_ent_t princ, long mask,
65                          int n_ks_tuple,
66                          krb5_key_salt_tuple *ks_tuple,
67                          char *pw)
68 {
69     generic_ret         r = { 0, 0 };
70     cprinc3_arg         arg;
71     kadm5_server_handle_t handle = server_handle;
72 
73     CHECK_HANDLE(server_handle);
74 
75     memset(&arg, 0, sizeof(arg));
76     arg.mask = mask;
77     arg.passwd = pw;
78     arg.api_version = handle->api_version;
79     arg.n_ks_tuple = n_ks_tuple;
80     arg.ks_tuple = ks_tuple;
81 
82     if(princ == NULL)
83         return EINVAL;
84 
85     memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
86     arg.rec.mod_name = NULL;
87 
88     if(!(mask & KADM5_POLICY))
89         arg.rec.policy = NULL;
90     if (! (mask & KADM5_KEY_DATA)) {
91         arg.rec.n_key_data = 0;
92         arg.rec.key_data = NULL;
93     }
94     if (! (mask & KADM5_TL_DATA)) {
95         arg.rec.n_tl_data = 0;
96         arg.rec.tl_data = NULL;
97     }
98 
99     if (create_principal3_2(&arg, &r, handle->clnt))
100         eret();
101     return r.code;
102 }
103 
104 kadm5_ret_t
kadm5_delete_principal(void * server_handle,krb5_principal principal)105 kadm5_delete_principal(void *server_handle, krb5_principal principal)
106 {
107     dprinc_arg          arg;
108     generic_ret         r = { 0, 0 };
109     kadm5_server_handle_t handle = server_handle;
110 
111     CHECK_HANDLE(server_handle);
112 
113     if(principal == NULL)
114         return EINVAL;
115     arg.princ = principal;
116     arg.api_version = handle->api_version;
117     if (delete_principal_2(&arg, &r, handle->clnt))
118         eret();
119     return r.code;
120 }
121 
122 kadm5_ret_t
kadm5_modify_principal(void * server_handle,kadm5_principal_ent_t princ,long mask)123 kadm5_modify_principal(void *server_handle,
124                        kadm5_principal_ent_t princ, long mask)
125 {
126     mprinc_arg          arg;
127     generic_ret         r = { 0, 0 };
128     kadm5_server_handle_t handle = server_handle;
129 
130     CHECK_HANDLE(server_handle);
131 
132     memset(&arg, 0, sizeof(arg));
133     arg.mask = mask;
134     arg.api_version = handle->api_version;
135     if(princ == NULL)
136         return EINVAL;
137     memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
138     if(!(mask & KADM5_POLICY))
139         arg.rec.policy = NULL;
140     if (! (mask & KADM5_KEY_DATA)) {
141         arg.rec.n_key_data = 0;
142         arg.rec.key_data = NULL;
143     }
144     if (! (mask & KADM5_TL_DATA)) {
145         arg.rec.n_tl_data = 0;
146         arg.rec.tl_data = NULL;
147     }
148 
149     arg.rec.mod_name = NULL;
150 
151     if (modify_principal_2(&arg, &r, handle->clnt))
152         eret();
153     return r.code;
154 }
155 
156 kadm5_ret_t
kadm5_get_principal(void * server_handle,krb5_principal princ,kadm5_principal_ent_t ent,long mask)157 kadm5_get_principal(void *server_handle,
158                     krb5_principal princ, kadm5_principal_ent_t ent,
159                     long mask)
160 {
161     gprinc_arg  arg;
162     gprinc_ret  r;
163     kadm5_server_handle_t handle = server_handle;
164 
165     CHECK_HANDLE(server_handle);
166 
167     if(princ == NULL)
168         return EINVAL;
169     arg.princ = princ;
170     arg.mask = mask;
171     arg.api_version = handle->api_version;
172     memset(&r, 0, sizeof(gprinc_ret));
173     if (get_principal_2(&arg, &r, handle->clnt))
174         eret();
175     if (r.code == 0)
176         memcpy(ent, &r.rec, sizeof(r.rec));
177 
178     return r.code;
179 }
180 
181 kadm5_ret_t
kadm5_get_principals(void * server_handle,char * exp,char *** princs,int * count)182 kadm5_get_principals(void *server_handle,
183                      char *exp, char ***princs, int *count)
184 {
185     gprincs_arg arg;
186     gprincs_ret r;
187     kadm5_server_handle_t handle = server_handle;
188 
189     CHECK_HANDLE(server_handle);
190 
191     if(princs == NULL || count == NULL)
192         return EINVAL;
193     arg.exp = exp;
194     arg.api_version = handle->api_version;
195     memset(&r, 0, sizeof(gprincs_ret));
196     if (get_princs_2(&arg, &r, handle->clnt))
197         eret();
198     if (r.code == 0) {
199         *count = r.count;
200         *princs = r.princs;
201     } else {
202         *count = 0;
203         *princs = NULL;
204     }
205 
206     return r.code;
207 }
208 
209 kadm5_ret_t
kadm5_rename_principal(void * server_handle,krb5_principal source,krb5_principal dest)210 kadm5_rename_principal(void *server_handle,
211                        krb5_principal source, krb5_principal dest)
212 {
213     rprinc_arg          arg;
214     generic_ret         r = { 0, 0 };
215     kadm5_server_handle_t handle = server_handle;
216 
217     CHECK_HANDLE(server_handle);
218 
219     arg.src = source;
220     arg.dest = dest;
221     arg.api_version = handle->api_version;
222     if (source == NULL || dest == NULL)
223         return EINVAL;
224     if (rename_principal_2(&arg, &r, handle->clnt))
225         eret();
226     return r.code;
227 }
228 
229 kadm5_ret_t
kadm5_chpass_principal(void * server_handle,krb5_principal princ,char * password)230 kadm5_chpass_principal(void *server_handle,
231                        krb5_principal princ, char *password)
232 {
233     chpass_arg          arg;
234     generic_ret         r = { 0, 0 };
235     kadm5_server_handle_t handle = server_handle;
236 
237     CHECK_HANDLE(server_handle);
238 
239     arg.princ = princ;
240     arg.pass = password;
241     arg.api_version = handle->api_version;
242 
243     if(princ == NULL)
244         return EINVAL;
245     if (chpass_principal_2(&arg, &r, handle->clnt))
246         eret();
247     return r.code;
248 }
249 
250 kadm5_ret_t
kadm5_chpass_principal_3(void * server_handle,krb5_principal princ,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,char * password)251 kadm5_chpass_principal_3(void *server_handle,
252                          krb5_principal princ, krb5_boolean keepold,
253                          int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
254                          char *password)
255 {
256     chpass3_arg         arg;
257     generic_ret         r = { 0, 0 };
258     kadm5_server_handle_t handle = server_handle;
259 
260     CHECK_HANDLE(server_handle);
261 
262     arg.princ = princ;
263     arg.pass = password;
264     arg.api_version = handle->api_version;
265     arg.keepold = keepold;
266     arg.n_ks_tuple = n_ks_tuple;
267     arg.ks_tuple = ks_tuple;
268 
269     if(princ == NULL)
270         return EINVAL;
271     if (chpass_principal3_2(&arg, &r, handle->clnt))
272         eret();
273     return r.code;
274 }
275 
276 kadm5_ret_t
kadm5_setkey_principal(void * server_handle,krb5_principal princ,krb5_keyblock * keyblocks,int n_keys)277 kadm5_setkey_principal(void *server_handle,
278                        krb5_principal princ,
279                        krb5_keyblock *keyblocks,
280                        int n_keys)
281 {
282     setkey_arg          arg;
283     generic_ret         r = { 0, 0 };
284     kadm5_server_handle_t handle = server_handle;
285 
286     CHECK_HANDLE(server_handle);
287 
288     arg.princ = princ;
289     arg.keyblocks = keyblocks;
290     arg.n_keys = n_keys;
291     arg.api_version = handle->api_version;
292 
293     if(princ == NULL || keyblocks == NULL)
294         return EINVAL;
295     if (setkey_principal_2(&arg, &r, handle->clnt))
296         eret();
297     return r.code;
298 }
299 
300 kadm5_ret_t
kadm5_setkey_principal_3(void * server_handle,krb5_principal princ,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,krb5_keyblock * keyblocks,int n_keys)301 kadm5_setkey_principal_3(void *server_handle,
302                          krb5_principal princ,
303                          krb5_boolean keepold, int n_ks_tuple,
304                          krb5_key_salt_tuple *ks_tuple,
305                          krb5_keyblock *keyblocks,
306                          int n_keys)
307 {
308     setkey3_arg         arg;
309     generic_ret         r = { 0, 0 };
310     kadm5_server_handle_t handle = server_handle;
311 
312     CHECK_HANDLE(server_handle);
313 
314     arg.princ = princ;
315     arg.keyblocks = keyblocks;
316     arg.n_keys = n_keys;
317     arg.api_version = handle->api_version;
318     arg.keepold = keepold;
319     arg.n_ks_tuple = n_ks_tuple;
320     arg.ks_tuple = ks_tuple;
321 
322     if(princ == NULL || keyblocks == NULL)
323         return EINVAL;
324     if (setkey_principal3_2(&arg, &r, handle->clnt))
325         eret();
326     return r.code;
327 }
328 
329 kadm5_ret_t
kadm5_setkey_principal_4(void * server_handle,krb5_principal princ,krb5_boolean keepold,kadm5_key_data * key_data,int n_key_data)330 kadm5_setkey_principal_4(void *server_handle,
331                          krb5_principal princ,
332                          krb5_boolean keepold,
333                          kadm5_key_data *key_data,
334                          int n_key_data)
335 {
336     setkey4_arg         arg;
337     generic_ret         r = { 0, 0 };
338     kadm5_server_handle_t handle = server_handle;
339 
340     CHECK_HANDLE(server_handle);
341 
342     arg.api_version = handle->api_version;
343     arg.princ = princ;
344     arg.keepold = keepold;
345     arg.key_data = key_data;
346     arg.n_key_data = n_key_data;
347 
348     if (princ == NULL || key_data == NULL || n_key_data == 0)
349         return EINVAL;
350     if (setkey_principal4_2(&arg, &r, handle->clnt))
351         eret();
352     return r.code;
353 }
354 
355 kadm5_ret_t
kadm5_randkey_principal_3(void * server_handle,krb5_principal princ,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,krb5_keyblock ** key,int * n_keys)356 kadm5_randkey_principal_3(void *server_handle,
357                           krb5_principal princ,
358                           krb5_boolean keepold, int n_ks_tuple,
359                           krb5_key_salt_tuple *ks_tuple,
360                           krb5_keyblock **key, int *n_keys)
361 {
362     chrand3_arg         arg;
363     chrand_ret          r;
364     kadm5_server_handle_t handle = server_handle;
365     int                 i;
366 
367     CHECK_HANDLE(server_handle);
368 
369     arg.princ = princ;
370     arg.api_version = handle->api_version;
371     arg.keepold = keepold;
372     arg.n_ks_tuple = n_ks_tuple;
373     arg.ks_tuple = ks_tuple;
374 
375     if(princ == NULL)
376         return EINVAL;
377     memset(&r, 0, sizeof(chrand_ret));
378     if (chrand_principal3_2(&arg, &r, handle->clnt))
379         eret();
380     if (n_keys)
381         *n_keys = r.n_keys;
382     if (key) {
383         *key = r.keys;
384     } else {
385         for (i = 0; i < r.n_keys; i++)
386             krb5_free_keyblock_contents(handle->context, &r.keys[i]);
387         free(r.keys);
388     }
389     return r.code;
390 }
391 
392 kadm5_ret_t
kadm5_randkey_principal(void * server_handle,krb5_principal princ,krb5_keyblock ** key,int * n_keys)393 kadm5_randkey_principal(void *server_handle,
394                         krb5_principal princ,
395                         krb5_keyblock **key, int *n_keys)
396 {
397     chrand_arg          arg;
398     chrand_ret          r;
399     kadm5_server_handle_t handle = server_handle;
400     int                 i;
401 
402     CHECK_HANDLE(server_handle);
403 
404     arg.princ = princ;
405     arg.api_version = handle->api_version;
406 
407     if(princ == NULL)
408         return EINVAL;
409     memset(&r, 0, sizeof(chrand_ret));
410     if (chrand_principal_2(&arg, &r, handle->clnt))
411         eret();
412     if (n_keys)
413         *n_keys = r.n_keys;
414     if (key) {
415         *key = r.keys;
416     } else {
417         for (i = 0; i < r.n_keys; i++)
418             krb5_free_keyblock_contents(handle->context, &r.keys[i]);
419         free(r.keys);
420     }
421     return r.code;
422 }
423 
424 /* not supported on client side */
kadm5_decrypt_key(void * server_handle,kadm5_principal_ent_t entry,krb5_int32 ktype,krb5_int32 stype,krb5_int32 kvno,krb5_keyblock * keyblock,krb5_keysalt * keysalt,int * kvnop)425 kadm5_ret_t kadm5_decrypt_key(void *server_handle,
426                               kadm5_principal_ent_t entry, krb5_int32
427                               ktype, krb5_int32 stype, krb5_int32
428                               kvno, krb5_keyblock *keyblock,
429                               krb5_keysalt *keysalt, int *kvnop)
430 {
431     return EINVAL;
432 }
433 
434 kadm5_ret_t
kadm5_purgekeys(void * server_handle,krb5_principal princ,int keepkvno)435 kadm5_purgekeys(void *server_handle,
436                 krb5_principal princ,
437                 int keepkvno)
438 {
439     purgekeys_arg       arg;
440     generic_ret         r = { 0, 0 };
441     kadm5_server_handle_t handle = server_handle;
442 
443     CHECK_HANDLE(server_handle);
444 
445     arg.princ = princ;
446     arg.keepkvno = keepkvno;
447     arg.api_version = handle->api_version;
448 
449     if (princ == NULL)
450         return EINVAL;
451     if (purgekeys_2(&arg, &r, handle->clnt))
452         eret();
453     return r.code;
454 }
455 
456 kadm5_ret_t
kadm5_get_strings(void * server_handle,krb5_principal principal,krb5_string_attr ** strings_out,int * count_out)457 kadm5_get_strings(void *server_handle, krb5_principal principal,
458                   krb5_string_attr **strings_out, int *count_out)
459 {
460     gstrings_arg arg;
461     gstrings_ret r;
462     kadm5_server_handle_t handle = server_handle;
463 
464     *strings_out = NULL;
465     *count_out = 0;
466     CHECK_HANDLE(server_handle);
467     if (principal == NULL)
468         return EINVAL;
469 
470     arg.princ = principal;
471     arg.api_version = handle->api_version;
472     memset(&r, 0, sizeof(gstrings_ret));
473     if (get_strings_2(&arg, &r, handle->clnt))
474         eret();
475     if (r.code == 0) {
476         *strings_out = r.strings;
477         *count_out = r.count;
478     }
479     return r.code;
480 }
481 
482 kadm5_ret_t
kadm5_set_string(void * server_handle,krb5_principal principal,const char * key,const char * value)483 kadm5_set_string(void *server_handle, krb5_principal principal,
484                  const char *key, const char *value)
485 {
486     sstring_arg arg;
487     generic_ret r = { 0, 0 };
488     kadm5_server_handle_t handle = server_handle;
489 
490     CHECK_HANDLE(server_handle);
491     if (principal == NULL || key == NULL)
492         return EINVAL;
493 
494     arg.princ = principal;
495     arg.key = (char *)key;
496     arg.value = (char *)value;
497     arg.api_version = handle->api_version;
498     if (set_string_2(&arg, &r, handle->clnt))
499         eret();
500     return r.code;
501 }
502 
503 kadm5_ret_t
kadm5_get_principal_keys(void * server_handle,krb5_principal princ,krb5_kvno kvno,kadm5_key_data ** key_data,int * n_key_data)504 kadm5_get_principal_keys(void *server_handle, krb5_principal princ,
505                          krb5_kvno kvno, kadm5_key_data **key_data,
506                          int *n_key_data)
507 {
508     getpkeys_arg        arg;
509     getpkeys_ret        r;
510     kadm5_server_handle_t handle = server_handle;
511 
512     CHECK_HANDLE(server_handle);
513 
514     arg.api_version = handle->api_version;
515     arg.princ = princ;
516     arg.kvno = kvno;
517 
518     if (princ == NULL || key_data == NULL || n_key_data == 0)
519         return EINVAL;
520     memset(&r, 0, sizeof(getpkeys_ret));
521     if (get_principal_keys_2(&arg, &r, handle->clnt))
522         eret();
523     if (r.code == 0) {
524         *key_data = r.key_data;
525         *n_key_data = r.n_key_data;
526     }
527     return r.code;
528 }
529