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