xref: /onnv-gate/usr/src/cmd/krb5/kadmin/gui/native/Kadmin.c (revision 4960:a4746a82a247)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*4960Swillf  * Common Development and Distribution License (the "License").
6*4960Swillf  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*4960Swillf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2396Ssemery  * Use is subject to license terms.
240Sstevel@tonic-gate  */
2596Ssemery 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <jni.h>
290Sstevel@tonic-gate #include <kadm5/admin.h>
300Sstevel@tonic-gate #include <adm_err.h>
310Sstevel@tonic-gate #include <sys/signal.h>
320Sstevel@tonic-gate #include <netdb.h>
330Sstevel@tonic-gate #include <iconv.h>
340Sstevel@tonic-gate #include <langinfo.h>
3596Ssemery #include <clnt/client_internal.h>
3696Ssemery #include <etypes.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate static int Principal_to_kadmin(JNIEnv *, jobject, int, krb5_principal *,
3996Ssemery 	kadm5_principal_ent_rec *, long *, char **, char **,
4096Ssemery 	kadm5_config_params *);
410Sstevel@tonic-gate static int kadmin_to_Principal(kadm5_principal_ent_rec *, JNIEnv *, jobject,
420Sstevel@tonic-gate 	const char *, char *);
430Sstevel@tonic-gate static int Policy_to_kadmin(JNIEnv *, jobject, int, kadm5_policy_ent_rec *,
440Sstevel@tonic-gate 	long *);
450Sstevel@tonic-gate static int kadmin_to_Policy(kadm5_policy_ent_rec *, JNIEnv *, jobject);
460Sstevel@tonic-gate static int edit_comments(kadm5_principal_ent_rec *, krb5_principal, char *);
470Sstevel@tonic-gate static int format_comments(kadm5_principal_ent_rec *, long *, char *);
480Sstevel@tonic-gate static int extract_comments(kadm5_principal_ent_rec *, char **);
4996Ssemery static int set_password(krb5_principal, char *, kadm5_config_params *);
500Sstevel@tonic-gate static void handle_error(JNIEnv *, int);
510Sstevel@tonic-gate static char *qualify(char *name);
520Sstevel@tonic-gate 
530Sstevel@tonic-gate static void *server_handle = NULL;
540Sstevel@tonic-gate static char *cur_realm = NULL;
550Sstevel@tonic-gate 
560Sstevel@tonic-gate static iconv_t cd = (iconv_t)-1;
570Sstevel@tonic-gate 
580Sstevel@tonic-gate static char *
qualify(char * name)590Sstevel@tonic-gate qualify(char *name)
600Sstevel@tonic-gate {
610Sstevel@tonic-gate 	char *fullname;
620Sstevel@tonic-gate 	int len;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	if (strchr(name, '@') != NULL)
650Sstevel@tonic-gate 		return (strdup(name));
660Sstevel@tonic-gate 	len = strlen(name) + strlen(cur_realm) + 2;
670Sstevel@tonic-gate 	fullname = malloc(len);
680Sstevel@tonic-gate 	if (fullname)
690Sstevel@tonic-gate 		snprintf(fullname, len, "%s@%s", name, cur_realm);
700Sstevel@tonic-gate 	return (fullname);
710Sstevel@tonic-gate }
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 
740Sstevel@tonic-gate /*
750Sstevel@tonic-gate  * Class:     Kadmin
760Sstevel@tonic-gate  * Method:    sessionInit
770Sstevel@tonic-gate  * Signature:
780Sstevel@tonic-gate  * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
790Sstevel@tonic-gate  */
800Sstevel@tonic-gate /*ARGSUSED*/
810Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_sessionInit(JNIEnv * env,jobject obj,jstring name,jstring passwd,jstring realm,jstring server,jint port)820Sstevel@tonic-gate Java_Kadmin_sessionInit(JNIEnv *env, jobject obj, jstring name,
830Sstevel@tonic-gate 	jstring passwd, jstring realm, jstring server, jint port)
840Sstevel@tonic-gate {
850Sstevel@tonic-gate 	const char *cname = NULL, *cpasswd = NULL;
860Sstevel@tonic-gate 	const char *crealm = NULL, *cserver = NULL;
870Sstevel@tonic-gate 	int cport = 749;
880Sstevel@tonic-gate 	kadm5_config_params params;
890Sstevel@tonic-gate 	kadm5_ret_t ret;
900Sstevel@tonic-gate 	char *ka_service = NULL;
910Sstevel@tonic-gate 	char *ka_name = NULL;
920Sstevel@tonic-gate 	char *codeset;
930Sstevel@tonic-gate 	int len;
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	if (server_handle != NULL)
960Sstevel@tonic-gate 		kadm5_destroy(server_handle);
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	if (cd == (iconv_t)-1) {
990Sstevel@tonic-gate 		codeset = nl_langinfo(CODESET);
1000Sstevel@tonic-gate 		/* fprintf(stderr, "codeset returned %s\n", codeset);  XXX */
1010Sstevel@tonic-gate 		if (strcmp("UTF-8", codeset) != 0)
1020Sstevel@tonic-gate 			cd = iconv_open("UTF-8", codeset);
1030Sstevel@tonic-gate 	}
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 	/* Get hold of string arguments */
1060Sstevel@tonic-gate 	cname = (*env)->GetStringUTFChars(env, name, NULL);
1070Sstevel@tonic-gate 	if (!cname) {
1080Sstevel@tonic-gate 		ret = KADM_JNI_STRING;
1090Sstevel@tonic-gate 		goto err;
1100Sstevel@tonic-gate 	}
1110Sstevel@tonic-gate 	cpasswd = (*env)->GetStringUTFChars(env, passwd, NULL);
1120Sstevel@tonic-gate 	if (!cpasswd) {
1130Sstevel@tonic-gate 		ret = KADM_JNI_STRING;
1140Sstevel@tonic-gate 		goto err;
1150Sstevel@tonic-gate 	}
1160Sstevel@tonic-gate 	crealm = (*env)->GetStringUTFChars(env, realm, NULL);
1170Sstevel@tonic-gate 	if (!crealm) {
1180Sstevel@tonic-gate 		ret = KADM_JNI_STRING;
1190Sstevel@tonic-gate 		goto err;
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate 	if (cur_realm)
1220Sstevel@tonic-gate 		free(cur_realm);
1230Sstevel@tonic-gate 	cur_realm = strdup(crealm);
1240Sstevel@tonic-gate 	cserver = (*env)->GetStringUTFChars(env, server, NULL);
1250Sstevel@tonic-gate 	if (!cserver) {
1260Sstevel@tonic-gate 		ret = KADM_JNI_STRING;
1270Sstevel@tonic-gate 		goto err;
1280Sstevel@tonic-gate 	}
1290Sstevel@tonic-gate 	if (port != 0)
1300Sstevel@tonic-gate 		cport = port;
1310Sstevel@tonic-gate 	else {
1320Sstevel@tonic-gate 		/*
1330Sstevel@tonic-gate 		 * Look for a services map entry
1340Sstevel@tonic-gate 		 * Note that this will be in network byte order,
1350Sstevel@tonic-gate 		 * and that the API requires native byte order.
1360Sstevel@tonic-gate 		 */
1370Sstevel@tonic-gate 		struct servent *rec = getservbyname("kerberos-adm", NULL);
1380Sstevel@tonic-gate 		if (rec)
1390Sstevel@tonic-gate 			cport = (int)ntohs((uint16_t)rec->s_port);
1400Sstevel@tonic-gate 	}
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	/*
1430Sstevel@tonic-gate 	 * Build kadm5_config_params with realm name and server name
1440Sstevel@tonic-gate 	 */
1450Sstevel@tonic-gate 	memset((char *)&params, 0, sizeof (params));
1460Sstevel@tonic-gate 	params.realm = (char *)crealm;
1470Sstevel@tonic-gate 	params.admin_server = (char *)cserver;
1480Sstevel@tonic-gate 	params.mask = KADM5_CONFIG_REALM | KADM5_CONFIG_ADMIN_SERVER;
1490Sstevel@tonic-gate 	params.kadmind_port = cport;
1500Sstevel@tonic-gate 	params.mask |= KADM5_CONFIG_KADMIND_PORT;
1510Sstevel@tonic-gate 	len = strlen("kadmin") + strlen(cserver) + 2;
1520Sstevel@tonic-gate 	ka_service = malloc(len);
1530Sstevel@tonic-gate 	if (!ka_service) {
1540Sstevel@tonic-gate 		ret = KADM_ENOMEM;
1550Sstevel@tonic-gate 		goto err;
1560Sstevel@tonic-gate 	}
1570Sstevel@tonic-gate 	snprintf(ka_service, len, "%s@%s", "kadmin", cserver);
1580Sstevel@tonic-gate 	ka_name = qualify((char *)cname);
1590Sstevel@tonic-gate 	if (!ka_name) {
1600Sstevel@tonic-gate 		ret = KADM_ENOMEM;
1610Sstevel@tonic-gate 		goto err;
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	ret = kadm5_init_with_password(ka_name, (char *)cpasswd,
1650Sstevel@tonic-gate 				ka_service, &params, KADM5_STRUCT_VERSION,
166*4960Swillf 				KADM5_API_VERSION_2, NULL, &server_handle);
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	/* Release string arguments and variables */
1690Sstevel@tonic-gate 	if (cname)
1700Sstevel@tonic-gate 		(*env)->ReleaseStringUTFChars(env, name, cname);
1710Sstevel@tonic-gate 	if (cpasswd)
1720Sstevel@tonic-gate 		(*env)->ReleaseStringUTFChars(env, passwd, cpasswd);
1730Sstevel@tonic-gate 	if (crealm)
1740Sstevel@tonic-gate 		(*env)->ReleaseStringUTFChars(env, realm, crealm);
1750Sstevel@tonic-gate 	if (cserver)
1760Sstevel@tonic-gate 		(*env)->ReleaseStringUTFChars(env, server, cserver);
1770Sstevel@tonic-gate 	if (ka_name)
1780Sstevel@tonic-gate 		free(ka_name);
1790Sstevel@tonic-gate 	if (ka_service)
1800Sstevel@tonic-gate 		free(ka_service);
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate err:
1830Sstevel@tonic-gate 	if (ret) {
1840Sstevel@tonic-gate 		handle_error(env, ret);
1850Sstevel@tonic-gate 		return (JNI_FALSE);
1860Sstevel@tonic-gate 	}
1870Sstevel@tonic-gate 	return (JNI_TRUE);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate /*
1910Sstevel@tonic-gate  * Class:     Kadmin
1920Sstevel@tonic-gate  * Method:    sessionExit
1930Sstevel@tonic-gate  * Signature: ()V
1940Sstevel@tonic-gate  */
1950Sstevel@tonic-gate /*ARGSUSED*/
1960Sstevel@tonic-gate JNIEXPORT void JNICALL
Java_Kadmin_sessionExit(JNIEnv * env,jobject obj)1970Sstevel@tonic-gate Java_Kadmin_sessionExit(JNIEnv *env, jobject obj)
1980Sstevel@tonic-gate {
1990Sstevel@tonic-gate 	kadm5_ret_t ret;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	/*
2020Sstevel@tonic-gate 	 * Use persistant handle to close
2030Sstevel@tonic-gate 	 */
2040Sstevel@tonic-gate 	ret = kadm5_destroy(server_handle);
2050Sstevel@tonic-gate 	if (ret)
2060Sstevel@tonic-gate 		handle_error(env, ret);
2070Sstevel@tonic-gate 	server_handle = NULL;
2080Sstevel@tonic-gate 	if (cur_realm) {
2090Sstevel@tonic-gate 		free(cur_realm);
2100Sstevel@tonic-gate 		cur_realm = NULL;
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate  * Class:     Kadmin
2160Sstevel@tonic-gate  * Method:    getPrivs
2170Sstevel@tonic-gate  * Signature: ()I
2180Sstevel@tonic-gate  */
2190Sstevel@tonic-gate /*ARGSUSED*/
2200Sstevel@tonic-gate JNIEXPORT jint JNICALL
Java_Kadmin_getPrivs(JNIEnv * env,jobject obj)2210Sstevel@tonic-gate Java_Kadmin_getPrivs(JNIEnv *env, jobject obj)
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate 	long privs = 0;
2240Sstevel@tonic-gate 	kadm5_ret_t ret;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	/*
2270Sstevel@tonic-gate 	 * Get ACL for this user
2280Sstevel@tonic-gate 	 */
2290Sstevel@tonic-gate 	ret = kadm5_get_privs(server_handle, &privs);
2300Sstevel@tonic-gate 	if (ret)
2310Sstevel@tonic-gate 		handle_error(env, ret);
2320Sstevel@tonic-gate 	return (privs);
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate static int
charcmp(const void * a,const void * b)2360Sstevel@tonic-gate charcmp(const void *a, const void *b)
2370Sstevel@tonic-gate {
2380Sstevel@tonic-gate 	char    **sa = (char **)a;
2390Sstevel@tonic-gate 	char    **sb = (char **)b;
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate 	return (strcmp(*sa, *sb));
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate /*
2450Sstevel@tonic-gate  * Class:     Kadmin
24696Ssemery  * Method:    getEncList
24796Ssemery  * Signature: ()[Ljava/lang/String;
24896Ssemery  */
24996Ssemery 
25096Ssemery /*ARGSUSED*/
25196Ssemery JNIEXPORT jobjectArray JNICALL
Java_Kadmin_getEncList(JNIEnv * env,jobject obj)25296Ssemery Java_Kadmin_getEncList(JNIEnv *env,
25396Ssemery 	jobject obj)
25496Ssemery {
25596Ssemery 	jclass stringclass;
25696Ssemery 	jobjectArray elist;
25796Ssemery 	jstring s;
25896Ssemery 	kadm5_ret_t ret;
25996Ssemery 	int i, j, k, *grp = NULL;
26096Ssemery 	krb5_int32 num_keysalts;
26196Ssemery 	krb5_key_salt_tuple *keysalts;
26296Ssemery 	krb5_enctype e_type;
26396Ssemery 	kadm5_server_handle_t handle;
26496Ssemery 	char *e_str, e_buf[BUFSIZ];
26596Ssemery 	krb5_error_code kret;
26696Ssemery 	krb5_boolean similar;
26796Ssemery 	krb5_context context;
26896Ssemery 
26996Ssemery 	if (kret = krb5_init_context(&context)) {
27096Ssemery 		handle_error(env, kret);
27196Ssemery 		return (NULL);
27296Ssemery 	}
27396Ssemery 
27496Ssemery 	/*
27596Ssemery 	 * Create and populate a Java String array
27696Ssemery 	 */
27796Ssemery 	stringclass = (*env)->FindClass(env, "java/lang/String");
27896Ssemery 	if (!stringclass) {
27996Ssemery 		handle_error(env, KADM_JNI_CLASS);
28096Ssemery 		return (NULL);
28196Ssemery 	}
28296Ssemery 
28396Ssemery 	handle = server_handle;
28496Ssemery 	num_keysalts = handle->params.num_keysalts;
28596Ssemery 	keysalts = handle->params.keysalts;
28696Ssemery 	elist = (*env)->NewObjectArray(env, num_keysalts, stringclass, NULL);
28796Ssemery 	if (!elist) {
28896Ssemery 		handle_error(env, KADM_JNI_ARRAY);
28996Ssemery 		return (NULL);
29096Ssemery 	}
29196Ssemery 
29296Ssemery 	/*
29396Ssemery 	 * Populate groupings for encryption types that are similar.
29496Ssemery 	 */
29596Ssemery 	grp = malloc(sizeof (int) * num_keysalts);
29696Ssemery 	if (grp == NULL) {
29796Ssemery 		handle_error(env, errno);
29896Ssemery 		return (NULL);
29996Ssemery 	}
30096Ssemery 	for (i = 0; i < num_keysalts; grp[i] = i++);
30196Ssemery 	for (i = 0; i < num_keysalts; i++) {
30296Ssemery 		if (grp[i] != i)
30396Ssemery 			continue;
30496Ssemery 		for (j = i + 1; j < num_keysalts; j++) {
30596Ssemery 			if (kret = krb5_c_enctype_compare(context,
30696Ssemery 			    keysalts[i].ks_enctype, keysalts[j].ks_enctype,
30796Ssemery 			    &similar)) {
30896Ssemery 				free(grp);
30996Ssemery 				handle_error(env, kret);
31096Ssemery 				return (NULL);
31196Ssemery 			}
31296Ssemery 			if (similar)
31396Ssemery 				grp[j] = grp[i];
31496Ssemery 		}
31596Ssemery 	}
31696Ssemery 
31796Ssemery 	/*
31896Ssemery 	 * Populate from params' supported enc type list from the initial kadmin
31996Ssemery 	 * session, this is documented default that the client can handle.
32096Ssemery 	 */
32196Ssemery 	for (i = 0; i < num_keysalts; i++) {
32296Ssemery 		e_type = keysalts[i].ks_enctype;
32396Ssemery 
32496Ssemery 		for (j = 0; j < krb5_enctypes_length; j++) {
32596Ssemery 			if (e_type == krb5_enctypes_list[j].etype) {
32696Ssemery 				e_str = krb5_enctypes_list[j].in_string;
32796Ssemery 				(void) snprintf(e_buf, sizeof (e_buf),
32896Ssemery 				    "%d %s:normal", grp[i], e_str);
32996Ssemery 				s = (*env)->NewStringUTF(env, e_buf);
33096Ssemery 				if (!s) {
33196Ssemery 					free(grp);
33296Ssemery 					handle_error(env, KADM_JNI_NEWSTRING);
33396Ssemery 					return (NULL);
33496Ssemery 				}
33596Ssemery 				(*env)->SetObjectArrayElement(env, elist, i, s);
33696Ssemery 				break;
33796Ssemery 			}
33896Ssemery 		}
33996Ssemery 	}
34096Ssemery 
34196Ssemery 	free(grp);
34296Ssemery 	return (elist);
34396Ssemery }
34496Ssemery 
34596Ssemery /*
34696Ssemery  * Class:     Kadmin
3470Sstevel@tonic-gate  * Method:    getPrincipalList
3480Sstevel@tonic-gate  * Signature: ()[Ljava/lang/String;
3490Sstevel@tonic-gate  */
3500Sstevel@tonic-gate /*ARGSUSED*/
3510Sstevel@tonic-gate JNIEXPORT jobjectArray JNICALL
Java_Kadmin_getPrincipalList(JNIEnv * env,jobject obj)3520Sstevel@tonic-gate Java_Kadmin_getPrincipalList(JNIEnv *env,
3530Sstevel@tonic-gate 	jobject obj)
3540Sstevel@tonic-gate {
3550Sstevel@tonic-gate 	jclass stringclass;
3560Sstevel@tonic-gate 	jobjectArray plist;
3570Sstevel@tonic-gate 	jstring s;
3580Sstevel@tonic-gate 	char **princs;
3590Sstevel@tonic-gate 	int i, count;
3600Sstevel@tonic-gate 	kadm5_ret_t ret;
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	/*
3630Sstevel@tonic-gate 	 * Get the list
3640Sstevel@tonic-gate 	 */
3650Sstevel@tonic-gate 	ret = kadm5_get_principals(server_handle, NULL, &princs, &count);
3660Sstevel@tonic-gate 	if (ret) {
3670Sstevel@tonic-gate 		handle_error(env, ret);
3680Sstevel@tonic-gate 		return (NULL);
3690Sstevel@tonic-gate 	}
3700Sstevel@tonic-gate 	qsort(princs, count, sizeof (princs[0]), charcmp);
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate 	/*
3730Sstevel@tonic-gate 	 * Create and populate a Java String array
3740Sstevel@tonic-gate 	 */
3750Sstevel@tonic-gate 	stringclass = (*env)->FindClass(env, "java/lang/String");
3760Sstevel@tonic-gate 	if (!stringclass) {
3770Sstevel@tonic-gate 		handle_error(env, KADM_JNI_CLASS);
3780Sstevel@tonic-gate 		return (NULL);
3790Sstevel@tonic-gate 	}
3800Sstevel@tonic-gate 	plist = (*env)->NewObjectArray(env, count, stringclass, NULL);
3810Sstevel@tonic-gate 	if (!plist) {
3820Sstevel@tonic-gate 		handle_error(env, KADM_JNI_ARRAY);
3830Sstevel@tonic-gate 		return (NULL);
3840Sstevel@tonic-gate 	}
3850Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
3860Sstevel@tonic-gate 		s = (*env)->NewStringUTF(env, princs[i]);
3870Sstevel@tonic-gate 		if (!s) {
3880Sstevel@tonic-gate 			handle_error(env, KADM_JNI_NEWSTRING);
3890Sstevel@tonic-gate 			return (NULL);
3900Sstevel@tonic-gate 		}
3910Sstevel@tonic-gate 		(*env)->SetObjectArrayElement(env, plist, i, s);
3920Sstevel@tonic-gate 	}
3930Sstevel@tonic-gate 	kadm5_free_name_list(server_handle, princs, count);
3940Sstevel@tonic-gate 	return (plist);
3950Sstevel@tonic-gate }
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate /*
3980Sstevel@tonic-gate  * Class:     Kadmin
3990Sstevel@tonic-gate  * Method:    getPrincipalList2
4000Sstevel@tonic-gate  * Signature: ()Ljava/lang/String;
4010Sstevel@tonic-gate  */
4020Sstevel@tonic-gate /*ARGSUSED*/
4030Sstevel@tonic-gate JNIEXPORT jstring JNICALL
Java_Kadmin_getPrincipalList2(JNIEnv * env,jobject obj)4040Sstevel@tonic-gate Java_Kadmin_getPrincipalList2(JNIEnv *env, jobject obj)
4050Sstevel@tonic-gate {
4060Sstevel@tonic-gate 	jstring plist;
4070Sstevel@tonic-gate 	char **princs;
4080Sstevel@tonic-gate 	char *princlist = NULL;
4090Sstevel@tonic-gate 	int i, count, n, used = 0, size = 0;
4100Sstevel@tonic-gate 	kadm5_ret_t ret;
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 	/*
4130Sstevel@tonic-gate 	 * Get the list
4140Sstevel@tonic-gate 	 */
4150Sstevel@tonic-gate 	ret = kadm5_get_principals(server_handle, NULL, &princs, &count);
4160Sstevel@tonic-gate 	if (ret) {
4170Sstevel@tonic-gate 		handle_error(env, ret);
4180Sstevel@tonic-gate 		return (NULL);
4190Sstevel@tonic-gate 	}
4200Sstevel@tonic-gate 	qsort(princs, count, sizeof (princs[0]), charcmp);
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	/*
4230Sstevel@tonic-gate 	 * Build one large C string to hold list
4240Sstevel@tonic-gate 	 */
4250Sstevel@tonic-gate 	used = 0;
4260Sstevel@tonic-gate 	princlist = malloc(size += 2048);
4270Sstevel@tonic-gate 	if (!princlist)
4280Sstevel@tonic-gate 		return (NULL);
4290Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
4300Sstevel@tonic-gate 		n = strlen(princs[i]);
4310Sstevel@tonic-gate 		if (used + n + 2 > size) {
4320Sstevel@tonic-gate 			princlist = realloc(princlist, size += 2048);
4330Sstevel@tonic-gate 			if (!princlist)
4340Sstevel@tonic-gate 				return (NULL);
4350Sstevel@tonic-gate 		}
4360Sstevel@tonic-gate 		strncpy(&princlist[used], princs[i], n);
4370Sstevel@tonic-gate 		used += n + 1;
4380Sstevel@tonic-gate 		princlist[used-1] = ' ';
4390Sstevel@tonic-gate 		princlist[used] = '\0';
4400Sstevel@tonic-gate 	}
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	/*
4430Sstevel@tonic-gate 	 * Create a Java String
4440Sstevel@tonic-gate 	 */
4450Sstevel@tonic-gate 	plist = (*env)->NewStringUTF(env, princlist);
4460Sstevel@tonic-gate 	free(princlist);
4470Sstevel@tonic-gate 	kadm5_free_name_list(server_handle, princs, count);
4480Sstevel@tonic-gate 	return (plist);
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate /*
4530Sstevel@tonic-gate  * Class:     Kadmin
4540Sstevel@tonic-gate  * Method:    loadPrincipal
4550Sstevel@tonic-gate  * Signature: (Ljava/lang/String;LPrincipal;)Z
4560Sstevel@tonic-gate  */
4570Sstevel@tonic-gate /*ARGSUSED*/
4580Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_loadPrincipal(JNIEnv * env,jobject obj,jstring name,jobject prin)4590Sstevel@tonic-gate Java_Kadmin_loadPrincipal(JNIEnv *env, jobject obj, jstring name, jobject prin)
4600Sstevel@tonic-gate {
4610Sstevel@tonic-gate 	const char *cname;
4620Sstevel@tonic-gate 	char *fullname;
4630Sstevel@tonic-gate 	char *comments = NULL;
4640Sstevel@tonic-gate 	kadm5_principal_ent_rec pr_rec;
4650Sstevel@tonic-gate 	kadm5_ret_t ret;
46696Ssemery 	long mask = KADM5_PRINCIPAL_NORMAL_MASK | KADM5_TL_DATA |
46796Ssemery 	    KADM5_KEY_DATA;
4680Sstevel@tonic-gate 	krb5_principal kprin = NULL;
4690Sstevel@tonic-gate 	krb5_context context;
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	cname = (*env)->GetStringUTFChars(env, name, NULL);
4720Sstevel@tonic-gate 	if (!cname) {
4730Sstevel@tonic-gate 		handle_error(env, KADM_JNI_STRING);
4740Sstevel@tonic-gate 		return (JNI_FALSE);
4750Sstevel@tonic-gate 	}
4760Sstevel@tonic-gate 	fullname = qualify((char *)cname);
4770Sstevel@tonic-gate 	if (!fullname) {
4780Sstevel@tonic-gate 		handle_error(env, KADM_JNI_STRING);
4790Sstevel@tonic-gate 		return (JNI_FALSE);
4800Sstevel@tonic-gate 	}
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate 	/*
4830Sstevel@tonic-gate 	 * Get the principal
4840Sstevel@tonic-gate 	 */
4850Sstevel@tonic-gate 	ret = krb5_init_context(&context);
4860Sstevel@tonic-gate 	if (ret) {
4870Sstevel@tonic-gate 		handle_error(env, ret);
4880Sstevel@tonic-gate 		return (JNI_FALSE);
4890Sstevel@tonic-gate 	}
4900Sstevel@tonic-gate 	ret = krb5_parse_name(context, fullname, &kprin);
4910Sstevel@tonic-gate 	if (ret) {
4920Sstevel@tonic-gate 		handle_error(env, ret);
4930Sstevel@tonic-gate 		return (JNI_FALSE);
4940Sstevel@tonic-gate 	}
4950Sstevel@tonic-gate 	memset((char *)&pr_rec, 0, sizeof (pr_rec));
4960Sstevel@tonic-gate 	ret = kadm5_get_principal(server_handle, kprin, &pr_rec, mask);
4970Sstevel@tonic-gate 	if (ret) {
4980Sstevel@tonic-gate 		handle_error(env, ret);
4990Sstevel@tonic-gate 		return (JNI_FALSE);
5000Sstevel@tonic-gate 	}
5010Sstevel@tonic-gate 
5020Sstevel@tonic-gate 	/*
5030Sstevel@tonic-gate 	 * Pull the comments out of the tl_data array
5040Sstevel@tonic-gate 	 */
5050Sstevel@tonic-gate 	ret = extract_comments(&pr_rec, &comments);
5060Sstevel@tonic-gate 	if (ret) {
5070Sstevel@tonic-gate 		handle_error(env, ret);
5080Sstevel@tonic-gate 		return (JNI_FALSE);
5090Sstevel@tonic-gate 	}
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	/*
5120Sstevel@tonic-gate 	 * Fill in our Principal object
5130Sstevel@tonic-gate 	 */
5140Sstevel@tonic-gate 	ret = kadmin_to_Principal(&pr_rec, env, prin, cname, comments);
5150Sstevel@tonic-gate 	if (ret) {
5160Sstevel@tonic-gate 		handle_error(env, ret);
5170Sstevel@tonic-gate 		return (JNI_FALSE);
5180Sstevel@tonic-gate 	}
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate 	kadm5_free_principal_ent(server_handle, &pr_rec);
5210Sstevel@tonic-gate 	krb5_free_principal(context, kprin);
5220Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, name, cname);
5230Sstevel@tonic-gate 	free(fullname);
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate 	return (JNI_TRUE);
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate /*
5290Sstevel@tonic-gate  * Class:     Kadmin
5300Sstevel@tonic-gate  * Method:    savePrincipal
5310Sstevel@tonic-gate  * Signature: (LPrincipal;)Z
5320Sstevel@tonic-gate  */
5330Sstevel@tonic-gate /*ARGSUSED*/
5340Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_savePrincipal(JNIEnv * env,jobject obj,jobject prin)5350Sstevel@tonic-gate Java_Kadmin_savePrincipal(JNIEnv *env, jobject obj, jobject prin)
5360Sstevel@tonic-gate {
5370Sstevel@tonic-gate 	kadm5_principal_ent_rec pr_rec;
5380Sstevel@tonic-gate 	long mask;
5390Sstevel@tonic-gate 	char *pw = NULL;
5400Sstevel@tonic-gate 	char *comments = NULL;
5410Sstevel@tonic-gate 	kadm5_ret_t ret;
5420Sstevel@tonic-gate 	krb5_principal kprin = NULL;
54396Ssemery 	kadm5_config_params params;
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	/*
5460Sstevel@tonic-gate 	 * Convert principal object to the kadmin API structure
5470Sstevel@tonic-gate 	 */
5480Sstevel@tonic-gate 	memset((char *)&pr_rec, 0, sizeof (pr_rec));
54996Ssemery 	memset((char *)&params, 0, sizeof (params));
5500Sstevel@tonic-gate 	ret = Principal_to_kadmin(env, prin, 0, &kprin, &pr_rec, &mask,
55196Ssemery 					&pw, &comments, &params);
5520Sstevel@tonic-gate 	if (ret) {
5530Sstevel@tonic-gate 		handle_error(env, ret);
5540Sstevel@tonic-gate 		return (JNI_FALSE);
5550Sstevel@tonic-gate 	}
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 	/*
5580Sstevel@tonic-gate 	 * Save the principal
5590Sstevel@tonic-gate 	 */
5600Sstevel@tonic-gate 	ret = kadm5_modify_principal(server_handle, &pr_rec, mask);
5610Sstevel@tonic-gate 	if (ret) {
5620Sstevel@tonic-gate 		handle_error(env, ret);
5630Sstevel@tonic-gate 		ret = JNI_FALSE;
5640Sstevel@tonic-gate 		goto out;
5650Sstevel@tonic-gate 	}
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate 	/*
5680Sstevel@tonic-gate 	 * Handle any comments with read-modify-write
5690Sstevel@tonic-gate 	 */
5700Sstevel@tonic-gate 	ret = edit_comments(&pr_rec, kprin, comments);
5710Sstevel@tonic-gate 	if (ret) {
5720Sstevel@tonic-gate 		handle_error(env, ret);
5730Sstevel@tonic-gate 		ret = JNI_FALSE;
5740Sstevel@tonic-gate 		goto out;
5750Sstevel@tonic-gate 	}
5760Sstevel@tonic-gate 
5770Sstevel@tonic-gate 	/*
5780Sstevel@tonic-gate 	 * Set the password if changed
5790Sstevel@tonic-gate 	 */
58096Ssemery 	ret = set_password(kprin, pw, &params);
58196Ssemery 	if (params.keysalts != NULL)
58296Ssemery 		free(params.keysalts);
5830Sstevel@tonic-gate 	if (ret) {
5840Sstevel@tonic-gate 		handle_error(env, ret);
5850Sstevel@tonic-gate 		ret = JNI_FALSE;
5860Sstevel@tonic-gate 		goto out;
5870Sstevel@tonic-gate 	}
5880Sstevel@tonic-gate 	ret = JNI_TRUE;
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate out:
5910Sstevel@tonic-gate 	kadm5_free_principal_ent(server_handle, &pr_rec);
5920Sstevel@tonic-gate 	return (ret);
5930Sstevel@tonic-gate }
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate /*
5960Sstevel@tonic-gate  * Class:     Kadmin
5970Sstevel@tonic-gate  * Method:    createPrincipal
5980Sstevel@tonic-gate  * Signature: (LPrincipal;)Z
5990Sstevel@tonic-gate  */
6000Sstevel@tonic-gate /*ARGSUSED*/
6010Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_createPrincipal(JNIEnv * env,jobject obj,jobject prin)6020Sstevel@tonic-gate Java_Kadmin_createPrincipal(JNIEnv *env, jobject obj, jobject prin)
6030Sstevel@tonic-gate {
6040Sstevel@tonic-gate 	kadm5_principal_ent_rec pr_rec;
6050Sstevel@tonic-gate 	long mask;
6060Sstevel@tonic-gate 	char *pw = NULL;
6070Sstevel@tonic-gate 	char *comments = NULL;
6080Sstevel@tonic-gate 	kadm5_ret_t ret;
6090Sstevel@tonic-gate 	krb5_principal kprin = NULL;
61096Ssemery 	kadm5_config_params params;
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 	/*
6130Sstevel@tonic-gate 	 * Convert principal object to the kadmin API structure
6140Sstevel@tonic-gate 	 */
6150Sstevel@tonic-gate 	memset((char *)&pr_rec, 0, sizeof (pr_rec));
61696Ssemery 	memset((char *)&params, 0, sizeof (params));
6170Sstevel@tonic-gate 	ret = Principal_to_kadmin(env, prin, 1, &kprin, &pr_rec, &mask,
61896Ssemery 					&pw, &comments, &params);
6190Sstevel@tonic-gate 	if (ret) {
6200Sstevel@tonic-gate 		handle_error(env, ret);
6210Sstevel@tonic-gate 		return (JNI_FALSE);
6220Sstevel@tonic-gate 	}
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 	/*
6250Sstevel@tonic-gate 	 * Create the new principal
6260Sstevel@tonic-gate 	 */
62796Ssemery 	if (params.mask & KADM5_CONFIG_ENCTYPES) {
62896Ssemery 		ret = kadm5_create_principal_3(server_handle, &pr_rec, mask,
62996Ssemery 			params.num_keysalts, params.keysalts, pw);
63096Ssemery 		if (params.keysalts != NULL)
63196Ssemery 			free(params.keysalts);
63296Ssemery 	} else
63396Ssemery 		ret = kadm5_create_principal(server_handle, &pr_rec, mask, pw);
6340Sstevel@tonic-gate 	if (ret) {
6350Sstevel@tonic-gate 		handle_error(env, ret);
6360Sstevel@tonic-gate 		ret = JNI_FALSE;
6370Sstevel@tonic-gate 		goto out;
6380Sstevel@tonic-gate 	}
6390Sstevel@tonic-gate 
6400Sstevel@tonic-gate 	/*
6410Sstevel@tonic-gate 	 * Handle any comments with read-modify-write
6420Sstevel@tonic-gate 	 */
6430Sstevel@tonic-gate 	ret = edit_comments(&pr_rec, kprin, comments);
6440Sstevel@tonic-gate 	if (ret) {
6450Sstevel@tonic-gate 		handle_error(env, ret);
6460Sstevel@tonic-gate 		ret = JNI_FALSE;
6470Sstevel@tonic-gate 		goto out;
6480Sstevel@tonic-gate 	}
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate 	ret = JNI_TRUE;
6510Sstevel@tonic-gate out:
6520Sstevel@tonic-gate 	kadm5_free_principal_ent(server_handle, &pr_rec);
6530Sstevel@tonic-gate 	return (ret);
6540Sstevel@tonic-gate }
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate /*
6570Sstevel@tonic-gate  * Class:     Kadmin
6580Sstevel@tonic-gate  * Method:    deletePrincipal
6590Sstevel@tonic-gate  * Signature: (Ljava/lang/String;)Z
6600Sstevel@tonic-gate  */
6610Sstevel@tonic-gate /*ARGSUSED*/
6620Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_deletePrincipal(JNIEnv * env,jobject obj,jstring name)6630Sstevel@tonic-gate Java_Kadmin_deletePrincipal(JNIEnv *env, jobject obj, jstring name)
6640Sstevel@tonic-gate {
6650Sstevel@tonic-gate 	kadm5_ret_t ret;
6660Sstevel@tonic-gate 	const char *cname;
6670Sstevel@tonic-gate 	char *fullname;
6680Sstevel@tonic-gate 	krb5_principal kprin = NULL;
6690Sstevel@tonic-gate 	krb5_context context;
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	/*
6720Sstevel@tonic-gate 	 * Get name and call the delete function
6730Sstevel@tonic-gate 	 */
6740Sstevel@tonic-gate 	cname = (*env)->GetStringUTFChars(env, name, NULL);
6750Sstevel@tonic-gate 	if (!cname) {
6760Sstevel@tonic-gate 		handle_error(env, KADM_JNI_STRING);
6770Sstevel@tonic-gate 		return (JNI_FALSE);
6780Sstevel@tonic-gate 	}
6790Sstevel@tonic-gate 	fullname = qualify((char *)cname);
6800Sstevel@tonic-gate 	if (!fullname) {
6810Sstevel@tonic-gate 		handle_error(env, KADM_JNI_STRING);
6820Sstevel@tonic-gate 		return (JNI_FALSE);
6830Sstevel@tonic-gate 	}
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 	ret = krb5_init_context(&context);
6860Sstevel@tonic-gate 	if (ret) {
6870Sstevel@tonic-gate 		handle_error(env, ret);
6880Sstevel@tonic-gate 		return (JNI_FALSE);
6890Sstevel@tonic-gate 	}
6900Sstevel@tonic-gate 	ret = krb5_parse_name(context, fullname, &kprin);
6910Sstevel@tonic-gate 	if (ret) {
6920Sstevel@tonic-gate 		handle_error(env, ret);
6930Sstevel@tonic-gate 		return (JNI_FALSE);
6940Sstevel@tonic-gate 	}
6950Sstevel@tonic-gate 	ret = kadm5_delete_principal(server_handle, kprin);
6960Sstevel@tonic-gate 	if (ret) {
6970Sstevel@tonic-gate 		handle_error(env, ret);
6980Sstevel@tonic-gate 		return (JNI_FALSE);
6990Sstevel@tonic-gate 	}
7000Sstevel@tonic-gate 
7010Sstevel@tonic-gate 	krb5_free_principal(context, kprin);
7020Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, name, cname);
7030Sstevel@tonic-gate 	free(fullname);
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate 	return (JNI_TRUE);
7060Sstevel@tonic-gate }
7070Sstevel@tonic-gate 
7080Sstevel@tonic-gate /*
7090Sstevel@tonic-gate  * Class:     Kadmin
7100Sstevel@tonic-gate  * Method:    getPolicyList
7110Sstevel@tonic-gate  * Signature: ()[Ljava/lang/String;
7120Sstevel@tonic-gate  */
7130Sstevel@tonic-gate /*ARGSUSED*/
7140Sstevel@tonic-gate JNIEXPORT jobjectArray JNICALL
Java_Kadmin_getPolicyList(JNIEnv * env,jobject obj)7150Sstevel@tonic-gate Java_Kadmin_getPolicyList(JNIEnv *env, jobject obj)
7160Sstevel@tonic-gate {
7170Sstevel@tonic-gate 	jclass stringclass;
7180Sstevel@tonic-gate 	jobjectArray plist;
7190Sstevel@tonic-gate 	jstring s;
7200Sstevel@tonic-gate 	char **pols;
7210Sstevel@tonic-gate 	int i, count;
7220Sstevel@tonic-gate 	kadm5_ret_t ret;
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate 	/*
7250Sstevel@tonic-gate 	 * Get the list
7260Sstevel@tonic-gate 	 */
7270Sstevel@tonic-gate 	ret = kadm5_get_policies(server_handle, NULL, &pols, &count);
7280Sstevel@tonic-gate 	if (ret) {
7290Sstevel@tonic-gate 		handle_error(env, ret);
7300Sstevel@tonic-gate 		return (NULL);
7310Sstevel@tonic-gate 	}
7320Sstevel@tonic-gate 	qsort(pols, count, sizeof (pols[0]), charcmp);
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 	/*
7350Sstevel@tonic-gate 	 * Create and populate a Java String array
7360Sstevel@tonic-gate 	 */
7370Sstevel@tonic-gate 	stringclass = (*env)->FindClass(env, "java/lang/String");
7380Sstevel@tonic-gate 	if (!stringclass) {
7390Sstevel@tonic-gate 		handle_error(env, KADM_JNI_CLASS);
7400Sstevel@tonic-gate 		return (NULL);
7410Sstevel@tonic-gate 	}
7420Sstevel@tonic-gate 	plist = (*env)->NewObjectArray(env, count, stringclass, NULL);
7430Sstevel@tonic-gate 	if (!plist) {
7440Sstevel@tonic-gate 		handle_error(env, KADM_JNI_ARRAY);
7450Sstevel@tonic-gate 		return (NULL);
7460Sstevel@tonic-gate 	}
7470Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
7480Sstevel@tonic-gate 		s = (*env)->NewStringUTF(env, pols[i]);
7490Sstevel@tonic-gate 		if (!s) {
7500Sstevel@tonic-gate 			handle_error(env, KADM_JNI_NEWSTRING);
7510Sstevel@tonic-gate 			return (NULL);
7520Sstevel@tonic-gate 		}
7530Sstevel@tonic-gate 		(*env)->SetObjectArrayElement(env, plist, i, s);
7540Sstevel@tonic-gate 	}
7550Sstevel@tonic-gate 	kadm5_free_name_list(server_handle, pols, count);
7560Sstevel@tonic-gate 	return (plist);
7570Sstevel@tonic-gate }
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate /*
7600Sstevel@tonic-gate  * Class:     Kadmin
7610Sstevel@tonic-gate  * Method:    loadPolicy
7620Sstevel@tonic-gate  * Signature: (Ljava/lang/String;LPolicy;)Z
7630Sstevel@tonic-gate  */
7640Sstevel@tonic-gate /*ARGSUSED*/
7650Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_loadPolicy(JNIEnv * env,jobject obj,jstring name,jobject pol)7660Sstevel@tonic-gate Java_Kadmin_loadPolicy(JNIEnv *env, jobject obj, jstring name, jobject pol)
7670Sstevel@tonic-gate {
7680Sstevel@tonic-gate 	const char *cname;
7690Sstevel@tonic-gate 	kadm5_policy_ent_rec po_rec;
7700Sstevel@tonic-gate 	kadm5_ret_t ret;
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate 	cname = (*env)->GetStringUTFChars(env, name, NULL);
7730Sstevel@tonic-gate 	if (!cname) {
7740Sstevel@tonic-gate 		handle_error(env, KADM_JNI_STRING);
7750Sstevel@tonic-gate 		return (JNI_FALSE);
7760Sstevel@tonic-gate 	}
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 	ret = kadm5_get_policy(server_handle, (char *)cname, &po_rec);
7790Sstevel@tonic-gate 	if (ret) {
7800Sstevel@tonic-gate 		handle_error(env, ret);
7810Sstevel@tonic-gate 		return (JNI_FALSE);
7820Sstevel@tonic-gate 	}
7830Sstevel@tonic-gate 
7840Sstevel@tonic-gate 	ret = kadmin_to_Policy(&po_rec, env, pol);
7850Sstevel@tonic-gate 	if (ret) {
7860Sstevel@tonic-gate 		handle_error(env, ret);
7870Sstevel@tonic-gate 		return (JNI_FALSE);
7880Sstevel@tonic-gate 	}
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	kadm5_free_policy_ent(server_handle, &po_rec);
7910Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, name, cname);
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 	return (JNI_TRUE);
7940Sstevel@tonic-gate }
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate /*
7970Sstevel@tonic-gate  * Class:     Kadmin
7980Sstevel@tonic-gate  * Method:    savePolicy
7990Sstevel@tonic-gate  * Signature: (LPolicy;)Z
8000Sstevel@tonic-gate  */
8010Sstevel@tonic-gate /*ARGSUSED*/
8020Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_savePolicy(JNIEnv * env,jobject obj,jobject pol)8030Sstevel@tonic-gate Java_Kadmin_savePolicy(JNIEnv *env, jobject obj, jobject pol)
8040Sstevel@tonic-gate {
8050Sstevel@tonic-gate 	kadm5_policy_ent_rec po_rec;
8060Sstevel@tonic-gate 	kadm5_ret_t ret;
8070Sstevel@tonic-gate 	long mask;
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 	ret = Policy_to_kadmin(env, pol, 0, &po_rec, &mask);
8100Sstevel@tonic-gate 	if (ret) {
8110Sstevel@tonic-gate 		handle_error(env, ret);
8120Sstevel@tonic-gate 		return (JNI_FALSE);
8130Sstevel@tonic-gate 	}
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 	ret = kadm5_modify_policy(server_handle, &po_rec, mask);
8160Sstevel@tonic-gate 	if (ret) {
8170Sstevel@tonic-gate 		handle_error(env, ret);
8180Sstevel@tonic-gate 		return (JNI_FALSE);
8190Sstevel@tonic-gate 	}
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate 	return (JNI_TRUE);
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate /*
8250Sstevel@tonic-gate  * Class:     Kadmin
8260Sstevel@tonic-gate  * Method:    createPolicy
8270Sstevel@tonic-gate  * Signature: (LPolicy;)Z
8280Sstevel@tonic-gate  */
8290Sstevel@tonic-gate /*ARGSUSED*/
8300Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_createPolicy(JNIEnv * env,jobject obj,jobject pol)8310Sstevel@tonic-gate Java_Kadmin_createPolicy(JNIEnv * env, jobject obj, jobject pol)
8320Sstevel@tonic-gate {
8330Sstevel@tonic-gate 	kadm5_policy_ent_rec po_rec;
8340Sstevel@tonic-gate 	kadm5_ret_t ret;
8350Sstevel@tonic-gate 	long mask;
8360Sstevel@tonic-gate 
8370Sstevel@tonic-gate 	ret = Policy_to_kadmin(env, pol, 1, &po_rec, &mask);
8380Sstevel@tonic-gate 	if (ret) {
8390Sstevel@tonic-gate 		handle_error(env, ret);
8400Sstevel@tonic-gate 		return (JNI_FALSE);
8410Sstevel@tonic-gate 	}
8420Sstevel@tonic-gate 
8430Sstevel@tonic-gate 	ret = kadm5_create_policy(server_handle, &po_rec, mask);
8440Sstevel@tonic-gate 	if (ret) {
8450Sstevel@tonic-gate 		handle_error(env, ret);
8460Sstevel@tonic-gate 		return (JNI_FALSE);
8470Sstevel@tonic-gate 	}
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 	return (JNI_TRUE);
8500Sstevel@tonic-gate }
8510Sstevel@tonic-gate 
8520Sstevel@tonic-gate /*
8530Sstevel@tonic-gate  * Class:     Kadmin
8540Sstevel@tonic-gate  * Method:    deletePolicy
8550Sstevel@tonic-gate  * Signature: (Ljava/lang/String;)Z
8560Sstevel@tonic-gate  */
8570Sstevel@tonic-gate /*ARGSUSED*/
8580Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_deletePolicy(JNIEnv * env,jobject obj,jstring name)8590Sstevel@tonic-gate Java_Kadmin_deletePolicy(JNIEnv * env, jobject obj, jstring name)
8600Sstevel@tonic-gate {
8610Sstevel@tonic-gate 	const char *cname;
8620Sstevel@tonic-gate 	kadm5_ret_t ret;
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate 	cname = (*env)->GetStringUTFChars(env, name, NULL);
8650Sstevel@tonic-gate 	if (!cname) {
8660Sstevel@tonic-gate 		handle_error(env, KADM_JNI_STRING);
8670Sstevel@tonic-gate 		return (JNI_FALSE);
8680Sstevel@tonic-gate 	}
8690Sstevel@tonic-gate 
8700Sstevel@tonic-gate 	ret = kadm5_delete_policy(server_handle, (char *)cname);
8710Sstevel@tonic-gate 	if (ret) {
8720Sstevel@tonic-gate 		handle_error(env, ret);
8730Sstevel@tonic-gate 		return (JNI_FALSE);
8740Sstevel@tonic-gate 	}
8750Sstevel@tonic-gate 	return (JNI_TRUE);
8760Sstevel@tonic-gate }
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate #ifdef needtoknowmore
8790Sstevel@tonic-gate /*
8800Sstevel@tonic-gate  * Class:     Kadmin
8810Sstevel@tonic-gate  * Method:    loadDefaults
8820Sstevel@tonic-gate  * Signature: (LConfig;)Z
8830Sstevel@tonic-gate  */
8840Sstevel@tonic-gate /*ARGSUSED*/
8850Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_loadDefaults(JNIEnv * env,jobject obj,jobject config)8860Sstevel@tonic-gate Java_Kadmin_loadDefaults(JNIEnv *env, jobject obj, jobject config)
8870Sstevel@tonic-gate {
8880Sstevel@tonic-gate 	/*
8890Sstevel@tonic-gate 	 *
8900Sstevel@tonic-gate 	 */
8910Sstevel@tonic-gate 	return (JNI_TRUE);
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate 
8940Sstevel@tonic-gate /*
8950Sstevel@tonic-gate  * Class:     Kadmin
8960Sstevel@tonic-gate  * Method:    saveDefaults
8970Sstevel@tonic-gate  * Signature: (LConfig;)Z
8980Sstevel@tonic-gate  */
8990Sstevel@tonic-gate /*ARGSUSED*/
9000Sstevel@tonic-gate JNIEXPORT jboolean JNICALL
Java_Kadmin_saveDefaults(JNIEnv * env,jobject obj,jobject config)9010Sstevel@tonic-gate Java_Kadmin_saveDefaults(JNIEnv *env, jobject obj, jobject config)
9020Sstevel@tonic-gate {
9030Sstevel@tonic-gate 	/*
9040Sstevel@tonic-gate 	 *
9050Sstevel@tonic-gate 	 */
9060Sstevel@tonic-gate 	return (JNI_TRUE);
9070Sstevel@tonic-gate }
9080Sstevel@tonic-gate #endif
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 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)9110Sstevel@tonic-gate Principal_to_kadmin(JNIEnv *env, jobject prin, int new, krb5_principal *kprin,
91296Ssemery 	kadm5_principal_ent_rec *p, long *mask, char **pw, char **comments,
91396Ssemery 	kadm5_config_params *pparams)
9140Sstevel@tonic-gate {
9150Sstevel@tonic-gate 	jstring s;
9160Sstevel@tonic-gate 	jclass prcl, dateclass, intclass;
9170Sstevel@tonic-gate 	jfieldID f;
9180Sstevel@tonic-gate 	jmethodID mid;
9190Sstevel@tonic-gate 	jobject obj;
9200Sstevel@tonic-gate 	const char *str;
9210Sstevel@tonic-gate 	jlong l;
9220Sstevel@tonic-gate 	jint i;
9230Sstevel@tonic-gate 	jboolean b;
9240Sstevel@tonic-gate 	kadm5_ret_t ret;
9250Sstevel@tonic-gate 	krb5_context context;
9260Sstevel@tonic-gate 	jfieldID flagsID;
9270Sstevel@tonic-gate 	jobject flagsObj;
9280Sstevel@tonic-gate 	jclass flagsClass;
9290Sstevel@tonic-gate 	char *fullname;
9300Sstevel@tonic-gate 
9310Sstevel@tonic-gate 	*mask = 0;
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	prcl = (*env)->GetObjectClass(env, prin);
9340Sstevel@tonic-gate 	if (!prcl)
9350Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
9360Sstevel@tonic-gate 	dateclass = (*env)->FindClass(env, "java/util/Date");
9370Sstevel@tonic-gate 	if (!dateclass)
9380Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
9390Sstevel@tonic-gate 	intclass = (*env)->FindClass(env, "java/lang/Integer");
9400Sstevel@tonic-gate 	if (!intclass)
9410Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PrName", "Ljava/lang/String;");
9440Sstevel@tonic-gate 	if (!f)
9450Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
9460Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
9470Sstevel@tonic-gate 	if (!obj)
9480Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
9490Sstevel@tonic-gate 	s = (jstring)obj;
9500Sstevel@tonic-gate 	str = (*env)->GetStringUTFChars(env, s, NULL);
9510Sstevel@tonic-gate 	if (!str)
9520Sstevel@tonic-gate 		return (KADM_JNI_STRING);
9530Sstevel@tonic-gate 	fullname = qualify((char *)str);
9540Sstevel@tonic-gate 	if (!fullname)
9550Sstevel@tonic-gate 		return (KADM_ENOMEM);
9560Sstevel@tonic-gate 	ret = krb5_init_context(&context);
9570Sstevel@tonic-gate 	if (ret)
9580Sstevel@tonic-gate 		return (ret);
9590Sstevel@tonic-gate 	ret = krb5_parse_name(context, fullname, kprin);
9600Sstevel@tonic-gate 	if (ret)
9610Sstevel@tonic-gate 		return (ret);
9620Sstevel@tonic-gate 	p->principal = *kprin;
9630Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, s, str);
9640Sstevel@tonic-gate 	if (new)
9650Sstevel@tonic-gate 		*mask |= KADM5_PRINCIPAL;
9660Sstevel@tonic-gate 
9670Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PrExpireTime", "Ljava/util/Date;");
9680Sstevel@tonic-gate 	if (!f)
9690Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
9700Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
9710Sstevel@tonic-gate 	if (!obj)
9720Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
9730Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "getTime", "()J");
9740Sstevel@tonic-gate 	if (!mid)
9750Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
9760Sstevel@tonic-gate 	l = (*env)->CallLongMethod(env, obj, mid);
9770Sstevel@tonic-gate 	p->princ_expire_time = (long)(l / 1000LL);
9780Sstevel@tonic-gate 	*mask |= KADM5_PRINC_EXPIRE_TIME;
9790Sstevel@tonic-gate 
98096Ssemery 	f = (*env)->GetFieldID(env, prcl, "EncTypes", "Ljava/lang/String;");
98196Ssemery 	if (!f)
98296Ssemery 		return (KADM_JNI_FIELD);
98396Ssemery 	obj = (*env)->GetObjectField(env, prin, f);
98496Ssemery 	if (!obj)
98596Ssemery 		return (KADM_JNI_OFIELD);
98696Ssemery 	s = (jstring)obj;
98796Ssemery 	str = (*env)->GetStringUTFChars(env, s, NULL);
98896Ssemery 	if (!str)
98996Ssemery 		return (KADM_JNI_STRING);
99096Ssemery 	if (strlen(str)) {
99196Ssemery 		ret = krb5_string_to_keysalts((char *)str, ", \t", ":.-", 0,
99296Ssemery 		    &(pparams->keysalts), &(pparams->num_keysalts));
99396Ssemery 		if (ret) {
99496Ssemery 			(*env)->ReleaseStringUTFChars(env, s, str);
99596Ssemery 			return (ret);
99696Ssemery 		}
99796Ssemery 		pparams->mask |= KADM5_CONFIG_ENCTYPES;
99896Ssemery 	}
99996Ssemery 	(*env)->ReleaseStringUTFChars(env, s, str);
100096Ssemery 
10010Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "Policy", "Ljava/lang/String;");
10020Sstevel@tonic-gate 	if (!f)
10030Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
10040Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
10050Sstevel@tonic-gate 	if (!obj)
10060Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
10070Sstevel@tonic-gate 	s = (jstring)obj;
10080Sstevel@tonic-gate 	str = (*env)->GetStringUTFChars(env, s, NULL);
10090Sstevel@tonic-gate 	if (!str)
10100Sstevel@tonic-gate 		return (KADM_JNI_STRING);
10110Sstevel@tonic-gate 	p->policy = strdup(str);
10120Sstevel@tonic-gate 	if (!p->policy)
10130Sstevel@tonic-gate 		return (KADM_ENOMEM);
10140Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, s, str);
10150Sstevel@tonic-gate 	if (strlen(p->policy))
10160Sstevel@tonic-gate 		*mask |= KADM5_POLICY;
10170Sstevel@tonic-gate 	else if (!new)
10180Sstevel@tonic-gate 		*mask |= KADM5_POLICY_CLR;
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PwExpireTime", "Ljava/util/Date;");
10210Sstevel@tonic-gate 	if (!f)
10220Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
10230Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
10240Sstevel@tonic-gate 	if (obj) {
10250Sstevel@tonic-gate 		mid = (*env)->GetMethodID(env, dateclass, "getTime", "()J");
10260Sstevel@tonic-gate 		if (!mid)
10270Sstevel@tonic-gate 			return (KADM_JNI_METHOD);
10280Sstevel@tonic-gate 		l = (*env)->CallLongMethod(env, obj, mid);
10290Sstevel@tonic-gate 		p->pw_expiration = (long)(l / 1000LL);
10300Sstevel@tonic-gate 		*mask |= KADM5_PW_EXPIRATION;
10310Sstevel@tonic-gate 	}
10320Sstevel@tonic-gate 
10330Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "MaxLife", "Ljava/lang/Integer;");
10340Sstevel@tonic-gate 	if (!f)
10350Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
10360Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
10370Sstevel@tonic-gate 	if (!obj)
10380Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
10390Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
10400Sstevel@tonic-gate 	if (!mid)
10410Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
10420Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
10430Sstevel@tonic-gate 	p->max_life = i;
10440Sstevel@tonic-gate 	*mask |= KADM5_MAX_LIFE;
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "MaxRenew", "Ljava/lang/Integer;");
10470Sstevel@tonic-gate 	if (!f)
10480Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
10490Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
10500Sstevel@tonic-gate 	if (!obj)
10510Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
10520Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
10530Sstevel@tonic-gate 	if (!mid)
10540Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
10550Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
10560Sstevel@tonic-gate 	p->max_renewable_life = i;
10570Sstevel@tonic-gate 	*mask |= KADM5_MAX_RLIFE;
10580Sstevel@tonic-gate 
10590Sstevel@tonic-gate 	/*
10600Sstevel@tonic-gate 	 * Comments: because of API rules on the TL_DATA entries,
10610Sstevel@tonic-gate 	 * which say that a load-modify-write is always necessary,
10620Sstevel@tonic-gate 	 * we will only deal with comments if they are newly changed.
10630Sstevel@tonic-gate 	 */
10640Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "newComments", "Z");
10650Sstevel@tonic-gate 	if (!f)
10660Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
10670Sstevel@tonic-gate 	b = (*env)->GetBooleanField(env, prin, f);
10680Sstevel@tonic-gate 	if (b == JNI_TRUE) {
10690Sstevel@tonic-gate 
10700Sstevel@tonic-gate 		f = (*env)->GetFieldID(env, prcl, "Comments",
10710Sstevel@tonic-gate 				"Ljava/lang/String;");
10720Sstevel@tonic-gate 		if (!f)
10730Sstevel@tonic-gate 			return (KADM_JNI_FIELD);
10740Sstevel@tonic-gate 		obj = (*env)->GetObjectField(env, prin, f);
10750Sstevel@tonic-gate 		if (!obj)
10760Sstevel@tonic-gate 			return (KADM_JNI_OFIELD);
10770Sstevel@tonic-gate 		s = (jstring)obj;
10780Sstevel@tonic-gate 		str = (*env)->GetStringUTFChars(env, s, NULL);
10790Sstevel@tonic-gate 		if (!str)
10800Sstevel@tonic-gate 			return (KADM_JNI_STRING);
10810Sstevel@tonic-gate 		*comments = strdup(str);
10820Sstevel@tonic-gate 		if (!*comments)
10830Sstevel@tonic-gate 			return (KADM_ENOMEM);
10840Sstevel@tonic-gate 		(*env)->ReleaseStringUTFChars(env, s, str);
10850Sstevel@tonic-gate 	}
10860Sstevel@tonic-gate 
10870Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "Kvno", "Ljava/lang/Integer;");
10880Sstevel@tonic-gate 	if (!f)
10890Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
10900Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
10910Sstevel@tonic-gate 	if (!obj)
10920Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
10930Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
10940Sstevel@tonic-gate 	if (!mid)
10950Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
10960Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
10970Sstevel@tonic-gate 	p->kvno = i;
10980Sstevel@tonic-gate 	*mask |= KADM5_KVNO;
10990Sstevel@tonic-gate 
11000Sstevel@tonic-gate 	/*
11010Sstevel@tonic-gate 	 * Get the Principal.flags field id
11020Sstevel@tonic-gate 	 */
11030Sstevel@tonic-gate 	flagsID = (*env)->GetFieldID(env, prcl, "flags",
11040Sstevel@tonic-gate 				    "LFlags;");
11050Sstevel@tonic-gate 	if (!f)
11060Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
11070Sstevel@tonic-gate 
11080Sstevel@tonic-gate 	/*
11090Sstevel@tonic-gate 	 * Get the Principal.Flags object
11100Sstevel@tonic-gate 	 */
11110Sstevel@tonic-gate 	flagsObj = (*env)->GetObjectField(env, prin, flagsID);
11120Sstevel@tonic-gate 	if (!obj)
11130Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
11140Sstevel@tonic-gate 
11150Sstevel@tonic-gate 	/*
11160Sstevel@tonic-gate 	 * Get the Flags object's class
11170Sstevel@tonic-gate 	 */
11180Sstevel@tonic-gate 	flagsClass = (*env)->GetObjectClass(env, flagsObj);
11190Sstevel@tonic-gate 	if (!flagsClass)
11200Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate 	/*
11230Sstevel@tonic-gate 	 * Now get the Flags.flags field's value
11240Sstevel@tonic-gate 	 */
11250Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, flagsClass, "flags", "I");
11260Sstevel@tonic-gate 	if (!f)
11270Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate 	i = (*env)->GetIntField(env, flagsObj, f);
11300Sstevel@tonic-gate 	p->attributes = i & ~65536;
11310Sstevel@tonic-gate 
11320Sstevel@tonic-gate 	*mask |= KADM5_ATTRIBUTES;
11330Sstevel@tonic-gate 
11340Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PrPasswd", "Ljava/lang/String;");
11350Sstevel@tonic-gate 	if (!f)
11360Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
11370Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
11380Sstevel@tonic-gate 	if (!obj)
11390Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
11400Sstevel@tonic-gate 	s = (jstring)obj;
11410Sstevel@tonic-gate 	str = (*env)->GetStringUTFChars(env, s, NULL);
11420Sstevel@tonic-gate 	if (!str)
11430Sstevel@tonic-gate 		return (KADM_JNI_STRING);
11440Sstevel@tonic-gate 	*pw = strdup(str);
11450Sstevel@tonic-gate 	if (!*pw)
11460Sstevel@tonic-gate 		return (KADM_ENOMEM);
11470Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, s, str);
11480Sstevel@tonic-gate 
11490Sstevel@tonic-gate 	free(fullname);
11500Sstevel@tonic-gate 	return (0);
11510Sstevel@tonic-gate }
11520Sstevel@tonic-gate 
11530Sstevel@tonic-gate static int
kadmin_to_Principal(kadm5_principal_ent_rec * p,JNIEnv * env,jobject prin,const char * prname,char * comments)11540Sstevel@tonic-gate kadmin_to_Principal(kadm5_principal_ent_rec *p, JNIEnv *env, jobject prin,
11550Sstevel@tonic-gate 		const char *prname, char *comments)
11560Sstevel@tonic-gate {
11570Sstevel@tonic-gate 	jstring s;
11580Sstevel@tonic-gate 	jclass prcl, dateclass, intclass;
11590Sstevel@tonic-gate 	jfieldID f;
11600Sstevel@tonic-gate 	jmethodID mid;
11610Sstevel@tonic-gate 	jobject obj;
116296Ssemery 	int i, j, n, used = 0, size = 0;
11630Sstevel@tonic-gate 	kadm5_ret_t ret;
11640Sstevel@tonic-gate 	krb5_context context;
116596Ssemery 	char *ptr, *enclist = NULL, *e_str = NULL, *i_str;
11660Sstevel@tonic-gate 	char *cstr;
11670Sstevel@tonic-gate 
11680Sstevel@tonic-gate 	jfieldID flagsID;
11690Sstevel@tonic-gate 	jobject flagsObj;
11700Sstevel@tonic-gate 	jclass flagsClass;
11710Sstevel@tonic-gate 
11720Sstevel@tonic-gate 	prcl = (*env)->GetObjectClass(env, prin);
11730Sstevel@tonic-gate 	if (!prcl)
11740Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
11750Sstevel@tonic-gate 	dateclass = (*env)->FindClass(env, "java/util/Date");
11760Sstevel@tonic-gate 	if (!dateclass)
11770Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
11780Sstevel@tonic-gate 	intclass = (*env)->FindClass(env, "java/lang/Integer");
11790Sstevel@tonic-gate 	if (!intclass)
11800Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
11810Sstevel@tonic-gate 
11820Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PrName", "Ljava/lang/String;");
11830Sstevel@tonic-gate 	if (!f)
11840Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
11850Sstevel@tonic-gate 	s = (*env)->NewStringUTF(env, prname);
11860Sstevel@tonic-gate 	if (!s)
11870Sstevel@tonic-gate 		return (KADM_JNI_NEWSTRING);
11880Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, s);
11890Sstevel@tonic-gate 
11900Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PrExpireTime", "Ljava/util/Date;");
11910Sstevel@tonic-gate 	if (!f)
11920Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
11930Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
11940Sstevel@tonic-gate 	if (!mid)
11950Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
11960Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
11970Sstevel@tonic-gate 	if (!obj)
11980Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
11990Sstevel@tonic-gate 	(*env)->CallVoidMethod(env, obj, mid,
12000Sstevel@tonic-gate 			(jlong) (p->princ_expire_time * 1000LL));
12010Sstevel@tonic-gate 
120296Ssemery 	f = (*env)->GetFieldID(env, prcl, "EncTypes", "Ljava/lang/String;");
120396Ssemery 	if (!f)
120496Ssemery 		return (KADM_JNI_FIELD);
120596Ssemery 	used = 0;
120696Ssemery 	enclist = malloc(size += 2048);
120796Ssemery 	if (enclist == NULL)
120896Ssemery 		return (errno);
120996Ssemery 	for (i = 0; i < p->n_key_data; i++) {
121096Ssemery 		krb5_key_data *key_data = &p->key_data[i];
121196Ssemery 		for (j = 0; j < krb5_enctypes_length; j++) {
121296Ssemery 			if (key_data->key_data_type[0] ==
121396Ssemery 			    krb5_enctypes_list[j].etype) {
121496Ssemery 				i_str = krb5_enctypes_list[j].in_string;
121596Ssemery 				n = strlen(i_str) + strlen(":normal");
121696Ssemery 				e_str = malloc(n);
121796Ssemery 				if (e_str == NULL) {
121896Ssemery 					free(enclist);
121996Ssemery 					return (errno);
122096Ssemery 				}
122196Ssemery 				(void) snprintf(e_str, n + 1, "%s:normal",
122296Ssemery 				    i_str);
122396Ssemery 				/*
122496Ssemery 				 * We reallocate if existing + what we need +
122596Ssemery 				 * 2 (the null byte and a space for the list).
122696Ssemery 				 */
122796Ssemery 				if (used + n + 2 > size) {
122896Ssemery 					enclist = realloc(enclist,
122996Ssemery 					    size += 2048);
123096Ssemery 					if (enclist == NULL) {
123196Ssemery 						free(e_str);
123296Ssemery 						return (errno);
123396Ssemery 					}
123496Ssemery 				}
123596Ssemery 				(void) strncpy(&enclist[used], e_str, n);
123696Ssemery 				free(e_str);
123796Ssemery 				e_str = NULL;
123896Ssemery 				used += n + 1;
123996Ssemery 				enclist[used-1] = ' ';
124096Ssemery 				enclist[used] = '\0';
124196Ssemery 				break;
124296Ssemery 			}
124396Ssemery 		}
124496Ssemery 	}
124596Ssemery 	s = (*env)->NewStringUTF(env, enclist);
124696Ssemery 	free(enclist);
124796Ssemery 	if (!s)
124896Ssemery 		return (KADM_JNI_NEWSTRING);
124996Ssemery 	(*env)->SetObjectField(env, prin, f, s);
125096Ssemery 
12510Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "Policy", "Ljava/lang/String;");
12520Sstevel@tonic-gate 	if (!f)
12530Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
12540Sstevel@tonic-gate 	cstr = strdup(p->policy ? p->policy : "");
12550Sstevel@tonic-gate 	if (!cstr)
12560Sstevel@tonic-gate 		return (KADM_ENOMEM);
12570Sstevel@tonic-gate 	s = (*env)->NewStringUTF(env, cstr);
12580Sstevel@tonic-gate 	if (!s)
12590Sstevel@tonic-gate 		return (KADM_JNI_NEWSTRING);
12600Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, s);
12610Sstevel@tonic-gate 	free(cstr);
12620Sstevel@tonic-gate 
12630Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "LastPwChange", "Ljava/util/Date;");
12640Sstevel@tonic-gate 	if (!f)
12650Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
12660Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
12670Sstevel@tonic-gate 	if (!mid)
12680Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
12690Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
12700Sstevel@tonic-gate 	if (!obj)
12710Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
12720Sstevel@tonic-gate 	(*env)->CallVoidMethod(env, obj, mid,
12730Sstevel@tonic-gate 			(jlong) (p->last_pwd_change * 1000LL));
12740Sstevel@tonic-gate 
12750Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "PwExpireTime", "Ljava/util/Date;");
12760Sstevel@tonic-gate 	if (!f)
12770Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
12780Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
12790Sstevel@tonic-gate 	if (!mid)
12800Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
12810Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
12820Sstevel@tonic-gate 	if (!obj)
12830Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
12840Sstevel@tonic-gate 	(*env)->CallVoidMethod(env, obj, mid,
12850Sstevel@tonic-gate 			(jlong) (p->pw_expiration * 1000LL));
12860Sstevel@tonic-gate 
12870Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "MaxLife", "Ljava/lang/Integer;");
12880Sstevel@tonic-gate 	if (!f)
12890Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
12900Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
12910Sstevel@tonic-gate 	if (!mid)
12920Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
12930Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, (jint) p->max_life);
12940Sstevel@tonic-gate 	if (!obj)
12950Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
12960Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, obj);
12970Sstevel@tonic-gate 
12980Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "MaxRenew", "Ljava/lang/Integer;");
12990Sstevel@tonic-gate 	if (!f)
13000Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13010Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
13020Sstevel@tonic-gate 	if (!mid)
13030Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
13040Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid,
13050Sstevel@tonic-gate 			(jint) p->max_renewable_life);
13060Sstevel@tonic-gate 	if (!obj)
13070Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
13080Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, obj);
13090Sstevel@tonic-gate 
13100Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "ModTime", "Ljava/util/Date;");
13110Sstevel@tonic-gate 	if (!f)
13120Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13130Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
13140Sstevel@tonic-gate 	if (!mid)
13150Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
13160Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
13170Sstevel@tonic-gate 	if (!obj)
13180Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
13190Sstevel@tonic-gate 	(*env)->CallVoidMethod(env, obj, mid,
13200Sstevel@tonic-gate 			(jlong) (p->mod_date * 1000LL));
13210Sstevel@tonic-gate 
13220Sstevel@tonic-gate 	ret = krb5_init_context(&context);
13230Sstevel@tonic-gate 	if (ret)
13240Sstevel@tonic-gate 		return (ret);
13250Sstevel@tonic-gate 	ret = krb5_unparse_name(context, p->mod_name, &ptr);
13260Sstevel@tonic-gate 	if (ret)
13270Sstevel@tonic-gate 		return (ret);
13280Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "ModName", "Ljava/lang/String;");
13290Sstevel@tonic-gate 	if (!f)
13300Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13310Sstevel@tonic-gate 	s = (*env)->NewStringUTF(env, ptr);
13320Sstevel@tonic-gate 	if (!s)
13330Sstevel@tonic-gate 		return (KADM_JNI_NEWSTRING);
13340Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, s);
13350Sstevel@tonic-gate 	krb5_xfree(ptr);
13360Sstevel@tonic-gate 
13370Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "LastSuccess", "Ljava/util/Date;");
13380Sstevel@tonic-gate 	if (!f)
13390Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13400Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
13410Sstevel@tonic-gate 	if (!mid)
13420Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
13430Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
13440Sstevel@tonic-gate 	if (!obj)
13450Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
13460Sstevel@tonic-gate 	(*env)->CallVoidMethod(env, obj, mid,
13470Sstevel@tonic-gate 			(jlong) (p->last_success * 1000LL));
13480Sstevel@tonic-gate 
13490Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "LastFailure", "Ljava/util/Date;");
13500Sstevel@tonic-gate 	if (!f)
13510Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13520Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, dateclass, "setTime", "(J)V");
13530Sstevel@tonic-gate 	if (!mid)
13540Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
13550Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, prin, f);
13560Sstevel@tonic-gate 	if (!obj)
13570Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
13580Sstevel@tonic-gate 	(*env)->CallVoidMethod(env, obj, mid,
13590Sstevel@tonic-gate 			(jlong) (p->last_failed * 1000LL));
13600Sstevel@tonic-gate 
13610Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "NumFailures", "Ljava/lang/Integer;");
13620Sstevel@tonic-gate 	if (!f)
13630Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13640Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
13650Sstevel@tonic-gate 	if (!mid)
13660Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
13670Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid,
13680Sstevel@tonic-gate 			(jint) p->fail_auth_count);
13690Sstevel@tonic-gate 	if (!obj)
13700Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
13710Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, obj);
13720Sstevel@tonic-gate 
13730Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "Comments", "Ljava/lang/String;");
13740Sstevel@tonic-gate 	if (!f)
13750Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13760Sstevel@tonic-gate 	cstr = strdup(comments ? comments : "");
13770Sstevel@tonic-gate 	if (!cstr)
13780Sstevel@tonic-gate 		return (KADM_ENOMEM);
13790Sstevel@tonic-gate 	s = (*env)->NewStringUTF(env, cstr);
13800Sstevel@tonic-gate 	if (!s)
13810Sstevel@tonic-gate 		return (KADM_JNI_NEWSTRING);
13820Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, s);
13830Sstevel@tonic-gate 	free(cstr);
13840Sstevel@tonic-gate 
13850Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "Kvno", "Ljava/lang/Integer;");
13860Sstevel@tonic-gate 	if (!f)
13870Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13880Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
13890Sstevel@tonic-gate 	if (!mid)
13900Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
13910Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->kvno);
13920Sstevel@tonic-gate 	if (!obj)
13930Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
13940Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, obj);
13950Sstevel@tonic-gate 
13960Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, prcl, "Mkvno", "Ljava/lang/Integer;");
13970Sstevel@tonic-gate 	if (!f)
13980Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
13990Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
14000Sstevel@tonic-gate 	if (!mid)
14010Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
14020Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->mkvno);
14030Sstevel@tonic-gate 	if (!obj)
14040Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
14050Sstevel@tonic-gate 	(*env)->SetObjectField(env, prin, f, obj);
14060Sstevel@tonic-gate 
14070Sstevel@tonic-gate 	i = p->attributes;
14080Sstevel@tonic-gate 
14090Sstevel@tonic-gate 	/*
14100Sstevel@tonic-gate 	 * Get the Principal.flags field id
14110Sstevel@tonic-gate 	 */
14120Sstevel@tonic-gate 	flagsID = (*env)->GetFieldID(env, prcl, "flags",
14130Sstevel@tonic-gate 				    "LFlags;");
14140Sstevel@tonic-gate 	if (!f)
14150Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
14160Sstevel@tonic-gate 
14170Sstevel@tonic-gate 	/*
14180Sstevel@tonic-gate 	 * Get the Principal.Flags object
14190Sstevel@tonic-gate 	 */
14200Sstevel@tonic-gate 	flagsObj = (*env)->GetObjectField(env, prin, flagsID);
14210Sstevel@tonic-gate 	if (!obj)
14220Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
14230Sstevel@tonic-gate 
14240Sstevel@tonic-gate 	/*
14250Sstevel@tonic-gate 	 * Get the Flags object's class
14260Sstevel@tonic-gate 	 */
14270Sstevel@tonic-gate 	flagsClass = (*env)->GetObjectClass(env, flagsObj);
14280Sstevel@tonic-gate 
14290Sstevel@tonic-gate 	/*
14300Sstevel@tonic-gate 	 * Now set the Flags.flags field's value
14310Sstevel@tonic-gate 	 */
14320Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, flagsClass, "flags", "I");
14330Sstevel@tonic-gate 	if (!f)
14340Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
14350Sstevel@tonic-gate 	(*env)->SetIntField(env, flagsObj, f, i);
14360Sstevel@tonic-gate 
14370Sstevel@tonic-gate 	return (0);
14380Sstevel@tonic-gate }
14390Sstevel@tonic-gate 
14400Sstevel@tonic-gate static int
Policy_to_kadmin(JNIEnv * env,jobject pol,int new,kadm5_policy_ent_rec * p,long * mask)14410Sstevel@tonic-gate Policy_to_kadmin(JNIEnv *env, jobject pol, int new,
14420Sstevel@tonic-gate 	kadm5_policy_ent_rec *p, long *mask)
14430Sstevel@tonic-gate {
14440Sstevel@tonic-gate 	jstring s;
14450Sstevel@tonic-gate 	jclass pocl, intclass;
14460Sstevel@tonic-gate 	jfieldID f;
14470Sstevel@tonic-gate 	jmethodID mid;
14480Sstevel@tonic-gate 	jobject obj;
14490Sstevel@tonic-gate 	const char *str;
14500Sstevel@tonic-gate 	int i;
14510Sstevel@tonic-gate 
14520Sstevel@tonic-gate 	*mask = 0;
14530Sstevel@tonic-gate 
14540Sstevel@tonic-gate 	pocl = (*env)->GetObjectClass(env, pol);
14550Sstevel@tonic-gate 	if (!pocl)
14560Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
14570Sstevel@tonic-gate 	intclass = (*env)->FindClass(env, "java/lang/Integer");
14580Sstevel@tonic-gate 	if (!intclass)
14590Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
14600Sstevel@tonic-gate 
14610Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PolicyName", "Ljava/lang/String;");
14620Sstevel@tonic-gate 	if (!f)
14630Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
14640Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, pol, f);
14650Sstevel@tonic-gate 	if (!obj)
14660Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
14670Sstevel@tonic-gate 	s = (jstring)obj;
14680Sstevel@tonic-gate 	str = (*env)->GetStringUTFChars(env, s, NULL);
14690Sstevel@tonic-gate 	if (!str)
14700Sstevel@tonic-gate 		return (KADM_JNI_STRING);
14710Sstevel@tonic-gate 	p->policy = strdup(str);
14720Sstevel@tonic-gate 	if (!p->policy)
14730Sstevel@tonic-gate 		return (KADM_ENOMEM);
14740Sstevel@tonic-gate 	if (new)
14750Sstevel@tonic-gate 		*mask |= KADM5_POLICY;
14760Sstevel@tonic-gate 	(*env)->ReleaseStringUTFChars(env, s, str);
14770Sstevel@tonic-gate 
14780Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMinLife", "Ljava/lang/Integer;");
14790Sstevel@tonic-gate 	if (!f)
14800Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
14810Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, pol, f);
14820Sstevel@tonic-gate 	if (!obj)
14830Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
14840Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
14850Sstevel@tonic-gate 	if (!mid)
14860Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
14870Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
14880Sstevel@tonic-gate 	p->pw_min_life = i;
14890Sstevel@tonic-gate 	*mask |= KADM5_PW_MIN_LIFE;
14900Sstevel@tonic-gate 
14910Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMaxLife", "Ljava/lang/Integer;");
14920Sstevel@tonic-gate 	if (!f)
14930Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
14940Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, pol, f);
14950Sstevel@tonic-gate 	if (!obj)
14960Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
14970Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
14980Sstevel@tonic-gate 	if (!mid)
14990Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15000Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
15010Sstevel@tonic-gate 	p->pw_max_life = i;
15020Sstevel@tonic-gate 	*mask |= KADM5_PW_MAX_LIFE;
15030Sstevel@tonic-gate 
15040Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMinLength", "Ljava/lang/Integer;");
15050Sstevel@tonic-gate 	if (!f)
15060Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15070Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, pol, f);
15080Sstevel@tonic-gate 	if (!obj)
15090Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
15100Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
15110Sstevel@tonic-gate 	if (!mid)
15120Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15130Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
15140Sstevel@tonic-gate 	p->pw_min_length = i;
15150Sstevel@tonic-gate 	*mask |= KADM5_PW_MIN_LENGTH;
15160Sstevel@tonic-gate 
15170Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMinClasses",
15180Sstevel@tonic-gate 				"Ljava/lang/Integer;");
15190Sstevel@tonic-gate 	if (!f)
15200Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15210Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, pol, f);
15220Sstevel@tonic-gate 	if (!obj)
15230Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
15240Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
15250Sstevel@tonic-gate 	if (!mid)
15260Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15270Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
15280Sstevel@tonic-gate 	p->pw_min_classes = i;
15290Sstevel@tonic-gate 	*mask |= KADM5_PW_MIN_CLASSES;
15300Sstevel@tonic-gate 
15310Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwSaveCount", "Ljava/lang/Integer;");
15320Sstevel@tonic-gate 	if (!f)
15330Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15340Sstevel@tonic-gate 	obj = (*env)->GetObjectField(env, pol, f);
15350Sstevel@tonic-gate 	if (!obj)
15360Sstevel@tonic-gate 		return (KADM_JNI_OFIELD);
15370Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "intValue", "()I");
15380Sstevel@tonic-gate 	if (!mid)
15390Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15400Sstevel@tonic-gate 	i = (*env)->CallIntMethod(env, obj, mid);
15410Sstevel@tonic-gate 	p->pw_history_num = i;
15420Sstevel@tonic-gate 	*mask |= KADM5_PW_HISTORY_NUM;
15430Sstevel@tonic-gate 
15440Sstevel@tonic-gate 	return (0);
15450Sstevel@tonic-gate }
15460Sstevel@tonic-gate 
15470Sstevel@tonic-gate static int
kadmin_to_Policy(kadm5_policy_ent_rec * p,JNIEnv * env,jobject pol)15480Sstevel@tonic-gate kadmin_to_Policy(kadm5_policy_ent_rec *p, JNIEnv *env, jobject pol)
15490Sstevel@tonic-gate {
15500Sstevel@tonic-gate 	jstring s;
15510Sstevel@tonic-gate 	jclass pocl, intclass;
15520Sstevel@tonic-gate 	jfieldID f;
15530Sstevel@tonic-gate 	jmethodID mid;
15540Sstevel@tonic-gate 	jobject obj;
15550Sstevel@tonic-gate 
15560Sstevel@tonic-gate 	pocl = (*env)->GetObjectClass(env, pol);
15570Sstevel@tonic-gate 	if (!pocl)
15580Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
15590Sstevel@tonic-gate 	intclass = (*env)->FindClass(env, "java/lang/Integer");
15600Sstevel@tonic-gate 	if (!intclass)
15610Sstevel@tonic-gate 		return (KADM_JNI_CLASS);
15620Sstevel@tonic-gate 
15630Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PolicyName", "Ljava/lang/String;");
15640Sstevel@tonic-gate 	if (!f)
15650Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15660Sstevel@tonic-gate 	s = (*env)->NewStringUTF(env, p->policy);
15670Sstevel@tonic-gate 	if (!s)
15680Sstevel@tonic-gate 		return (KADM_JNI_NEWSTRING);
15690Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, s);
15700Sstevel@tonic-gate 
15710Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMinLife", "Ljava/lang/Integer;");
15720Sstevel@tonic-gate 	if (!f)
15730Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15740Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
15750Sstevel@tonic-gate 	if (!mid)
15760Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15770Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->pw_min_life);
15780Sstevel@tonic-gate 	if (!obj)
15790Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
15800Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, obj);
15810Sstevel@tonic-gate 
15820Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMaxLife", "Ljava/lang/Integer;");
15830Sstevel@tonic-gate 	if (!f)
15840Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15850Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
15860Sstevel@tonic-gate 	if (!mid)
15870Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15880Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->pw_max_life);
15890Sstevel@tonic-gate 	if (!obj)
15900Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
15910Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, obj);
15920Sstevel@tonic-gate 
15930Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMinLength", "Ljava/lang/Integer;");
15940Sstevel@tonic-gate 	if (!f)
15950Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
15960Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
15970Sstevel@tonic-gate 	if (!mid)
15980Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
15990Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->pw_min_length);
16000Sstevel@tonic-gate 	if (!obj)
16010Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
16020Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, obj);
16030Sstevel@tonic-gate 
16040Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwMinClasses",
16050Sstevel@tonic-gate 				"Ljava/lang/Integer;");
16060Sstevel@tonic-gate 	if (!f)
16070Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
16080Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
16090Sstevel@tonic-gate 	if (!mid)
16100Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
16110Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->pw_min_classes);
16120Sstevel@tonic-gate 	if (!obj)
16130Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
16140Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, obj);
16150Sstevel@tonic-gate 
16160Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "PwSaveCount", "Ljava/lang/Integer;");
16170Sstevel@tonic-gate 	if (!f)
16180Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
16190Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
16200Sstevel@tonic-gate 	if (!mid)
16210Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
16220Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->pw_history_num);
16230Sstevel@tonic-gate 	if (!obj)
16240Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
16250Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, obj);
16260Sstevel@tonic-gate 
16270Sstevel@tonic-gate 	f = (*env)->GetFieldID(env, pocl, "RefCount", "Ljava/lang/Integer;");
16280Sstevel@tonic-gate 	if (!f)
16290Sstevel@tonic-gate 		return (KADM_JNI_FIELD);
16300Sstevel@tonic-gate 	mid = (*env)->GetMethodID(env, intclass, "<init>", "(I)V");
16310Sstevel@tonic-gate 	if (!mid)
16320Sstevel@tonic-gate 		return (KADM_JNI_METHOD);
16330Sstevel@tonic-gate 	obj = (*env)->NewObject(env, intclass, mid, p->policy_refcnt);
16340Sstevel@tonic-gate 	if (!obj)
16350Sstevel@tonic-gate 		return (KADM_JNI_OBJECT);
16360Sstevel@tonic-gate 	(*env)->SetObjectField(env, pol, f, obj);
16370Sstevel@tonic-gate 
16380Sstevel@tonic-gate 	return (0);
16390Sstevel@tonic-gate }
16400Sstevel@tonic-gate 
16410Sstevel@tonic-gate #define	SUNSOFT_COMMENTS	256
16420Sstevel@tonic-gate 
16430Sstevel@tonic-gate /*
16440Sstevel@tonic-gate  * The new principal has been saved; now we do a load-modify-store
16450Sstevel@tonic-gate  * to get the comments into the TL_DATA array.
16460Sstevel@tonic-gate  */
16470Sstevel@tonic-gate static int
edit_comments(kadm5_principal_ent_rec * p,krb5_principal kprin,char * comments)16480Sstevel@tonic-gate edit_comments(kadm5_principal_ent_rec *p, krb5_principal kprin, char *comments)
16490Sstevel@tonic-gate {
16500Sstevel@tonic-gate 	long mask = KADM5_PRINCIPAL | KADM5_TL_DATA;
16510Sstevel@tonic-gate 	kadm5_ret_t ret;
16520Sstevel@tonic-gate 
16530Sstevel@tonic-gate 	if (!comments || !strlen(comments))
16540Sstevel@tonic-gate 		return (0);
16550Sstevel@tonic-gate 
16560Sstevel@tonic-gate 	ret = kadm5_get_principal(server_handle, kprin, p, mask);
16570Sstevel@tonic-gate 	if (ret)
16580Sstevel@tonic-gate 		return (ret);
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate 	mask = 0;
16610Sstevel@tonic-gate 	ret = format_comments(p, &mask, comments);
16620Sstevel@tonic-gate 	if (ret)
16630Sstevel@tonic-gate 		return (ret);
16640Sstevel@tonic-gate 
16650Sstevel@tonic-gate 	if (mask) {
16660Sstevel@tonic-gate 		ret = kadm5_modify_principal(server_handle, p, mask);
16670Sstevel@tonic-gate 		if (ret)
16680Sstevel@tonic-gate 			return (ret);
16690Sstevel@tonic-gate 	}
16700Sstevel@tonic-gate 
16710Sstevel@tonic-gate 	return (0);
16720Sstevel@tonic-gate }
16730Sstevel@tonic-gate 
16740Sstevel@tonic-gate /*
16750Sstevel@tonic-gate  * Put the comments into TL_DATA.
16760Sstevel@tonic-gate  */
16770Sstevel@tonic-gate static int
format_comments(kadm5_principal_ent_rec * p,long * mask,char * comments)16780Sstevel@tonic-gate format_comments(kadm5_principal_ent_rec *p, long *mask, char *comments)
16790Sstevel@tonic-gate {
16800Sstevel@tonic-gate 	krb5_tl_data *t, *t1, *tdp;
16810Sstevel@tonic-gate 	char *s;
16820Sstevel@tonic-gate 
16830Sstevel@tonic-gate 	if (!comments || !strlen(comments))
16840Sstevel@tonic-gate 		return (0);
16850Sstevel@tonic-gate 	tdp = malloc(sizeof (krb5_tl_data));
16860Sstevel@tonic-gate 	if (!tdp)
16870Sstevel@tonic-gate 		return (KADM_ENOMEM);
16880Sstevel@tonic-gate 	s = strdup(comments);
16890Sstevel@tonic-gate 	if (!s)
16900Sstevel@tonic-gate 		return (KADM_ENOMEM);
16910Sstevel@tonic-gate 
16920Sstevel@tonic-gate 	/*
16930Sstevel@tonic-gate 	 * Search for existing comments field, or find next-to-last
16940Sstevel@tonic-gate 	 */
16950Sstevel@tonic-gate 	for (t = t1 = p->tl_data; t; t1 = t, t = t->tl_data_next)
16960Sstevel@tonic-gate 		if (t->tl_data_type == SUNSOFT_COMMENTS)
16970Sstevel@tonic-gate 			break;
16980Sstevel@tonic-gate 	if (t) {
16990Sstevel@tonic-gate 		t->tl_data_length = strlen(comments);
17000Sstevel@tonic-gate 		free(t->tl_data_contents);
17010Sstevel@tonic-gate 		t->tl_data_contents = (krb5_octet *)s;
17020Sstevel@tonic-gate 	} else {
17030Sstevel@tonic-gate 		tdp->tl_data_next = NULL;
17040Sstevel@tonic-gate 		tdp->tl_data_type = SUNSOFT_COMMENTS;
17050Sstevel@tonic-gate 		tdp->tl_data_length = strlen(comments)+1;
17060Sstevel@tonic-gate 		tdp->tl_data_contents = (krb5_octet *)s;
17070Sstevel@tonic-gate 		if (t1)
17080Sstevel@tonic-gate 			t1->tl_data_next = tdp;
17090Sstevel@tonic-gate 		else
17100Sstevel@tonic-gate 			p->tl_data = tdp;
17110Sstevel@tonic-gate 		p->n_tl_data++;
17120Sstevel@tonic-gate 	}
17130Sstevel@tonic-gate 	*mask |= KADM5_TL_DATA;
17140Sstevel@tonic-gate 	return (0);
17150Sstevel@tonic-gate }
17160Sstevel@tonic-gate 
17170Sstevel@tonic-gate /*
17180Sstevel@tonic-gate  * The principal has been loaded, so we pluck the comments out of TL_DATA.
17190Sstevel@tonic-gate  */
17200Sstevel@tonic-gate static int
extract_comments(kadm5_principal_ent_rec * p,char ** comments)17210Sstevel@tonic-gate extract_comments(kadm5_principal_ent_rec *p, char **comments)
17220Sstevel@tonic-gate {
17230Sstevel@tonic-gate 	krb5_tl_data *t;
17240Sstevel@tonic-gate 	char *s;
17250Sstevel@tonic-gate 
17260Sstevel@tonic-gate 	/*
17270Sstevel@tonic-gate 	 * Search for existing comments field, or find next-to-last
17280Sstevel@tonic-gate 	 */
17290Sstevel@tonic-gate 	if (!p->n_tl_data)
17300Sstevel@tonic-gate 		return (0);
17310Sstevel@tonic-gate 	for (t = p->tl_data; t; t = t->tl_data_next)
17320Sstevel@tonic-gate 		if (t->tl_data_type == SUNSOFT_COMMENTS)
17330Sstevel@tonic-gate 			break;
17340Sstevel@tonic-gate 	if (t && t->tl_data_length) {
17350Sstevel@tonic-gate 		s = strdup((char *)t->tl_data_contents);
17360Sstevel@tonic-gate 		if (!s)
17370Sstevel@tonic-gate 			return (KADM_ENOMEM);
17380Sstevel@tonic-gate 		s[t->tl_data_length] = 0;
17390Sstevel@tonic-gate 		*comments = s;
17400Sstevel@tonic-gate 	}
17410Sstevel@tonic-gate 	return (0);
17420Sstevel@tonic-gate }
17430Sstevel@tonic-gate 
17440Sstevel@tonic-gate /*
17450Sstevel@tonic-gate  * Set password for the modified principal
17460Sstevel@tonic-gate  */
17470Sstevel@tonic-gate static int
set_password(krb5_principal kprin,char * pw,kadm5_config_params * pparams)174896Ssemery set_password(krb5_principal kprin, char *pw, kadm5_config_params *pparams)
17490Sstevel@tonic-gate {
17500Sstevel@tonic-gate 	kadm5_ret_t ret;
175196Ssemery 	int keepold = 0;
17520Sstevel@tonic-gate 
17530Sstevel@tonic-gate 	if (!pw || !strlen(pw))
17540Sstevel@tonic-gate 		return (0);
175596Ssemery 
175696Ssemery 	if (pparams->mask & KADM5_CONFIG_ENCTYPES)
175796Ssemery 		ret = kadm5_chpass_principal_3(server_handle, kprin, keepold,
175896Ssemery 		    pparams->num_keysalts, pparams->keysalts, pw);
175996Ssemery 	else
176096Ssemery 		ret = kadm5_chpass_principal(server_handle, kprin, pw);
176196Ssemery 
17620Sstevel@tonic-gate 	if (ret)
17630Sstevel@tonic-gate 		return (ret);
17640Sstevel@tonic-gate 	return (0);
17650Sstevel@tonic-gate }
17660Sstevel@tonic-gate 
17670Sstevel@tonic-gate static void
handle_error(JNIEnv * env,int error)17680Sstevel@tonic-gate handle_error(JNIEnv *env, int error)
17690Sstevel@tonic-gate {
17700Sstevel@tonic-gate 	char *s;
17710Sstevel@tonic-gate 	char    from[BUFSIZ], to[BUFSIZ];
17720Sstevel@tonic-gate 	char    *tptr;
17730Sstevel@tonic-gate 	const char  *fptr;
17740Sstevel@tonic-gate 	size_t  ileft, oleft, ret;
17750Sstevel@tonic-gate 
17760Sstevel@tonic-gate 	s = (char *)error_message(error);
17770Sstevel@tonic-gate 	/* fprintf(stderr, "Kadmin: %s (%d)\n", s, error); XXX */
17780Sstevel@tonic-gate 	if (cd != (iconv_t)-1) {
17790Sstevel@tonic-gate 		ileft = strlen(s);
17800Sstevel@tonic-gate 		strncpy(from, s, ileft);
17810Sstevel@tonic-gate 		fptr = from;
17820Sstevel@tonic-gate 		oleft = BUFSIZ;
17830Sstevel@tonic-gate 		tptr = to;
17840Sstevel@tonic-gate 		ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
17850Sstevel@tonic-gate 		if (ret != (size_t)-1) {
17860Sstevel@tonic-gate 			to[BUFSIZ-oleft] = '\0';
17870Sstevel@tonic-gate 			s = to;
17880Sstevel@tonic-gate 		/* fprintf(stderr, "Kadmin: %s (%d)\n", s, error); XXX */
17890Sstevel@tonic-gate 		}
17900Sstevel@tonic-gate 	}
17910Sstevel@tonic-gate 	(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/Exception"),
17920Sstevel@tonic-gate 			(const char *)s);
17930Sstevel@tonic-gate }
1794