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 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <jni.h> 29 #include <kadm5/admin.h> 30 #include <adm_err.h> 31 #include <sys/signal.h> 32 #include <netdb.h> 33 #include <iconv.h> 34 #include <langinfo.h> 35 #include <clnt/client_internal.h> 36 #include <etypes.h> 37 38 static int Principal_to_kadmin(JNIEnv *, jobject, int, krb5_principal *, 39 kadm5_principal_ent_rec *, long *, char **, char **, 40 kadm5_config_params *); 41 static int kadmin_to_Principal(kadm5_principal_ent_rec *, JNIEnv *, jobject, 42 const char *, char *); 43 static int Policy_to_kadmin(JNIEnv *, jobject, int, kadm5_policy_ent_rec *, 44 long *); 45 static int kadmin_to_Policy(kadm5_policy_ent_rec *, JNIEnv *, jobject); 46 static int edit_comments(kadm5_principal_ent_rec *, krb5_principal, char *); 47 static int format_comments(kadm5_principal_ent_rec *, long *, char *); 48 static int extract_comments(kadm5_principal_ent_rec *, char **); 49 static int set_password(krb5_principal, char *, kadm5_config_params *); 50 static void handle_error(JNIEnv *, int); 51 static char *qualify(char *name); 52 53 static void *server_handle = NULL; 54 static char *cur_realm = NULL; 55 56 static iconv_t cd = (iconv_t)-1; 57 58 static char * 59 qualify(char *name) 60 { 61 char *fullname; 62 int len; 63 64 if (strchr(name, '@') != NULL) 65 return (strdup(name)); 66 len = strlen(name) + strlen(cur_realm) + 2; 67 fullname = malloc(len); 68 if (fullname) 69 snprintf(fullname, len, "%s@%s", name, cur_realm); 70 return (fullname); 71 } 72 73 74 /* 75 * Class: Kadmin 76 * Method: sessionInit 77 * Signature: 78 * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z 79 */ 80 /*ARGSUSED*/ 81 JNIEXPORT jboolean JNICALL 82 Java_Kadmin_sessionInit(JNIEnv *env, jobject obj, jstring name, 83 jstring passwd, jstring realm, jstring server, jint port) 84 { 85 const char *cname = NULL, *cpasswd = NULL; 86 const char *crealm = NULL, *cserver = NULL; 87 int cport = 749; 88 kadm5_config_params params; 89 kadm5_ret_t ret; 90 char *ka_service = NULL; 91 char *ka_name = NULL; 92 char *codeset; 93 int len; 94 95 if (server_handle != NULL) 96 kadm5_destroy(server_handle); 97 98 if (cd == (iconv_t)-1) { 99 codeset = nl_langinfo(CODESET); 100 /* fprintf(stderr, "codeset returned %s\n", codeset); XXX */ 101 if (strcmp("UTF-8", codeset) != 0) 102 cd = iconv_open("UTF-8", codeset); 103 } 104 105 /* Get hold of string arguments */ 106 cname = (*env)->GetStringUTFChars(env, name, NULL); 107 if (!cname) { 108 ret = KADM_JNI_STRING; 109 goto err; 110 } 111 cpasswd = (*env)->GetStringUTFChars(env, passwd, NULL); 112 if (!cpasswd) { 113 ret = KADM_JNI_STRING; 114 goto err; 115 } 116 crealm = (*env)->GetStringUTFChars(env, realm, NULL); 117 if (!crealm) { 118 ret = KADM_JNI_STRING; 119 goto err; 120 } 121 if (cur_realm) 122 free(cur_realm); 123 cur_realm = strdup(crealm); 124 cserver = (*env)->GetStringUTFChars(env, server, NULL); 125 if (!cserver) { 126 ret = KADM_JNI_STRING; 127 goto err; 128 } 129 if (port != 0) 130 cport = port; 131 else { 132 /* 133 * Look for a services map entry 134 * Note that this will be in network byte order, 135 * and that the API requires native byte order. 136 */ 137 struct servent *rec = getservbyname("kerberos-adm", NULL); 138 if (rec) 139 cport = (int)ntohs((uint16_t)rec->s_port); 140 } 141 142 /* 143 * Build kadm5_config_params with realm name and server name 144 */ 145 memset((char *)¶ms, 0, sizeof (params)); 146 params.realm = (char *)crealm; 147 params.admin_server = (char *)cserver; 148 params.mask = KADM5_CONFIG_REALM | KADM5_CONFIG_ADMIN_SERVER; 149 params.kadmind_port = cport; 150 params.mask |= KADM5_CONFIG_KADMIND_PORT; 151 len = strlen("kadmin") + strlen(cserver) + 2; 152 ka_service = malloc(len); 153 if (!ka_service) { 154 ret = KADM_ENOMEM; 155 goto err; 156 } 157 snprintf(ka_service, len, "%s@%s", "kadmin", cserver); 158 ka_name = qualify((char *)cname); 159 if (!ka_name) { 160 ret = KADM_ENOMEM; 161 goto err; 162 } 163 164 ret = kadm5_init_with_password(ka_name, (char *)cpasswd, 165 ka_service, ¶ms, KADM5_STRUCT_VERSION, 166 KADM5_API_VERSION_2, NULL, &server_handle); 167 168 /* Release string arguments and variables */ 169 if (cname) 170 (*env)->ReleaseStringUTFChars(env, name, cname); 171 if (cpasswd) 172 (*env)->ReleaseStringUTFChars(env, passwd, cpasswd); 173 if (crealm) 174 (*env)->ReleaseStringUTFChars(env, realm, crealm); 175 if (cserver) 176 (*env)->ReleaseStringUTFChars(env, server, cserver); 177 if (ka_name) 178 free(ka_name); 179 if (ka_service) 180 free(ka_service); 181 182 err: 183 if (ret) { 184 handle_error(env, ret); 185 return (JNI_FALSE); 186 } 187 return (JNI_TRUE); 188 } 189 190 /* 191 * Class: Kadmin 192 * Method: sessionExit 193 * Signature: ()V 194 */ 195 /*ARGSUSED*/ 196 JNIEXPORT void JNICALL 197 Java_Kadmin_sessionExit(JNIEnv *env, jobject obj) 198 { 199 kadm5_ret_t ret; 200 201 /* 202 * Use persistant handle to close 203 */ 204 ret = kadm5_destroy(server_handle); 205 if (ret) 206 handle_error(env, ret); 207 server_handle = NULL; 208 if (cur_realm) { 209 free(cur_realm); 210 cur_realm = NULL; 211 } 212 } 213 214 /* 215 * Class: Kadmin 216 * Method: getPrivs 217 * Signature: ()I 218 */ 219 /*ARGSUSED*/ 220 JNIEXPORT jint JNICALL 221 Java_Kadmin_getPrivs(JNIEnv *env, jobject obj) 222 { 223 long privs = 0; 224 kadm5_ret_t ret; 225 226 /* 227 * Get ACL for this user 228 */ 229 ret = kadm5_get_privs(server_handle, &privs); 230 if (ret) 231 handle_error(env, ret); 232 return (privs); 233 } 234 235 static int 236 charcmp(const void *a, const void *b) 237 { 238 char **sa = (char **)a; 239 char **sb = (char **)b; 240 241 return (strcmp(*sa, *sb)); 242 } 243 244 /* 245 * Class: Kadmin 246 * Method: getEncList 247 * Signature: ()[Ljava/lang/String; 248 */ 249 250 /*ARGSUSED*/ 251 JNIEXPORT jobjectArray JNICALL 252 Java_Kadmin_getEncList(JNIEnv *env, 253 jobject obj) 254 { 255 jclass stringclass; 256 jobjectArray elist; 257 jstring s; 258 kadm5_ret_t ret; 259 int i, j, k, *grp = NULL; 260 krb5_int32 num_keysalts; 261 krb5_key_salt_tuple *keysalts; 262 krb5_enctype e_type; 263 kadm5_server_handle_t handle; 264 char *e_str, e_buf[BUFSIZ]; 265 krb5_error_code kret; 266 krb5_boolean similar; 267 krb5_context context; 268 269 if (kret = krb5_init_context(&context)) { 270 handle_error(env, kret); 271 return (NULL); 272 } 273 274 /* 275 * Create and populate a Java String array 276 */ 277 stringclass = (*env)->FindClass(env, "java/lang/String"); 278 if (!stringclass) { 279 handle_error(env, KADM_JNI_CLASS); 280 return (NULL); 281 } 282 283 handle = server_handle; 284 num_keysalts = handle->params.num_keysalts; 285 keysalts = handle->params.keysalts; 286 elist = (*env)->NewObjectArray(env, num_keysalts, stringclass, NULL); 287 if (!elist) { 288 handle_error(env, KADM_JNI_ARRAY); 289 return (NULL); 290 } 291 292 /* 293 * Populate groupings for encryption types that are similar. 294 */ 295 grp = malloc(sizeof (int) * num_keysalts); 296 if (grp == NULL) { 297 handle_error(env, errno); 298 return (NULL); 299 } 300 for (i = 0; i < num_keysalts; grp[i] = i++); 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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