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