1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <jni.h>
27 #include <kadm5/admin.h>
28 #include <adm_err.h>
29 #include <sys/signal.h>
30 #include <netdb.h>
31 #include <iconv.h>
32 #include <langinfo.h>
33 #include <clnt/client_internal.h>
34 #include <etypes.h>
35
36 static int Principal_to_kadmin(JNIEnv *, jobject, int, krb5_principal *,
37 kadm5_principal_ent_rec *, long *, char **, char **,
38 kadm5_config_params *);
39 static int kadmin_to_Principal(kadm5_principal_ent_rec *, JNIEnv *, jobject,
40 const char *, char *);
41 static int Policy_to_kadmin(JNIEnv *, jobject, int, kadm5_policy_ent_rec *,
42 long *);
43 static int kadmin_to_Policy(kadm5_policy_ent_rec *, JNIEnv *, jobject);
44 static int edit_comments(kadm5_principal_ent_rec *, krb5_principal, char *);
45 static int format_comments(kadm5_principal_ent_rec *, long *, char *);
46 static int extract_comments(kadm5_principal_ent_rec *, char **);
47 static int set_password(krb5_principal, char *, kadm5_config_params *);
48 static void handle_error(JNIEnv *, int);
49 static char *qualify(char *name);
50
51 static void *server_handle = NULL;
52 static char *cur_realm = NULL;
53
54 static iconv_t cd = (iconv_t)-1;
55
56 static char *
qualify(char * name)57 qualify(char *name)
58 {
59 char *fullname;
60 int len;
61
62 if (strchr(name, '@') != NULL)
63 return (strdup(name));
64 len = strlen(name) + strlen(cur_realm) + 2;
65 fullname = malloc(len);
66 if (fullname)
67 snprintf(fullname, len, "%s@%s", name, cur_realm);
68 return (fullname);
69 }
70
71
72 /*
73 * Class: Kadmin
74 * Method: sessionInit
75 * Signature:
76 * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
77 */
78 /*ARGSUSED*/
79 JNIEXPORT jboolean JNICALL
Java_Kadmin_sessionInit(JNIEnv * env,jobject obj,jstring name,jstring passwd,jstring realm,jstring server,jint port)80 Java_Kadmin_sessionInit(JNIEnv *env, jobject obj, jstring name,
81 jstring passwd, jstring realm, jstring server, jint port)
82 {
83 const char *cname = NULL, *cpasswd = NULL;
84 const char *crealm = NULL, *cserver = NULL;
85 int cport = 749;
86 kadm5_config_params params;
87 kadm5_ret_t ret;
88 char *ka_service = NULL;
89 char *ka_name = NULL;
90 char *codeset;
91 int len;
92
93 if (server_handle != NULL)
94 kadm5_destroy(server_handle);
95
96 if (cd == (iconv_t)-1) {
97 codeset = nl_langinfo(CODESET);
98 /* fprintf(stderr, "codeset returned %s\n", codeset); XXX */
99 if (strcmp("UTF-8", codeset) != 0)
100 cd = iconv_open("UTF-8", codeset);
101 }
102
103 /* Get hold of string arguments */
104 cname = (*env)->GetStringUTFChars(env, name, NULL);
105 if (!cname) {
106 ret = KADM_JNI_STRING;
107 goto err;
108 }
109 cpasswd = (*env)->GetStringUTFChars(env, passwd, NULL);
110 if (!cpasswd) {
111 ret = KADM_JNI_STRING;
112 goto err;
113 }
114 crealm = (*env)->GetStringUTFChars(env, realm, NULL);
115 if (!crealm) {
116 ret = KADM_JNI_STRING;
117 goto err;
118 }
119 if (cur_realm)
120 free(cur_realm);
121 cur_realm = strdup(crealm);
122 cserver = (*env)->GetStringUTFChars(env, server, NULL);
123 if (!cserver) {
124 ret = KADM_JNI_STRING;
125 goto err;
126 }
127 if (port != 0)
128 cport = port;
129 else {
130 /*
131 * Look for a services map entry
132 * Note that this will be in network byte order,
133 * and that the API requires native byte order.
134 */
135 struct servent *rec = getservbyname("kerberos-adm", NULL);
136 if (rec)
137 cport = (int)ntohs((uint16_t)rec->s_port);
138 }
139
140 /*
141 * Build kadm5_config_params with realm name and server name
142 */
143 memset((char *)¶ms, 0, sizeof (params));
144 params.realm = (char *)crealm;
145 params.admin_server = (char *)cserver;
146 params.mask = KADM5_CONFIG_REALM | KADM5_CONFIG_ADMIN_SERVER;
147 params.kadmind_port = cport;
148 params.mask |= KADM5_CONFIG_KADMIND_PORT;
149 len = strlen("kadmin") + strlen(cserver) + 2;
150 ka_service = malloc(len);
151 if (!ka_service) {
152 ret = KADM_ENOMEM;
153 goto err;
154 }
155 snprintf(ka_service, len, "%s@%s", "kadmin", cserver);
156 ka_name = qualify((char *)cname);
157 if (!ka_name) {
158 ret = KADM_ENOMEM;
159 goto err;
160 }
161
162 ret = kadm5_init_with_password(ka_name, (char *)cpasswd,
163 ka_service, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2,
164 NULL, &server_handle);
165
166 /* Release string arguments and variables */
167 if (cname)
168 (*env)->ReleaseStringUTFChars(env, name, cname);
169 if (cpasswd)
170 (*env)->ReleaseStringUTFChars(env, passwd, cpasswd);
171 if (crealm)
172 (*env)->ReleaseStringUTFChars(env, realm, crealm);
173 if (cserver)
174 (*env)->ReleaseStringUTFChars(env, server, cserver);
175 if (ka_name)
176 free(ka_name);
177 if (ka_service)
178 free(ka_service);
179
180 err:
181 if (ret) {
182 handle_error(env, ret);
183 return (JNI_FALSE);
184 }
185 return (JNI_TRUE);
186 }
187
188 /*
189 * Class: Kadmin
190 * Method: sessionExit
191 * Signature: ()V
192 */
193 /*ARGSUSED*/
194 JNIEXPORT void JNICALL
Java_Kadmin_sessionExit(JNIEnv * env,jobject obj)195 Java_Kadmin_sessionExit(JNIEnv *env, jobject obj)
196 {
197 kadm5_ret_t ret;
198
199 /*
200 * Use persistant handle to close
201 */
202 ret = kadm5_destroy(server_handle);
203 if (ret)
204 handle_error(env, ret);
205 server_handle = NULL;
206 if (cur_realm) {
207 free(cur_realm);
208 cur_realm = NULL;
209 }
210 }
211
212 /*
213 * Class: Kadmin
214 * Method: getPrivs
215 * Signature: ()I
216 */
217 /*ARGSUSED*/
218 JNIEXPORT jint JNICALL
Java_Kadmin_getPrivs(JNIEnv * env,jobject obj)219 Java_Kadmin_getPrivs(JNIEnv *env, jobject obj)
220 {
221 long privs = 0;
222 kadm5_ret_t ret;
223
224 /*
225 * Get ACL for this user
226 */
227 ret = kadm5_get_privs(server_handle, &privs);
228 if (ret)
229 handle_error(env, ret);
230 return (privs);
231 }
232
233 static int
charcmp(const void * a,const void * b)234 charcmp(const void *a, const void *b)
235 {
236 char **sa = (char **)a;
237 char **sb = (char **)b;
238
239 return (strcmp(*sa, *sb));
240 }
241
242 /*
243 * Class: Kadmin
244 * Method: getEncList
245 * Signature: ()[Ljava/lang/String;
246 */
247
248 /*ARGSUSED*/
249 JNIEXPORT jobjectArray JNICALL
Java_Kadmin_getEncList(JNIEnv * env,jobject obj)250 Java_Kadmin_getEncList(JNIEnv *env,
251 jobject obj)
252 {
253 jclass stringclass;
254 jobjectArray elist;
255 jstring s;
256 kadm5_ret_t ret;
257 int i, j, k, *grp = NULL;
258 krb5_int32 num_keysalts;
259 krb5_key_salt_tuple *keysalts;
260 krb5_enctype e_type;
261 kadm5_server_handle_t handle;
262 char *e_str, e_buf[BUFSIZ];
263 krb5_error_code kret;
264 krb5_boolean similar;
265 krb5_context context;
266
267 if (kret = krb5_init_context(&context)) {
268 handle_error(env, kret);
269 return (NULL);
270 }
271
272 /*
273 * Create and populate a Java String array
274 */
275 stringclass = (*env)->FindClass(env, "java/lang/String");
276 if (!stringclass) {
277 handle_error(env, KADM_JNI_CLASS);
278 return (NULL);
279 }
280
281 handle = server_handle;
282 num_keysalts = handle->params.num_keysalts;
283 keysalts = handle->params.keysalts;
284 elist = (*env)->NewObjectArray(env, num_keysalts, stringclass, NULL);
285 if (!elist) {
286 handle_error(env, KADM_JNI_ARRAY);
287 return (NULL);
288 }
289
290 /*
291 * Populate groupings for encryption types that are similar.
292 */
293 grp = malloc(sizeof (int) * num_keysalts);
294 if (grp == NULL) {
295 handle_error(env, errno);
296 return (NULL);
297 }
298 for (i = 0; i < num_keysalts; i++)
299 grp[i] = i;
300
301 for (i = 0; i < num_keysalts; i++) {
302 if (grp[i] != i)
303 continue;
304 for (j = i + 1; j < num_keysalts; j++) {
305 if (kret = krb5_c_enctype_compare(context,
306 keysalts[i].ks_enctype, keysalts[j].ks_enctype,
307 &similar)) {
308 free(grp);
309 handle_error(env, kret);
310 return (NULL);
311 }
312 if (similar)
313 grp[j] = grp[i];
314 }
315 }
316
317 /*
318 * Populate from params' supported enc type list from the initial kadmin
319 * session, this is documented default that the client can handle.
320 */
321 for (i = 0; i < num_keysalts; i++) {
322 e_type = keysalts[i].ks_enctype;
323
324 for (j = 0; j < krb5_enctypes_length; j++) {
325 if (e_type == krb5_enctypes_list[j].etype) {
326 e_str = krb5_enctypes_list[j].in_string;
327 (void) snprintf(e_buf, sizeof (e_buf),
328 "%d %s:normal", grp[i], e_str);
329 s = (*env)->NewStringUTF(env, e_buf);
330 if (!s) {
331 free(grp);
332 handle_error(env, KADM_JNI_NEWSTRING);
333 return (NULL);
334 }
335 (*env)->SetObjectArrayElement(env, elist, i, s);
336 break;
337 }
338 }
339 }
340
341 free(grp);
342 return (elist);
343 }
344
345 /*
346 * Class: Kadmin
347 * Method: getPrincipalList
348 * Signature: ()[Ljava/lang/String;
349 */
350 /*ARGSUSED*/
351 JNIEXPORT jobjectArray JNICALL
Java_Kadmin_getPrincipalList(JNIEnv * env,jobject obj)352 Java_Kadmin_getPrincipalList(JNIEnv *env,
353 jobject obj)
354 {
355 jclass stringclass;
356 jobjectArray plist;
357 jstring s;
358 char **princs;
359 int i, count;
360 kadm5_ret_t ret;
361
362 /*
363 * Get the list
364 */
365 ret = kadm5_get_principals(server_handle, NULL, &princs, &count);
366 if (ret) {
367 handle_error(env, ret);
368 return (NULL);
369 }
370 qsort(princs, count, sizeof (princs[0]), charcmp);
371
372 /*
373 * Create and populate a Java String array
374 */
375 stringclass = (*env)->FindClass(env, "java/lang/String");
376 if (!stringclass) {
377 handle_error(env, KADM_JNI_CLASS);
378 return (NULL);
379 }
380 plist = (*env)->NewObjectArray(env, count, stringclass, NULL);
381 if (!plist) {
382 handle_error(env, KADM_JNI_ARRAY);
383 return (NULL);
384 }
385 for (i = 0; i < count; i++) {
386 s = (*env)->NewStringUTF(env, princs[i]);
387 if (!s) {
388 handle_error(env, KADM_JNI_NEWSTRING);
389 return (NULL);
390 }
391 (*env)->SetObjectArrayElement(env, plist, i, s);
392 }
393 kadm5_free_name_list(server_handle, princs, count);
394 return (plist);
395 }
396
397 /*
398 * Class: Kadmin
399 * Method: getPrincipalList2
400 * Signature: ()Ljava/lang/String;
401 */
402 /*ARGSUSED*/
403 JNIEXPORT jstring JNICALL
Java_Kadmin_getPrincipalList2(JNIEnv * env,jobject obj)404 Java_Kadmin_getPrincipalList2(JNIEnv *env, jobject obj)
405 {
406 jstring plist;
407 char **princs;
408 char *princlist = NULL;
409 int i, count, n, used = 0, size = 0;
410 kadm5_ret_t ret;
411
412 /*
413 * Get the list
414 */
415 ret = kadm5_get_principals(server_handle, NULL, &princs, &count);
416 if (ret) {
417 handle_error(env, ret);
418 return (NULL);
419 }
420 qsort(princs, count, sizeof (princs[0]), charcmp);
421
422 /*
423 * Build one large C string to hold list
424 */
425 used = 0;
426 princlist = malloc(size += 2048);
427 if (!princlist)
428 return (NULL);
429 for (i = 0; i < count; i++) {
430 n = strlen(princs[i]);
431 if (used + n + 2 > size) {
432 princlist = realloc(princlist, size += 2048);
433 if (!princlist)
434 return (NULL);
435 }
436 strncpy(&princlist[used], princs[i], n);
437 used += n + 1;
438 princlist[used-1] = ' ';
439 princlist[used] = '\0';
440 }
441
442 /*
443 * Create a Java String
444 */
445 plist = (*env)->NewStringUTF(env, princlist);
446 free(princlist);
447 kadm5_free_name_list(server_handle, princs, count);
448 return (plist);
449 }
450
451
452 /*
453 * Class: Kadmin
454 * Method: loadPrincipal
455 * Signature: (Ljava/lang/String;LPrincipal;)Z
456 */
457 /*ARGSUSED*/
458 JNIEXPORT jboolean JNICALL
Java_Kadmin_loadPrincipal(JNIEnv * env,jobject obj,jstring name,jobject prin)459 Java_Kadmin_loadPrincipal(JNIEnv *env, jobject obj, jstring name, jobject prin)
460 {
461 const char *cname;
462 char *fullname;
463 char *comments = NULL;
464 kadm5_principal_ent_rec pr_rec;
465 kadm5_ret_t ret;
466 long mask = KADM5_PRINCIPAL_NORMAL_MASK | KADM5_TL_DATA |
467 KADM5_KEY_DATA;
468 krb5_principal kprin = NULL;
469 krb5_context context;
470
471 cname = (*env)->GetStringUTFChars(env, name, NULL);
472 if (!cname) {
473 handle_error(env, KADM_JNI_STRING);
474 return (JNI_FALSE);
475 }
476 fullname = qualify((char *)cname);
477 if (!fullname) {
478 handle_error(env, KADM_JNI_STRING);
479 return (JNI_FALSE);
480 }
481
482 /*
483 * Get the principal
484 */
485 ret = krb5_init_context(&context);
486 if (ret) {
487 handle_error(env, ret);
488 return (JNI_FALSE);
489 }
490 ret = krb5_parse_name(context, fullname, &kprin);
491 if (ret) {
492 handle_error(env, ret);
493 return (JNI_FALSE);
494 }
495 memset((char *)&pr_rec, 0, sizeof (pr_rec));
496 ret = kadm5_get_principal(server_handle, kprin, &pr_rec, mask);
497 if (ret) {
498 handle_error(env, ret);
499 return (JNI_FALSE);
500 }
501
502 /*
503 * Pull the comments out of the tl_data array
504 */
505 ret = extract_comments(&pr_rec, &comments);
506 if (ret) {
507 handle_error(env, ret);
508 return (JNI_FALSE);
509 }
510
511 /*
512 * Fill in our Principal object
513 */
514 ret = kadmin_to_Principal(&pr_rec, env, prin, cname, comments);
515 if (ret) {
516 handle_error(env, ret);
517 return (JNI_FALSE);
518 }
519
520 kadm5_free_principal_ent(server_handle, &pr_rec);
521 krb5_free_principal(context, kprin);
522 (*env)->ReleaseStringUTFChars(env, name, cname);
523 free(fullname);
524
525 return (JNI_TRUE);
526 }
527
528 /*
529 * Class: Kadmin
530 * Method: savePrincipal
531 * Signature: (LPrincipal;)Z
532 */
533 /*ARGSUSED*/
534 JNIEXPORT jboolean JNICALL
Java_Kadmin_savePrincipal(JNIEnv * env,jobject obj,jobject prin)535 Java_Kadmin_savePrincipal(JNIEnv *env, jobject obj, jobject prin)
536 {
537 kadm5_principal_ent_rec pr_rec;
538 long mask;
539 char *pw = NULL;
540 char *comments = NULL;
541 kadm5_ret_t ret;
542 krb5_principal kprin = NULL;
543 kadm5_config_params params;
544
545 /*
546 * Convert principal object to the kadmin API structure
547 */
548 memset((char *)&pr_rec, 0, sizeof (pr_rec));
549 memset((char *)¶ms, 0, sizeof (params));
550 ret = Principal_to_kadmin(env, prin, 0, &kprin, &pr_rec, &mask,
551 &pw, &comments, ¶ms);
552 if (ret) {
553 handle_error(env, ret);
554 return (JNI_FALSE);
555 }
556
557 /*
558 * Save the principal
559 */
560 ret = kadm5_modify_principal(server_handle, &pr_rec, mask);
561 if (ret) {
562 handle_error(env, ret);
563 ret = JNI_FALSE;
564 goto out;
565 }
566
567 /*
568 * Handle any comments with read-modify-write
569 */
570 ret = edit_comments(&pr_rec, kprin, comments);
571 if (ret) {
572 handle_error(env, ret);
573 ret = JNI_FALSE;
574 goto out;
575 }
576
577 /*
578 * Set the password if changed
579 */
580 ret = set_password(kprin, pw, ¶ms);
581 if (params.keysalts != NULL)
582 free(params.keysalts);
583 if (ret) {
584 handle_error(env, ret);
585 ret = JNI_FALSE;
586 goto out;
587 }
588 ret = JNI_TRUE;
589
590 out:
591 kadm5_free_principal_ent(server_handle, &pr_rec);
592 return (ret);
593 }
594
595 /*
596 * Class: Kadmin
597 * Method: createPrincipal
598 * Signature: (LPrincipal;)Z
599 */
600 /*ARGSUSED*/
601 JNIEXPORT jboolean JNICALL
Java_Kadmin_createPrincipal(JNIEnv * env,jobject obj,jobject prin)602 Java_Kadmin_createPrincipal(JNIEnv *env, jobject obj, jobject prin)
603 {
604 kadm5_principal_ent_rec pr_rec;
605 long mask;
606 char *pw = NULL;
607 char *comments = NULL;
608 kadm5_ret_t ret;
609 krb5_principal kprin = NULL;
610 kadm5_config_params params;
611
612 /*
613 * Convert principal object to the kadmin API structure
614 */
615 memset((char *)&pr_rec, 0, sizeof (pr_rec));
616 memset((char *)¶ms, 0, sizeof (params));
617 ret = Principal_to_kadmin(env, prin, 1, &kprin, &pr_rec, &mask,
618 &pw, &comments, ¶ms);
619 if (ret) {
620 handle_error(env, ret);
621 return (JNI_FALSE);
622 }
623
624 /*
625 * Create the new principal
626 */
627 if (params.mask & KADM5_CONFIG_ENCTYPES) {
628 ret = kadm5_create_principal_3(server_handle, &pr_rec, mask,
629 params.num_keysalts, params.keysalts, pw);
630 if (params.keysalts != NULL)
631 free(params.keysalts);
632 } else
633 ret = kadm5_create_principal(server_handle, &pr_rec, mask, pw);
634 if (ret) {
635 handle_error(env, ret);
636 ret = JNI_FALSE;
637 goto out;
638 }
639
640 /*
641 * Handle any comments with read-modify-write
642 */
643 ret = edit_comments(&pr_rec, kprin, comments);
644 if (ret) {
645 handle_error(env, ret);
646 ret = JNI_FALSE;
647 goto out;
648 }
649
650 ret = JNI_TRUE;
651 out:
652 kadm5_free_principal_ent(server_handle, &pr_rec);
653 return (ret);
654 }
655
656 /*
657 * Class: Kadmin
658 * Method: deletePrincipal
659 * Signature: (Ljava/lang/String;)Z
660 */
661 /*ARGSUSED*/
662 JNIEXPORT jboolean JNICALL
Java_Kadmin_deletePrincipal(JNIEnv * env,jobject obj,jstring name)663 Java_Kadmin_deletePrincipal(JNIEnv *env, jobject obj, jstring name)
664 {
665 kadm5_ret_t ret;
666 const char *cname;
667 char *fullname;
668 krb5_principal kprin = NULL;
669 krb5_context context;
670
671 /*
672 * Get name and call the delete function
673 */
674 cname = (*env)->GetStringUTFChars(env, name, NULL);
675 if (!cname) {
676 handle_error(env, KADM_JNI_STRING);
677 return (JNI_FALSE);
678 }
679 fullname = qualify((char *)cname);
680 if (!fullname) {
681 handle_error(env, KADM_JNI_STRING);
682 return (JNI_FALSE);
683 }
684
685 ret = krb5_init_context(&context);
686 if (ret) {
687 handle_error(env, ret);
688 return (JNI_FALSE);
689 }
690 ret = krb5_parse_name(context, fullname, &kprin);
691 if (ret) {
692 handle_error(env, ret);
693 return (JNI_FALSE);
694 }
695 ret = kadm5_delete_principal(server_handle, kprin);
696 if (ret) {
697 handle_error(env, ret);
698 return (JNI_FALSE);
699 }
700
701 krb5_free_principal(context, kprin);
702 (*env)->ReleaseStringUTFChars(env, name, cname);
703 free(fullname);
704
705 return (JNI_TRUE);
706 }
707
708 /*
709 * Class: Kadmin
710 * Method: getPolicyList
711 * Signature: ()[Ljava/lang/String;
712 */
713 /*ARGSUSED*/
714 JNIEXPORT jobjectArray JNICALL
Java_Kadmin_getPolicyList(JNIEnv * env,jobject obj)715 Java_Kadmin_getPolicyList(JNIEnv *env, jobject obj)
716 {
717 jclass stringclass;
718 jobjectArray plist;
719 jstring s;
720 char **pols;
721 int i, count;
722 kadm5_ret_t ret;
723
724 /*
725 * Get the list
726 */
727 ret = kadm5_get_policies(server_handle, NULL, &pols, &count);
728 if (ret) {
729 handle_error(env, ret);
730 return (NULL);
731 }
732 qsort(pols, count, sizeof (pols[0]), charcmp);
733
734 /*
735 * Create and populate a Java String array
736 */
737 stringclass = (*env)->FindClass(env, "java/lang/String");
738 if (!stringclass) {
739 handle_error(env, KADM_JNI_CLASS);
740 return (NULL);
741 }
742 plist = (*env)->NewObjectArray(env, count, stringclass, NULL);
743 if (!plist) {
744 handle_error(env, KADM_JNI_ARRAY);
745 return (NULL);
746 }
747 for (i = 0; i < count; i++) {
748 s = (*env)->NewStringUTF(env, pols[i]);
749 if (!s) {
750 handle_error(env, KADM_JNI_NEWSTRING);
751 return (NULL);
752 }
753 (*env)->SetObjectArrayElement(env, plist, i, s);
754 }
755 kadm5_free_name_list(server_handle, pols, count);
756 return (plist);
757 }
758
759 /*
760 * Class: Kadmin
761 * Method: loadPolicy
762 * Signature: (Ljava/lang/String;LPolicy;)Z
763 */
764 /*ARGSUSED*/
765 JNIEXPORT jboolean JNICALL
Java_Kadmin_loadPolicy(JNIEnv * env,jobject obj,jstring name,jobject pol)766 Java_Kadmin_loadPolicy(JNIEnv *env, jobject obj, jstring name, jobject pol)
767 {
768 const char *cname;
769 kadm5_policy_ent_rec po_rec;
770 kadm5_ret_t ret;
771
772 cname = (*env)->GetStringUTFChars(env, name, NULL);
773 if (!cname) {
774 handle_error(env, KADM_JNI_STRING);
775 return (JNI_FALSE);
776 }
777
778 ret = kadm5_get_policy(server_handle, (char *)cname, &po_rec);
779 if (ret) {
780 handle_error(env, ret);
781 return (JNI_FALSE);
782 }
783
784 ret = kadmin_to_Policy(&po_rec, env, pol);
785 if (ret) {
786 handle_error(env, ret);
787 return (JNI_FALSE);
788 }
789
790 kadm5_free_policy_ent(server_handle, &po_rec);
791 (*env)->ReleaseStringUTFChars(env, name, cname);
792
793 return (JNI_TRUE);
794 }
795
796 /*
797 * Class: Kadmin
798 * Method: savePolicy
799 * Signature: (LPolicy;)Z
800 */
801 /*ARGSUSED*/
802 JNIEXPORT jboolean JNICALL
Java_Kadmin_savePolicy(JNIEnv * env,jobject obj,jobject pol)803 Java_Kadmin_savePolicy(JNIEnv *env, jobject obj, jobject pol)
804 {
805 kadm5_policy_ent_rec po_rec;
806 kadm5_ret_t ret;
807 long mask;
808
809 ret = Policy_to_kadmin(env, pol, 0, &po_rec, &mask);
810 if (ret) {
811 handle_error(env, ret);
812 return (JNI_FALSE);
813 }
814
815 ret = kadm5_modify_policy(server_handle, &po_rec, mask);
816 if (ret) {
817 handle_error(env, ret);
818 return (JNI_FALSE);
819 }
820
821 return (JNI_TRUE);
822 }
823
824 /*
825 * Class: Kadmin
826 * Method: createPolicy
827 * Signature: (LPolicy;)Z
828 */
829 /*ARGSUSED*/
830 JNIEXPORT jboolean JNICALL
Java_Kadmin_createPolicy(JNIEnv * env,jobject obj,jobject pol)831 Java_Kadmin_createPolicy(JNIEnv * env, jobject obj, jobject pol)
832 {
833 kadm5_policy_ent_rec po_rec;
834 kadm5_ret_t ret;
835 long mask;
836
837 ret = Policy_to_kadmin(env, pol, 1, &po_rec, &mask);
838 if (ret) {
839 handle_error(env, ret);
840 return (JNI_FALSE);
841 }
842
843 ret = kadm5_create_policy(server_handle, &po_rec, mask);
844 if (ret) {
845 handle_error(env, ret);
846 return (JNI_FALSE);
847 }
848
849 return (JNI_TRUE);
850 }
851
852 /*
853 * Class: Kadmin
854 * Method: deletePolicy
855 * Signature: (Ljava/lang/String;)Z
856 */
857 /*ARGSUSED*/
858 JNIEXPORT jboolean JNICALL
Java_Kadmin_deletePolicy(JNIEnv * env,jobject obj,jstring name)859 Java_Kadmin_deletePolicy(JNIEnv * env, jobject obj, jstring name)
860 {
861 const char *cname;
862 kadm5_ret_t ret;
863
864 cname = (*env)->GetStringUTFChars(env, name, NULL);
865 if (!cname) {
866 handle_error(env, KADM_JNI_STRING);
867 return (JNI_FALSE);
868 }
869
870 ret = kadm5_delete_policy(server_handle, (char *)cname);
871 if (ret) {
872 handle_error(env, ret);
873 return (JNI_FALSE);
874 }
875 return (JNI_TRUE);
876 }
877
878 #ifdef needtoknowmore
879 /*
880 * Class: Kadmin
881 * Method: loadDefaults
882 * Signature: (LConfig;)Z
883 */
884 /*ARGSUSED*/
885 JNIEXPORT jboolean JNICALL
Java_Kadmin_loadDefaults(JNIEnv * env,jobject obj,jobject config)886 Java_Kadmin_loadDefaults(JNIEnv *env, jobject obj, jobject config)
887 {
888 /*
889 *
890 */
891 return (JNI_TRUE);
892 }
893
894 /*
895 * Class: Kadmin
896 * Method: saveDefaults
897 * Signature: (LConfig;)Z
898 */
899 /*ARGSUSED*/
900 JNIEXPORT jboolean JNICALL
Java_Kadmin_saveDefaults(JNIEnv * env,jobject obj,jobject config)901 Java_Kadmin_saveDefaults(JNIEnv *env, jobject obj, jobject config)
902 {
903 /*
904 *
905 */
906 return (JNI_TRUE);
907 }
908 #endif
909
910 static int
Principal_to_kadmin(JNIEnv * env,jobject prin,int new,krb5_principal * kprin,kadm5_principal_ent_rec * p,long * mask,char ** pw,char ** comments,kadm5_config_params * pparams)911 Principal_to_kadmin(JNIEnv *env, jobject prin, int new, krb5_principal *kprin,
912 kadm5_principal_ent_rec *p, long *mask, char **pw, char **comments,
913 kadm5_config_params *pparams)
914 {
915 jstring s;
916 jclass prcl, dateclass, intclass;
917 jfieldID f;
918 jmethodID mid;
919 jobject obj;
920 const char *str;
921 jlong l;
922 jint i;
923 jboolean b;
924 kadm5_ret_t ret;
925 krb5_context context;
926 jfieldID flagsID;
927 jobject flagsObj;
928 jclass flagsClass;
929 char *fullname;
930
931 *mask = 0;
932
933 prcl = (*env)->GetObjectClass(env, prin);
934 if (!prcl)
935 return (KADM_JNI_CLASS);
936 dateclass = (*env)->FindClass(env, "java/util/Date");
937 if (!dateclass)
938 return (KADM_JNI_CLASS);
939 intclass = (*env)->FindClass(env, "java/lang/Integer");
940 if (!intclass)
941 return (KADM_JNI_CLASS);
942
943 f = (*env)->GetFieldID(env, prcl, "PrName", "Ljava/lang/String;");
944 if (!f)
945 return (KADM_JNI_FIELD);
946 obj = (*env)->GetObjectField(env, prin, f);
947 if (!obj)
948 return (KADM_JNI_OFIELD);
949 s = (jstring)obj;
950 str = (*env)->GetStringUTFChars(env, s, NULL);
951 if (!str)
952 return (KADM_JNI_STRING);
953 fullname = qualify((char *)str);
954 if (!fullname)
955 return (KADM_ENOMEM);
956 ret = krb5_init_context(&context);
957 if (ret)
958 return (ret);
959 ret = krb5_parse_name(context, fullname, kprin);
960 if (ret)
961 return (ret);
962 p->principal = *kprin;
963 (*env)->ReleaseStringUTFChars(env, s, str);
964 if (new)
965 *mask |= KADM5_PRINCIPAL;
966
967 f = (*env)->GetFieldID(env, prcl, "PrExpireTime", "Ljava/util/Date;");
968 if (!f)
969 return (KADM_JNI_FIELD);
970 obj = (*env)->GetObjectField(env, prin, f);
971 if (!obj)
972 return (KADM_JNI_OFIELD);
973 mid = (*env)->GetMethodID(env, dateclass, "getTime", "()J");
974 if (!mid)
975 return (KADM_JNI_METHOD);
976 l = (*env)->CallLongMethod(env, obj, mid);
977 p->princ_expire_time = (long)(l / 1000LL);
978 *mask |= KADM5_PRINC_EXPIRE_TIME;
979
980 f = (*env)->GetFieldID(env, prcl, "EncTypes", "Ljava/lang/String;");
981 if (!f)
982 return (KADM_JNI_FIELD);
983 obj = (*env)->GetObjectField(env, prin, f);
984 if (!obj)
985 return (KADM_JNI_OFIELD);
986 s = (jstring)obj;
987 str = (*env)->GetStringUTFChars(env, s, NULL);
988 if (!str)
989 return (KADM_JNI_STRING);
990 if (strlen(str)) {
991 ret = krb5_string_to_keysalts((char *)str, ", \t", ":.-", 0,
992 &(pparams->keysalts), &(pparams->num_keysalts));
993 if (ret) {
994 (*env)->ReleaseStringUTFChars(env, s, str);
995 return (ret);
996 }
997 pparams->mask |= KADM5_CONFIG_ENCTYPES;
998 }
999 (*env)->ReleaseStringUTFChars(env, s, str);
1000
1001 f = (*env)->GetFieldID(env, prcl, "Policy", "Ljava/lang/String;");
1002 if (!f)
1003 return (KADM_JNI_FIELD);
1004 obj = (*env)->GetObjectField(env, prin, f);
1005 if (!obj)
1006 return (KADM_JNI_OFIELD);
1007 s = (jstring)obj;
1008 str = (*env)->GetStringUTFChars(env, s, NULL);
1009 if (!str)
1010 return (KADM_JNI_STRING);
1011 p->policy = strdup(str);
1012 if (!p->policy)
1013 return (KADM_ENOMEM);
1014 (*env)->ReleaseStringUTFChars(env, s, str);
1015 if (strlen(p->policy))
1016 *mask |= KADM5_POLICY;
1017 else if (!new)
1018 *mask |= KADM5_POLICY_CLR;
1019
1020 f = (*env)->GetFieldID(env, prcl, "PwExpireTime", "Ljava/util/Date;");
1021 if (!f)
1022 return (KADM_JNI_FIELD);
1023 obj = (*env)->GetObjectField(env, prin, f);
1024 if (obj) {
1025 mid = (*env)->GetMethodID(env, dateclass, "getTime", "()J");
1026 if (!mid)
1027 return (KADM_JNI_METHOD);
1028 l = (*env)->CallLongMethod(env, obj, mid);
1029 p->pw_expiration = (long)(l / 1000LL);
1030 *mask |= KADM5_PW_EXPIRATION;
1031 }
1032
1033 f = (*env)->GetFieldID(env, prcl, "MaxLife", "Ljava/lang/Integer;");
1034 if (!f)
1035 return (KADM_JNI_FIELD);
1036 obj = (*env)->GetObjectField(env, prin, f);
1037 if (!obj)
1038 return (KADM_JNI_OFIELD);
1039 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1040 if (!mid)
1041 return (KADM_JNI_METHOD);
1042 i = (*env)->CallIntMethod(env, obj, mid);
1043 p->max_life = i;
1044 *mask |= KADM5_MAX_LIFE;
1045
1046 f = (*env)->GetFieldID(env, prcl, "MaxRenew", "Ljava/lang/Integer;");
1047 if (!f)
1048 return (KADM_JNI_FIELD);
1049 obj = (*env)->GetObjectField(env, prin, f);
1050 if (!obj)
1051 return (KADM_JNI_OFIELD);
1052 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1053 if (!mid)
1054 return (KADM_JNI_METHOD);
1055 i = (*env)->CallIntMethod(env, obj, mid);
1056 p->max_renewable_life = i;
1057 *mask |= KADM5_MAX_RLIFE;
1058
1059 /*
1060 * Comments: because of API rules on the TL_DATA entries,
1061 * which say that a load-modify-write is always necessary,
1062 * we will only deal with comments if they are newly changed.
1063 */
1064 f = (*env)->GetFieldID(env, prcl, "newComments", "Z");
1065 if (!f)
1066 return (KADM_JNI_FIELD);
1067 b = (*env)->GetBooleanField(env, prin, f);
1068 if (b == JNI_TRUE) {
1069
1070 f = (*env)->GetFieldID(env, prcl, "Comments",
1071 "Ljava/lang/String;");
1072 if (!f)
1073 return (KADM_JNI_FIELD);
1074 obj = (*env)->GetObjectField(env, prin, f);
1075 if (!obj)
1076 return (KADM_JNI_OFIELD);
1077 s = (jstring)obj;
1078 str = (*env)->GetStringUTFChars(env, s, NULL);
1079 if (!str)
1080 return (KADM_JNI_STRING);
1081 *comments = strdup(str);
1082 if (!*comments)
1083 return (KADM_ENOMEM);
1084 (*env)->ReleaseStringUTFChars(env, s, str);
1085 }
1086
1087 f = (*env)->GetFieldID(env, prcl, "Kvno", "Ljava/lang/Integer;");
1088 if (!f)
1089 return (KADM_JNI_FIELD);
1090 obj = (*env)->GetObjectField(env, prin, f);
1091 if (!obj)
1092 return (KADM_JNI_OFIELD);
1093 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1094 if (!mid)
1095 return (KADM_JNI_METHOD);
1096 i = (*env)->CallIntMethod(env, obj, mid);
1097 p->kvno = i;
1098 *mask |= KADM5_KVNO;
1099
1100 /*
1101 * Get the Principal.flags field id
1102 */
1103 flagsID = (*env)->GetFieldID(env, prcl, "flags",
1104 "LFlags;");
1105 if (!f)
1106 return (KADM_JNI_FIELD);
1107
1108 /*
1109 * Get the Principal.Flags object
1110 */
1111 flagsObj = (*env)->GetObjectField(env, prin, flagsID);
1112 if (!obj)
1113 return (KADM_JNI_OFIELD);
1114
1115 /*
1116 * Get the Flags object's class
1117 */
1118 flagsClass = (*env)->GetObjectClass(env, flagsObj);
1119 if (!flagsClass)
1120 return (KADM_JNI_CLASS);
1121
1122 /*
1123 * Now get the Flags.flags field's value
1124 */
1125 f = (*env)->GetFieldID(env, flagsClass, "flags", "I");
1126 if (!f)
1127 return (KADM_JNI_FIELD);
1128
1129 i = (*env)->GetIntField(env, flagsObj, f);
1130 p->attributes = i & ~65536;
1131
1132 *mask |= KADM5_ATTRIBUTES;
1133
1134 f = (*env)->GetFieldID(env, prcl, "PrPasswd", "Ljava/lang/String;");
1135 if (!f)
1136 return (KADM_JNI_FIELD);
1137 obj = (*env)->GetObjectField(env, prin, f);
1138 if (!obj)
1139 return (KADM_JNI_OFIELD);
1140 s = (jstring)obj;
1141 str = (*env)->GetStringUTFChars(env, s, NULL);
1142 if (!str)
1143 return (KADM_JNI_STRING);
1144 *pw = strdup(str);
1145 if (!*pw)
1146 return (KADM_ENOMEM);
1147 (*env)->ReleaseStringUTFChars(env, s, str);
1148
1149 free(fullname);
1150 return (0);
1151 }
1152
1153 static int
kadmin_to_Principal(kadm5_principal_ent_rec * p,JNIEnv * env,jobject prin,const char * prname,char * comments)1154 kadmin_to_Principal(kadm5_principal_ent_rec *p, JNIEnv *env, jobject prin,
1155 const char *prname, char *comments)
1156 {
1157 jstring s;
1158 jclass prcl, dateclass, intclass;
1159 jfieldID f;
1160 jmethodID mid;
1161 jobject obj;
1162 int i, j, n, used = 0, size = 0;
1163 kadm5_ret_t ret;
1164 krb5_context context;
1165 char *ptr, *enclist = NULL, *e_str = NULL, *i_str;
1166 char *cstr;
1167
1168 jfieldID flagsID;
1169 jobject flagsObj;
1170 jclass flagsClass;
1171
1172 prcl = (*env)->GetObjectClass(env, prin);
1173 if (!prcl)
1174 return (KADM_JNI_CLASS);
1175 dateclass = (*env)->FindClass(env, "java/util/Date");
1176 if (!dateclass)
1177 return (KADM_JNI_CLASS);
1178 intclass = (*env)->FindClass(env, "java/lang/Integer");
1179 if (!intclass)
1180 return (KADM_JNI_CLASS);
1181
1182 f = (*env)->GetFieldID(env, prcl, "PrName", "Ljava/lang/String;");
1183 if (!f)
1184 return (KADM_JNI_FIELD);
1185 s = (*env)->NewStringUTF(env, prname);
1186 if (!s)
1187 return (KADM_JNI_NEWSTRING);
1188 (*env)->SetObjectField(env, prin, f, s);
1189
1190 f = (*env)->GetFieldID(env, prcl, "PrExpireTime", "Ljava/util/Date;");
1191 if (!f)
1192 return (KADM_JNI_FIELD);
1193 mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
1194 if (!mid)
1195 return (KADM_JNI_METHOD);
1196 obj = (*env)->GetObjectField(env, prin, f);
1197 if (!obj)
1198 return (KADM_JNI_OFIELD);
1199 (*env)->CallVoidMethod(env, obj, mid,
1200 (jlong) (p->princ_expire_time * 1000LL));
1201
1202 f = (*env)->GetFieldID(env, prcl, "EncTypes", "Ljava/lang/String;");
1203 if (!f)
1204 return (KADM_JNI_FIELD);
1205 used = 0;
1206 enclist = malloc(size += 2048);
1207 if (enclist == NULL)
1208 return (errno);
1209 for (i = 0; i < p->n_key_data; i++) {
1210 krb5_key_data *key_data = &p->key_data[i];
1211 for (j = 0; j < krb5_enctypes_length; j++) {
1212 if (key_data->key_data_type[0] ==
1213 krb5_enctypes_list[j].etype) {
1214 i_str = krb5_enctypes_list[j].in_string;
1215 n = strlen(i_str) + strlen(":normal");
1216 e_str = malloc(n);
1217 if (e_str == NULL) {
1218 free(enclist);
1219 return (errno);
1220 }
1221 (void) snprintf(e_str, n + 1, "%s:normal",
1222 i_str);
1223 /*
1224 * We reallocate if existing + what we need +
1225 * 2 (the null byte and a space for the list).
1226 */
1227 if (used + n + 2 > size) {
1228 enclist = realloc(enclist,
1229 size += 2048);
1230 if (enclist == NULL) {
1231 free(e_str);
1232 return (errno);
1233 }
1234 }
1235 (void) strncpy(&enclist[used], e_str, n);
1236 free(e_str);
1237 e_str = NULL;
1238 used += n + 1;
1239 enclist[used-1] = ' ';
1240 enclist[used] = '\0';
1241 break;
1242 }
1243 }
1244 }
1245 s = (*env)->NewStringUTF(env, enclist);
1246 free(enclist);
1247 if (!s)
1248 return (KADM_JNI_NEWSTRING);
1249 (*env)->SetObjectField(env, prin, f, s);
1250
1251 f = (*env)->GetFieldID(env, prcl, "Policy", "Ljava/lang/String;");
1252 if (!f)
1253 return (KADM_JNI_FIELD);
1254 cstr = strdup(p->policy ? p->policy : "");
1255 if (!cstr)
1256 return (KADM_ENOMEM);
1257 s = (*env)->NewStringUTF(env, cstr);
1258 if (!s)
1259 return (KADM_JNI_NEWSTRING);
1260 (*env)->SetObjectField(env, prin, f, s);
1261 free(cstr);
1262
1263 f = (*env)->GetFieldID(env, prcl, "LastPwChange", "Ljava/util/Date;");
1264 if (!f)
1265 return (KADM_JNI_FIELD);
1266 mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
1267 if (!mid)
1268 return (KADM_JNI_METHOD);
1269 obj = (*env)->GetObjectField(env, prin, f);
1270 if (!obj)
1271 return (KADM_JNI_OFIELD);
1272 (*env)->CallVoidMethod(env, obj, mid,
1273 (jlong) (p->last_pwd_change * 1000LL));
1274
1275 f = (*env)->GetFieldID(env, prcl, "PwExpireTime", "Ljava/util/Date;");
1276 if (!f)
1277 return (KADM_JNI_FIELD);
1278 mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
1279 if (!mid)
1280 return (KADM_JNI_METHOD);
1281 obj = (*env)->GetObjectField(env, prin, f);
1282 if (!obj)
1283 return (KADM_JNI_OFIELD);
1284 (*env)->CallVoidMethod(env, obj, mid,
1285 (jlong) (p->pw_expiration * 1000LL));
1286
1287 f = (*env)->GetFieldID(env, prcl, "MaxLife", "Ljava/lang/Integer;");
1288 if (!f)
1289 return (KADM_JNI_FIELD);
1290 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1291 if (!mid)
1292 return (KADM_JNI_METHOD);
1293 obj = (*env)->NewObject(env, intclass, mid, (jint) p->max_life);
1294 if (!obj)
1295 return (KADM_JNI_OBJECT);
1296 (*env)->SetObjectField(env, prin, f, obj);
1297
1298 f = (*env)->GetFieldID(env, prcl, "MaxRenew", "Ljava/lang/Integer;");
1299 if (!f)
1300 return (KADM_JNI_FIELD);
1301 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1302 if (!mid)
1303 return (KADM_JNI_METHOD);
1304 obj = (*env)->NewObject(env, intclass, mid,
1305 (jint) p->max_renewable_life);
1306 if (!obj)
1307 return (KADM_JNI_OBJECT);
1308 (*env)->SetObjectField(env, prin, f, obj);
1309
1310 f = (*env)->GetFieldID(env, prcl, "ModTime", "Ljava/util/Date;");
1311 if (!f)
1312 return (KADM_JNI_FIELD);
1313 mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
1314 if (!mid)
1315 return (KADM_JNI_METHOD);
1316 obj = (*env)->GetObjectField(env, prin, f);
1317 if (!obj)
1318 return (KADM_JNI_OFIELD);
1319 (*env)->CallVoidMethod(env, obj, mid,
1320 (jlong) (p->mod_date * 1000LL));
1321
1322 ret = krb5_init_context(&context);
1323 if (ret)
1324 return (ret);
1325 ret = krb5_unparse_name(context, p->mod_name, &ptr);
1326 if (ret)
1327 return (ret);
1328 f = (*env)->GetFieldID(env, prcl, "ModName", "Ljava/lang/String;");
1329 if (!f)
1330 return (KADM_JNI_FIELD);
1331 s = (*env)->NewStringUTF(env, ptr);
1332 if (!s)
1333 return (KADM_JNI_NEWSTRING);
1334 (*env)->SetObjectField(env, prin, f, s);
1335 krb5_xfree(ptr);
1336
1337 f = (*env)->GetFieldID(env, prcl, "LastSuccess", "Ljava/util/Date;");
1338 if (!f)
1339 return (KADM_JNI_FIELD);
1340 mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
1341 if (!mid)
1342 return (KADM_JNI_METHOD);
1343 obj = (*env)->GetObjectField(env, prin, f);
1344 if (!obj)
1345 return (KADM_JNI_OFIELD);
1346 (*env)->CallVoidMethod(env, obj, mid,
1347 (jlong) (p->last_success * 1000LL));
1348
1349 f = (*env)->GetFieldID(env, prcl, "LastFailure", "Ljava/util/Date;");
1350 if (!f)
1351 return (KADM_JNI_FIELD);
1352 mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
1353 if (!mid)
1354 return (KADM_JNI_METHOD);
1355 obj = (*env)->GetObjectField(env, prin, f);
1356 if (!obj)
1357 return (KADM_JNI_OFIELD);
1358 (*env)->CallVoidMethod(env, obj, mid,
1359 (jlong) (p->last_failed * 1000LL));
1360
1361 f = (*env)->GetFieldID(env, prcl, "NumFailures", "Ljava/lang/Integer;");
1362 if (!f)
1363 return (KADM_JNI_FIELD);
1364 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1365 if (!mid)
1366 return (KADM_JNI_METHOD);
1367 obj = (*env)->NewObject(env, intclass, mid,
1368 (jint) p->fail_auth_count);
1369 if (!obj)
1370 return (KADM_JNI_OBJECT);
1371 (*env)->SetObjectField(env, prin, f, obj);
1372
1373 f = (*env)->GetFieldID(env, prcl, "Comments", "Ljava/lang/String;");
1374 if (!f)
1375 return (KADM_JNI_FIELD);
1376 cstr = strdup(comments ? comments : "");
1377 if (!cstr)
1378 return (KADM_ENOMEM);
1379 s = (*env)->NewStringUTF(env, cstr);
1380 if (!s)
1381 return (KADM_JNI_NEWSTRING);
1382 (*env)->SetObjectField(env, prin, f, s);
1383 free(cstr);
1384
1385 f = (*env)->GetFieldID(env, prcl, "Kvno", "Ljava/lang/Integer;");
1386 if (!f)
1387 return (KADM_JNI_FIELD);
1388 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1389 if (!mid)
1390 return (KADM_JNI_METHOD);
1391 obj = (*env)->NewObject(env, intclass, mid, p->kvno);
1392 if (!obj)
1393 return (KADM_JNI_OBJECT);
1394 (*env)->SetObjectField(env, prin, f, obj);
1395
1396 f = (*env)->GetFieldID(env, prcl, "Mkvno", "Ljava/lang/Integer;");
1397 if (!f)
1398 return (KADM_JNI_FIELD);
1399 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1400 if (!mid)
1401 return (KADM_JNI_METHOD);
1402 obj = (*env)->NewObject(env, intclass, mid, p->mkvno);
1403 if (!obj)
1404 return (KADM_JNI_OBJECT);
1405 (*env)->SetObjectField(env, prin, f, obj);
1406
1407 i = p->attributes;
1408
1409 /*
1410 * Get the Principal.flags field id
1411 */
1412 flagsID = (*env)->GetFieldID(env, prcl, "flags",
1413 "LFlags;");
1414 if (!f)
1415 return (KADM_JNI_FIELD);
1416
1417 /*
1418 * Get the Principal.Flags object
1419 */
1420 flagsObj = (*env)->GetObjectField(env, prin, flagsID);
1421 if (!obj)
1422 return (KADM_JNI_OFIELD);
1423
1424 /*
1425 * Get the Flags object's class
1426 */
1427 flagsClass = (*env)->GetObjectClass(env, flagsObj);
1428
1429 /*
1430 * Now set the Flags.flags field's value
1431 */
1432 f = (*env)->GetFieldID(env, flagsClass, "flags", "I");
1433 if (!f)
1434 return (KADM_JNI_FIELD);
1435 (*env)->SetIntField(env, flagsObj, f, i);
1436
1437 return (0);
1438 }
1439
1440 static int
Policy_to_kadmin(JNIEnv * env,jobject pol,int new,kadm5_policy_ent_rec * p,long * mask)1441 Policy_to_kadmin(JNIEnv *env, jobject pol, int new,
1442 kadm5_policy_ent_rec *p, long *mask)
1443 {
1444 jstring s;
1445 jclass pocl, intclass;
1446 jfieldID f;
1447 jmethodID mid;
1448 jobject obj;
1449 const char *str;
1450 int i;
1451
1452 *mask = 0;
1453
1454 pocl = (*env)->GetObjectClass(env, pol);
1455 if (!pocl)
1456 return (KADM_JNI_CLASS);
1457 intclass = (*env)->FindClass(env, "java/lang/Integer");
1458 if (!intclass)
1459 return (KADM_JNI_CLASS);
1460
1461 f = (*env)->GetFieldID(env, pocl, "PolicyName", "Ljava/lang/String;");
1462 if (!f)
1463 return (KADM_JNI_FIELD);
1464 obj = (*env)->GetObjectField(env, pol, f);
1465 if (!obj)
1466 return (KADM_JNI_OFIELD);
1467 s = (jstring)obj;
1468 str = (*env)->GetStringUTFChars(env, s, NULL);
1469 if (!str)
1470 return (KADM_JNI_STRING);
1471 p->policy = strdup(str);
1472 if (!p->policy)
1473 return (KADM_ENOMEM);
1474 if (new)
1475 *mask |= KADM5_POLICY;
1476 (*env)->ReleaseStringUTFChars(env, s, str);
1477
1478 f = (*env)->GetFieldID(env, pocl, "PwMinLife", "Ljava/lang/Integer;");
1479 if (!f)
1480 return (KADM_JNI_FIELD);
1481 obj = (*env)->GetObjectField(env, pol, f);
1482 if (!obj)
1483 return (KADM_JNI_OFIELD);
1484 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1485 if (!mid)
1486 return (KADM_JNI_METHOD);
1487 i = (*env)->CallIntMethod(env, obj, mid);
1488 p->pw_min_life = i;
1489 *mask |= KADM5_PW_MIN_LIFE;
1490
1491 f = (*env)->GetFieldID(env, pocl, "PwMaxLife", "Ljava/lang/Integer;");
1492 if (!f)
1493 return (KADM_JNI_FIELD);
1494 obj = (*env)->GetObjectField(env, pol, f);
1495 if (!obj)
1496 return (KADM_JNI_OFIELD);
1497 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1498 if (!mid)
1499 return (KADM_JNI_METHOD);
1500 i = (*env)->CallIntMethod(env, obj, mid);
1501 p->pw_max_life = i;
1502 *mask |= KADM5_PW_MAX_LIFE;
1503
1504 f = (*env)->GetFieldID(env, pocl, "PwMinLength", "Ljava/lang/Integer;");
1505 if (!f)
1506 return (KADM_JNI_FIELD);
1507 obj = (*env)->GetObjectField(env, pol, f);
1508 if (!obj)
1509 return (KADM_JNI_OFIELD);
1510 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1511 if (!mid)
1512 return (KADM_JNI_METHOD);
1513 i = (*env)->CallIntMethod(env, obj, mid);
1514 p->pw_min_length = i;
1515 *mask |= KADM5_PW_MIN_LENGTH;
1516
1517 f = (*env)->GetFieldID(env, pocl, "PwMinClasses",
1518 "Ljava/lang/Integer;");
1519 if (!f)
1520 return (KADM_JNI_FIELD);
1521 obj = (*env)->GetObjectField(env, pol, f);
1522 if (!obj)
1523 return (KADM_JNI_OFIELD);
1524 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1525 if (!mid)
1526 return (KADM_JNI_METHOD);
1527 i = (*env)->CallIntMethod(env, obj, mid);
1528 p->pw_min_classes = i;
1529 *mask |= KADM5_PW_MIN_CLASSES;
1530
1531 f = (*env)->GetFieldID(env, pocl, "PwSaveCount", "Ljava/lang/Integer;");
1532 if (!f)
1533 return (KADM_JNI_FIELD);
1534 obj = (*env)->GetObjectField(env, pol, f);
1535 if (!obj)
1536 return (KADM_JNI_OFIELD);
1537 mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
1538 if (!mid)
1539 return (KADM_JNI_METHOD);
1540 i = (*env)->CallIntMethod(env, obj, mid);
1541 p->pw_history_num = i;
1542 *mask |= KADM5_PW_HISTORY_NUM;
1543
1544 return (0);
1545 }
1546
1547 static int
kadmin_to_Policy(kadm5_policy_ent_rec * p,JNIEnv * env,jobject pol)1548 kadmin_to_Policy(kadm5_policy_ent_rec *p, JNIEnv *env, jobject pol)
1549 {
1550 jstring s;
1551 jclass pocl, intclass;
1552 jfieldID f;
1553 jmethodID mid;
1554 jobject obj;
1555
1556 pocl = (*env)->GetObjectClass(env, pol);
1557 if (!pocl)
1558 return (KADM_JNI_CLASS);
1559 intclass = (*env)->FindClass(env, "java/lang/Integer");
1560 if (!intclass)
1561 return (KADM_JNI_CLASS);
1562
1563 f = (*env)->GetFieldID(env, pocl, "PolicyName", "Ljava/lang/String;");
1564 if (!f)
1565 return (KADM_JNI_FIELD);
1566 s = (*env)->NewStringUTF(env, p->policy);
1567 if (!s)
1568 return (KADM_JNI_NEWSTRING);
1569 (*env)->SetObjectField(env, pol, f, s);
1570
1571 f = (*env)->GetFieldID(env, pocl, "PwMinLife", "Ljava/lang/Integer;");
1572 if (!f)
1573 return (KADM_JNI_FIELD);
1574 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1575 if (!mid)
1576 return (KADM_JNI_METHOD);
1577 obj = (*env)->NewObject(env, intclass, mid, p->pw_min_life);
1578 if (!obj)
1579 return (KADM_JNI_OBJECT);
1580 (*env)->SetObjectField(env, pol, f, obj);
1581
1582 f = (*env)->GetFieldID(env, pocl, "PwMaxLife", "Ljava/lang/Integer;");
1583 if (!f)
1584 return (KADM_JNI_FIELD);
1585 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1586 if (!mid)
1587 return (KADM_JNI_METHOD);
1588 obj = (*env)->NewObject(env, intclass, mid, p->pw_max_life);
1589 if (!obj)
1590 return (KADM_JNI_OBJECT);
1591 (*env)->SetObjectField(env, pol, f, obj);
1592
1593 f = (*env)->GetFieldID(env, pocl, "PwMinLength", "Ljava/lang/Integer;");
1594 if (!f)
1595 return (KADM_JNI_FIELD);
1596 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1597 if (!mid)
1598 return (KADM_JNI_METHOD);
1599 obj = (*env)->NewObject(env, intclass, mid, p->pw_min_length);
1600 if (!obj)
1601 return (KADM_JNI_OBJECT);
1602 (*env)->SetObjectField(env, pol, f, obj);
1603
1604 f = (*env)->GetFieldID(env, pocl, "PwMinClasses",
1605 "Ljava/lang/Integer;");
1606 if (!f)
1607 return (KADM_JNI_FIELD);
1608 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1609 if (!mid)
1610 return (KADM_JNI_METHOD);
1611 obj = (*env)->NewObject(env, intclass, mid, p->pw_min_classes);
1612 if (!obj)
1613 return (KADM_JNI_OBJECT);
1614 (*env)->SetObjectField(env, pol, f, obj);
1615
1616 f = (*env)->GetFieldID(env, pocl, "PwSaveCount", "Ljava/lang/Integer;");
1617 if (!f)
1618 return (KADM_JNI_FIELD);
1619 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1620 if (!mid)
1621 return (KADM_JNI_METHOD);
1622 obj = (*env)->NewObject(env, intclass, mid, p->pw_history_num);
1623 if (!obj)
1624 return (KADM_JNI_OBJECT);
1625 (*env)->SetObjectField(env, pol, f, obj);
1626
1627 f = (*env)->GetFieldID(env, pocl, "RefCount", "Ljava/lang/Integer;");
1628 if (!f)
1629 return (KADM_JNI_FIELD);
1630 mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
1631 if (!mid)
1632 return (KADM_JNI_METHOD);
1633 obj = (*env)->NewObject(env, intclass, mid, p->policy_refcnt);
1634 if (!obj)
1635 return (KADM_JNI_OBJECT);
1636 (*env)->SetObjectField(env, pol, f, obj);
1637
1638 return (0);
1639 }
1640
1641 #define SUNSOFT_COMMENTS 256
1642
1643 /*
1644 * The new principal has been saved; now we do a load-modify-store
1645 * to get the comments into the TL_DATA array.
1646 */
1647 static int
edit_comments(kadm5_principal_ent_rec * p,krb5_principal kprin,char * comments)1648 edit_comments(kadm5_principal_ent_rec *p, krb5_principal kprin, char *comments)
1649 {
1650 long mask = KADM5_PRINCIPAL | KADM5_TL_DATA;
1651 kadm5_ret_t ret;
1652
1653 if (!comments || !strlen(comments))
1654 return (0);
1655
1656 ret = kadm5_get_principal(server_handle, kprin, p, mask);
1657 if (ret)
1658 return (ret);
1659
1660 mask = 0;
1661 ret = format_comments(p, &mask, comments);
1662 if (ret)
1663 return (ret);
1664
1665 if (mask) {
1666 ret = kadm5_modify_principal(server_handle, p, mask);
1667 if (ret)
1668 return (ret);
1669 }
1670
1671 return (0);
1672 }
1673
1674 /*
1675 * Put the comments into TL_DATA.
1676 */
1677 static int
format_comments(kadm5_principal_ent_rec * p,long * mask,char * comments)1678 format_comments(kadm5_principal_ent_rec *p, long *mask, char *comments)
1679 {
1680 krb5_tl_data *t, *t1, *tdp;
1681 char *s;
1682
1683 if (!comments || !strlen(comments))
1684 return (0);
1685 tdp = malloc(sizeof (krb5_tl_data));
1686 if (!tdp)
1687 return (KADM_ENOMEM);
1688 s = strdup(comments);
1689 if (!s)
1690 return (KADM_ENOMEM);
1691
1692 /*
1693 * Search for existing comments field, or find next-to-last
1694 */
1695 for (t = t1 = p->tl_data; t; t1 = t, t = t->tl_data_next)
1696 if (t->tl_data_type == SUNSOFT_COMMENTS)
1697 break;
1698 if (t) {
1699 t->tl_data_length = strlen(comments);
1700 free(t->tl_data_contents);
1701 t->tl_data_contents = (krb5_octet *)s;
1702 } else {
1703 tdp->tl_data_next = NULL;
1704 tdp->tl_data_type = SUNSOFT_COMMENTS;
1705 tdp->tl_data_length = strlen(comments)+1;
1706 tdp->tl_data_contents = (krb5_octet *)s;
1707 if (t1)
1708 t1->tl_data_next = tdp;
1709 else
1710 p->tl_data = tdp;
1711 p->n_tl_data++;
1712 }
1713 *mask |= KADM5_TL_DATA;
1714 return (0);
1715 }
1716
1717 /*
1718 * The principal has been loaded, so we pluck the comments out of TL_DATA.
1719 */
1720 static int
extract_comments(kadm5_principal_ent_rec * p,char ** comments)1721 extract_comments(kadm5_principal_ent_rec *p, char **comments)
1722 {
1723 krb5_tl_data *t;
1724 char *s;
1725
1726 /*
1727 * Search for existing comments field, or find next-to-last
1728 */
1729 if (!p->n_tl_data)
1730 return (0);
1731 for (t = p->tl_data; t; t = t->tl_data_next)
1732 if (t->tl_data_type == SUNSOFT_COMMENTS)
1733 break;
1734 if (t && t->tl_data_length) {
1735 s = strdup((char *)t->tl_data_contents);
1736 if (!s)
1737 return (KADM_ENOMEM);
1738 s[t->tl_data_length] = 0;
1739 *comments = s;
1740 }
1741 return (0);
1742 }
1743
1744 /*
1745 * Set password for the modified principal
1746 */
1747 static int
set_password(krb5_principal kprin,char * pw,kadm5_config_params * pparams)1748 set_password(krb5_principal kprin, char *pw, kadm5_config_params *pparams)
1749 {
1750 kadm5_ret_t ret;
1751 int keepold = 0;
1752
1753 if (!pw || !strlen(pw))
1754 return (0);
1755
1756 if (pparams->mask & KADM5_CONFIG_ENCTYPES)
1757 ret = kadm5_chpass_principal_3(server_handle, kprin, keepold,
1758 pparams->num_keysalts, pparams->keysalts, pw);
1759 else
1760 ret = kadm5_chpass_principal(server_handle, kprin, pw);
1761
1762 if (ret)
1763 return (ret);
1764 return (0);
1765 }
1766
1767 static void
handle_error(JNIEnv * env,int error)1768 handle_error(JNIEnv *env, int error)
1769 {
1770 char *s;
1771 char from[BUFSIZ], to[BUFSIZ];
1772 char *tptr;
1773 const char *fptr;
1774 size_t ileft, oleft, ret;
1775
1776 s = (char *)error_message(error);
1777 /* fprintf(stderr, "Kadmin: %s (%d)\n", s, error); XXX */
1778 if (cd != (iconv_t)-1) {
1779 ileft = strlen(s);
1780 strncpy(from, s, ileft);
1781 fptr = from;
1782 oleft = BUFSIZ;
1783 tptr = to;
1784 ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
1785 if (ret != (size_t)-1) {
1786 to[BUFSIZ-oleft] = '\0';
1787 s = to;
1788 /* fprintf(stderr, "Kadmin: %s (%d)\n", s, error); XXX */
1789 }
1790 }
1791 (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/Exception"),
1792 (const char *)s);
1793 }
1794