1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * ident	"%Z%%M%	%I%	%E% SMI"
24*0Sstevel@tonic-gate  *
25*0Sstevel@tonic-gate  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
26*0Sstevel@tonic-gate  * All rights reserved.
27*0Sstevel@tonic-gate  */
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate import java.util.Date;
30*0Sstevel@tonic-gate import java.text.DateFormat;
31*0Sstevel@tonic-gate import java.text.NumberFormat;
32*0Sstevel@tonic-gate import java.text.ParseException;
33*0Sstevel@tonic-gate import java.util.Calendar;
34*0Sstevel@tonic-gate import java.util.ResourceBundle;
35*0Sstevel@tonic-gate import java.util.MissingResourceException;
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate /**
38*0Sstevel@tonic-gate  * Class representing a Kerberos V5 principal
39*0Sstevel@tonic-gate  * Class data items correspond to fields in struct _kadm5_principal_ent_t_v2
40*0Sstevel@tonic-gate  */
41*0Sstevel@tonic-gate class Principal {
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate     private static DateFormat df;
44*0Sstevel@tonic-gate     private static NumberFormat nf;
45*0Sstevel@tonic-gate     private static String neverString;
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate     private static Integer INFINITE_LIFE = new Integer(Integer.MAX_VALUE);
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate     Flags flags;
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate     // For I18N
52*0Sstevel@tonic-gate     private static ResourceBundle rb;
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate     String PrName;		// krb5_principal principal;
55*0Sstevel@tonic-gate     Date PrExpireTime;		// krb5_timestamp princ_expire_time;
56*0Sstevel@tonic-gate     String Policy;		// char *policy;
57*0Sstevel@tonic-gate     Date LastPwChange;		// krb5_timestamp last_pwd_change;
58*0Sstevel@tonic-gate     Date PwExpireTime;		// krb5_timestamp pw_expiration;
59*0Sstevel@tonic-gate     Integer MaxLife;	        // krb5_deltat max_life;
60*0Sstevel@tonic-gate     Integer MaxRenew;		// krb5_deltat max_renewable_life;
61*0Sstevel@tonic-gate     Date ModTime;		// krb5_timestamp mod_date;
62*0Sstevel@tonic-gate     String ModName;		// krb5_principal mod_name;
63*0Sstevel@tonic-gate     Date LastSuccess;		// krb5_timestamp last_success;
64*0Sstevel@tonic-gate     Date LastFailure;		// krb5_timestamp last_failed;
65*0Sstevel@tonic-gate     Integer NumFailures;	// krb5_kvno fail_auth_count;
66*0Sstevel@tonic-gate     String Comments;		// ==> entry in tl_data array
67*0Sstevel@tonic-gate     Integer Kvno;		// krb5_kvno kvno;
68*0Sstevel@tonic-gate     Integer Mkvno;		// krb5_kvno mkvno;
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate     String PrPasswd;		// standalone field in Kadmin API
71*0Sstevel@tonic-gate     Kadmin Kadmin;
72*0Sstevel@tonic-gate     boolean isNew;		// newly created principal?
73*0Sstevel@tonic-gate     boolean dummy;		// use dummy data?
74*0Sstevel@tonic-gate     boolean newComments;	// are comments new or changed?
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate     /**
77*0Sstevel@tonic-gate      * Initialize new principal to defaults - this one is for new creations
78*0Sstevel@tonic-gate      */
79*0Sstevel@tonic-gate     public Principal() {
80*0Sstevel@tonic-gate         isNew = true;
81*0Sstevel@tonic-gate         dummy = true;
82*0Sstevel@tonic-gate         newComments = false;
83*0Sstevel@tonic-gate         PrName = new String("");
84*0Sstevel@tonic-gate         PrPasswd = new String("");
85*0Sstevel@tonic-gate         Calendar cal = Calendar.getInstance();
86*0Sstevel@tonic-gate         cal.setTime(new Date());	    /* start with now ... */
87*0Sstevel@tonic-gate         cal.add(Calendar.YEAR, 1);	    /* ... add a year ... XXX */
88*0Sstevel@tonic-gate         PrExpireTime = cal.getTime();  /* ... to get expiry */
89*0Sstevel@tonic-gate         Policy = new String("");
90*0Sstevel@tonic-gate         LastPwChange = new Date(0);    /* never */
91*0Sstevel@tonic-gate         PwExpireTime = null; // may be server side default
92*0Sstevel@tonic-gate         MaxLife = null; // may be server side default
93*0Sstevel@tonic-gate         MaxRenew = null; // may be server side default
94*0Sstevel@tonic-gate         ModTime = new Date();	    /* now */
95*0Sstevel@tonic-gate         ModName = System.getProperty("user.name");
96*0Sstevel@tonic-gate         LastSuccess = new Date(0);	    /* never */
97*0Sstevel@tonic-gate         LastFailure = new Date(0);	    /* never */
98*0Sstevel@tonic-gate         NumFailures = new Integer(0);
99*0Sstevel@tonic-gate         Comments = new String("");
100*0Sstevel@tonic-gate         Kvno = new Integer(0);
101*0Sstevel@tonic-gate         Mkvno = new Integer(0);
102*0Sstevel@tonic-gate         flags = new Flags();
103*0Sstevel@tonic-gate     }
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate     /*
106*0Sstevel@tonic-gate      * This is used for loading an existing principal
107*0Sstevel@tonic-gate      */
108*0Sstevel@tonic-gate     public Principal(String Pname) {
109*0Sstevel@tonic-gate 	/* Get some specific data from somewhere */
110*0Sstevel@tonic-gate 	this();
111*0Sstevel@tonic-gate 	isNew = false;
112*0Sstevel@tonic-gate 	PrName = Pname;
113*0Sstevel@tonic-gate 	PwExpireTime = new Date(0);
114*0Sstevel@tonic-gate 	loadPrincipal(Pname);
115*0Sstevel@tonic-gate     }
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate     /*
118*0Sstevel@tonic-gate      * This is used for duplicating a new principal from an old one
119*0Sstevel@tonic-gate      */
120*0Sstevel@tonic-gate     public Principal(Principal old) {
121*0Sstevel@tonic-gate 	/* Copy old principal to new one */
122*0Sstevel@tonic-gate 	this();
123*0Sstevel@tonic-gate 	copyPrincipal(old, this);
124*0Sstevel@tonic-gate     }
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate     /*
127*0Sstevel@tonic-gate      * For real data, use Kadmin as a first argument
128*0Sstevel@tonic-gate      */
129*0Sstevel@tonic-gate     public Principal(Kadmin session, Defaults defaults) {
130*0Sstevel@tonic-gate 	this();
131*0Sstevel@tonic-gate 	dummy = false;
132*0Sstevel@tonic-gate 	Kadmin = session;
133*0Sstevel@tonic-gate 	setDefaults(defaults);
134*0Sstevel@tonic-gate     }
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate     public Principal(Kadmin session, String Pname) {
137*0Sstevel@tonic-gate 	this();
138*0Sstevel@tonic-gate 	isNew = false;
139*0Sstevel@tonic-gate 	dummy = false;
140*0Sstevel@tonic-gate 	Kadmin = session;
141*0Sstevel@tonic-gate 	PrName = Pname;
142*0Sstevel@tonic-gate 	PwExpireTime = new Date(0);
143*0Sstevel@tonic-gate 	loadPrincipal(Pname);
144*0Sstevel@tonic-gate     }
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate     public Principal(Kadmin session, Principal old) {
147*0Sstevel@tonic-gate 	this(old);
148*0Sstevel@tonic-gate 	dummy = false;
149*0Sstevel@tonic-gate 	Kadmin = session;
150*0Sstevel@tonic-gate     }
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate     public void setDefaults(Defaults defaults) {
153*0Sstevel@tonic-gate         flags = new Flags(defaults.getFlags().getBits());
154*0Sstevel@tonic-gate         if (!defaults.getServerSide()) {
155*0Sstevel@tonic-gate             MaxLife  = defaults.getMaxTicketLife();
156*0Sstevel@tonic-gate             MaxRenew = defaults.getMaxTicketRenewableLife();
157*0Sstevel@tonic-gate         }
158*0Sstevel@tonic-gate         PrExpireTime = defaults.getAccountExpiryDate();
159*0Sstevel@tonic-gate     }
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate     /**
162*0Sstevel@tonic-gate      * Copy relevant fields from old principal, overriding as necessary
163*0Sstevel@tonic-gate      */
164*0Sstevel@tonic-gate     public static void copyPrincipal(Principal old, Principal curr) {
165*0Sstevel@tonic-gate 	curr.PrName = new String("");	    /* override */
166*0Sstevel@tonic-gate 	curr.PrPasswd = new String("");	    /* override */
167*0Sstevel@tonic-gate 	curr.PrExpireTime = new Date(old.PrExpireTime.getTime());
168*0Sstevel@tonic-gate 	curr.Policy = new String(old.Policy);
169*0Sstevel@tonic-gate 	curr.LastPwChange = new Date(0);    /* override: never */
170*0Sstevel@tonic-gate 	if (old.PwExpireTime == null)
171*0Sstevel@tonic-gate 	    curr.PwExpireTime = null;
172*0Sstevel@tonic-gate 	else
173*0Sstevel@tonic-gate 	    curr.PwExpireTime = new Date(old.PwExpireTime.getTime());
174*0Sstevel@tonic-gate 	curr.MaxLife = new Integer(old.MaxLife.intValue());
175*0Sstevel@tonic-gate 	curr.MaxRenew = new Integer(old.MaxRenew.intValue());
176*0Sstevel@tonic-gate 	curr.ModTime = new Date();	    /* override: now */
177*0Sstevel@tonic-gate 	curr.ModName = System.getProperty("user.name");	    /* override */
178*0Sstevel@tonic-gate 	curr.LastSuccess = new Date(0);	    /* override: never */
179*0Sstevel@tonic-gate 	curr.LastFailure = new Date(0);	    /* override: never */
180*0Sstevel@tonic-gate 	curr.NumFailures = new Integer(0);  /* override: none */
181*0Sstevel@tonic-gate 	curr.Comments = new String(old.Comments);
182*0Sstevel@tonic-gate 	curr.Kvno = new Integer(old.Kvno.intValue());
183*0Sstevel@tonic-gate 	curr.Mkvno = new Integer(old.Mkvno.intValue());
184*0Sstevel@tonic-gate 	curr.flags = new Flags(old.flags.getBits());
185*0Sstevel@tonic-gate     }
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate     public boolean loadPrincipal(String name) {
188*0Sstevel@tonic-gate 	if (dummy)
189*0Sstevel@tonic-gate 		return true;
190*0Sstevel@tonic-gate 	boolean b = Kadmin.loadPrincipal(name, this);
191*0Sstevel@tonic-gate 	// System.out.println(this.toString());
192*0Sstevel@tonic-gate 	return b;
193*0Sstevel@tonic-gate     }
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate     public boolean savePrincipal() {
196*0Sstevel@tonic-gate 	// System.out.println(this.toString());
197*0Sstevel@tonic-gate 	if (dummy)
198*0Sstevel@tonic-gate 		return true;
199*0Sstevel@tonic-gate 	if (MaxLife == null)
200*0Sstevel@tonic-gate 	  MaxLife = INFINITE_LIFE;
201*0Sstevel@tonic-gate 	if (MaxRenew == null)
202*0Sstevel@tonic-gate 	  MaxRenew = INFINITE_LIFE;
203*0Sstevel@tonic-gate 	if (this.isNew)
204*0Sstevel@tonic-gate 	    return Kadmin.createPrincipal(this);
205*0Sstevel@tonic-gate 	else
206*0Sstevel@tonic-gate 	    return Kadmin.savePrincipal(this);
207*0Sstevel@tonic-gate     }
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate     public boolean setName(String name) {
211*0Sstevel@tonic-gate 	// xxx: see where this gets called from to determine if a new Principal
212*0Sstevel@tonic-gate 	// just added can have a duplicate name or whether that would have been
213*0Sstevel@tonic-gate 	// screened out earlier.
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 	PrName = name;
216*0Sstevel@tonic-gate 	return true;
217*0Sstevel@tonic-gate     }
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate     public boolean setComments(String comments) {
220*0Sstevel@tonic-gate 	  // xxx: check to see if all characters are in the allowable list of
221*0Sstevel@tonic-gate 	  // characters. The list needs to be I18N. No length restrictions on
222*0Sstevel@tonic-gate 	  // Java side but what about the c side?
223*0Sstevel@tonic-gate         Comments = comments;
224*0Sstevel@tonic-gate         newComments = true;
225*0Sstevel@tonic-gate         return true;
226*0Sstevel@tonic-gate     }
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate     public boolean setPolicy(String pol) {
229*0Sstevel@tonic-gate 	  // xxx: is this a valid policy name? Should we assume that error is
230*0Sstevel@tonic-gate 	  // already trapped before this point?
231*0Sstevel@tonic-gate 	Policy = pol;
232*0Sstevel@tonic-gate 	return true;
233*0Sstevel@tonic-gate     }
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate     public boolean setPassword(String pw) {
236*0Sstevel@tonic-gate 	  // xxx: check to see if the passwd follows the rules laid down by
237*0Sstevel@tonic-gate 	  // the policy
238*0Sstevel@tonic-gate 	PrPasswd = pw;
239*0Sstevel@tonic-gate 	return true;
240*0Sstevel@tonic-gate     }
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate     /**
243*0Sstevel@tonic-gate      * @param exp Contains a date formatted by the default locale,
244*0Sstevel@tonic-gate      * representing the expiry time for the principal's expiration.
245*0Sstevel@tonic-gate      */
246*0Sstevel@tonic-gate     public boolean setExpiry(String exp) {
247*0Sstevel@tonic-gate         exp = exp.trim();
248*0Sstevel@tonic-gate         if (exp.equalsIgnoreCase(neverString))
249*0Sstevel@tonic-gate            PrExpireTime = new Date(0);
250*0Sstevel@tonic-gate         else {
251*0Sstevel@tonic-gate             try {
252*0Sstevel@tonic-gate    	        PrExpireTime = df.parse(exp);
253*0Sstevel@tonic-gate             } catch (ParseException e) {
254*0Sstevel@tonic-gate 	        return false;
255*0Sstevel@tonic-gate             } catch (NullPointerException e) {
256*0Sstevel@tonic-gate 	        // gets thrown when parse string begins with text
257*0Sstevel@tonic-gate 	        // probable JDK bug
258*0Sstevel@tonic-gate 	        return false;
259*0Sstevel@tonic-gate             } catch (StringIndexOutOfBoundsException e) {
260*0Sstevel@tonic-gate 	        // gets thrown when parse string contains only one number
261*0Sstevel@tonic-gate 	        // probable JDK bug
262*0Sstevel@tonic-gate 	        return false;
263*0Sstevel@tonic-gate             }
264*0Sstevel@tonic-gate         }
265*0Sstevel@tonic-gate         return true;
266*0Sstevel@tonic-gate     }
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate     /**
269*0Sstevel@tonic-gate      * @param exp Contains a date formatted by the default locale,
270*0Sstevel@tonic-gate      * representing the expiry time for the password expiration.
271*0Sstevel@tonic-gate      */
272*0Sstevel@tonic-gate     public boolean setPwExpiry(String exp) {
273*0Sstevel@tonic-gate         exp = exp.trim();
274*0Sstevel@tonic-gate         if (exp.equals(""))
275*0Sstevel@tonic-gate             PwExpireTime = null;
276*0Sstevel@tonic-gate         else if (exp.equalsIgnoreCase(neverString))
277*0Sstevel@tonic-gate             PwExpireTime = new Date(0);
278*0Sstevel@tonic-gate         else {
279*0Sstevel@tonic-gate             try {
280*0Sstevel@tonic-gate     	        PwExpireTime = df.parse(exp);
281*0Sstevel@tonic-gate             } catch (ParseException e) {
282*0Sstevel@tonic-gate 	        return false;
283*0Sstevel@tonic-gate             } catch (NullPointerException e) {
284*0Sstevel@tonic-gate 	        // gets thrown when parse string begins with text
285*0Sstevel@tonic-gate 	        // probable JDK bug
286*0Sstevel@tonic-gate 	        return false;
287*0Sstevel@tonic-gate             }  catch (StringIndexOutOfBoundsException e) {
288*0Sstevel@tonic-gate 	        // gets thrown when parse string contains only one number
289*0Sstevel@tonic-gate 	        // probable JDK bug
290*0Sstevel@tonic-gate 	        return false;
291*0Sstevel@tonic-gate             }
292*0Sstevel@tonic-gate         }
293*0Sstevel@tonic-gate         return true;
294*0Sstevel@tonic-gate     }
295*0Sstevel@tonic-gate 
296*0Sstevel@tonic-gate     public String getModTime() {
297*0Sstevel@tonic-gate         if (ModTime.getTime() == 0)
298*0Sstevel@tonic-gate             return neverString;
299*0Sstevel@tonic-gate         else
300*0Sstevel@tonic-gate             return df.format(ModTime);
301*0Sstevel@tonic-gate     }
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate     public String getExpiry() {
304*0Sstevel@tonic-gate         if (PrExpireTime.getTime() == 0)
305*0Sstevel@tonic-gate             return neverString;
306*0Sstevel@tonic-gate         else
307*0Sstevel@tonic-gate             return df.format(PrExpireTime);
308*0Sstevel@tonic-gate     }
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate     public String getLastSuccess() {
311*0Sstevel@tonic-gate         if (LastSuccess.getTime() == 0)
312*0Sstevel@tonic-gate             return neverString;
313*0Sstevel@tonic-gate         else
314*0Sstevel@tonic-gate             return df.format(LastSuccess);
315*0Sstevel@tonic-gate     }
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate     public String getLastFailure() {
318*0Sstevel@tonic-gate         if (LastFailure.getTime() == 0)
319*0Sstevel@tonic-gate             return neverString;
320*0Sstevel@tonic-gate         else
321*0Sstevel@tonic-gate             return df.format(LastFailure);
322*0Sstevel@tonic-gate     }
323*0Sstevel@tonic-gate 
324*0Sstevel@tonic-gate     public String getLastPwChange() {
325*0Sstevel@tonic-gate         if (LastPwChange.getTime() == 0)
326*0Sstevel@tonic-gate             return neverString;
327*0Sstevel@tonic-gate         else
328*0Sstevel@tonic-gate             return df.format(LastPwChange);
329*0Sstevel@tonic-gate     }
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate     public String getPwExpireTime() {
332*0Sstevel@tonic-gate         if (PwExpireTime == null)
333*0Sstevel@tonic-gate             return new String("");
334*0Sstevel@tonic-gate         else if (PwExpireTime.getTime() == 0)
335*0Sstevel@tonic-gate             return neverString;
336*0Sstevel@tonic-gate         else
337*0Sstevel@tonic-gate             return df.format(PwExpireTime);
338*0Sstevel@tonic-gate     }
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate     public String getMaxLife() {
341*0Sstevel@tonic-gate         if (MaxLife != null)
342*0Sstevel@tonic-gate             return nf.format(MaxLife.longValue());
343*0Sstevel@tonic-gate         else
344*0Sstevel@tonic-gate             return "";
345*0Sstevel@tonic-gate     }
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate     public String getMaxRenew() {
348*0Sstevel@tonic-gate         if (MaxRenew != null)
349*0Sstevel@tonic-gate             return nf.format(MaxRenew.longValue());
350*0Sstevel@tonic-gate         else
351*0Sstevel@tonic-gate             return "";
352*0Sstevel@tonic-gate     }
353*0Sstevel@tonic-gate 
354*0Sstevel@tonic-gate     /**
355*0Sstevel@tonic-gate      * @param vers Contains a number representing the key version.
356*0Sstevel@tonic-gate      */
357*0Sstevel@tonic-gate     public boolean setKvno(String vers) {
358*0Sstevel@tonic-gate 	try {
359*0Sstevel@tonic-gate 	    Kvno = new Integer(nf.parse(vers.trim()).intValue());
360*0Sstevel@tonic-gate 	}catch (ParseException e) {
361*0Sstevel@tonic-gate 	    return false;
362*0Sstevel@tonic-gate 	}
363*0Sstevel@tonic-gate 	return true;
364*0Sstevel@tonic-gate     }
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate     /**
367*0Sstevel@tonic-gate      * @param val Contains a number representing the maximum lifetime, in
368*0Sstevel@tonic-gate      * seconds, of a ticket for this principal.
369*0Sstevel@tonic-gate      */
370*0Sstevel@tonic-gate     public boolean setMaxlife(String val) {
371*0Sstevel@tonic-gate 	try {
372*0Sstevel@tonic-gate 	    String noSpace = val.trim();
373*0Sstevel@tonic-gate 	    if (noSpace.length() == 0)
374*0Sstevel@tonic-gate 	        return true;
375*0Sstevel@tonic-gate 	    MaxLife = new Integer(nf.parse(noSpace).intValue());
376*0Sstevel@tonic-gate 	}catch (ParseException e) {
377*0Sstevel@tonic-gate 	    return false;
378*0Sstevel@tonic-gate 	}
379*0Sstevel@tonic-gate 	return true;
380*0Sstevel@tonic-gate     }
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate     /**
383*0Sstevel@tonic-gate      * @param val Contains a number representing the maximum renewable lifetime,
384*0Sstevel@tonic-gate      * in seconds, of a ticket for this principal.
385*0Sstevel@tonic-gate      */
386*0Sstevel@tonic-gate     public boolean setMaxrenew(String val) {
387*0Sstevel@tonic-gate 	try {
388*0Sstevel@tonic-gate 	    String noSpace = val.trim();
389*0Sstevel@tonic-gate 	    if (noSpace.length() == 0)
390*0Sstevel@tonic-gate 	        return true;
391*0Sstevel@tonic-gate 	    MaxRenew = new Integer(nf.parse(noSpace).intValue());
392*0Sstevel@tonic-gate 	}catch (ParseException e) {
393*0Sstevel@tonic-gate 	    return false;
394*0Sstevel@tonic-gate 	}
395*0Sstevel@tonic-gate 	return true;
396*0Sstevel@tonic-gate     }
397*0Sstevel@tonic-gate 
398*0Sstevel@tonic-gate     /**
399*0Sstevel@tonic-gate      * Toggles a particular flag.
400*0Sstevel@tonic-gate      * @param mask one of the statically defined masks indicating which flag to
401*0Sstevel@tonic-gate      * toggle.
402*0Sstevel@tonic-gate      */
403*0Sstevel@tonic-gate     public boolean setFlag(int mask) {
404*0Sstevel@tonic-gate         flags.toggleFlags(mask);
405*0Sstevel@tonic-gate         return true;
406*0Sstevel@tonic-gate     }
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate     /**
409*0Sstevel@tonic-gate      * Obtain a string representation of this principal.
410*0Sstevel@tonic-gate      * @return a String containing the following information about this
411*0Sstevel@tonic-gate      * principal:<br>
412*0Sstevel@tonic-gate      * <ul>
413*0Sstevel@tonic-gate      * <li>principal name
414*0Sstevel@tonic-gate      *<li>policy being applied
415*0Sstevel@tonic-gate      *<li>expiry date
416*0Sstevel@tonic-gate      *<li>comments
417*0Sstevel@tonic-gate      *<li>key version number
418*0Sstevel@tonic-gate      *<li>password expire time
419*0Sstevel@tonic-gate      *<li>maximum lifetime
420*0Sstevel@tonic-gate      *<li>maximum renewable lifetime
421*0Sstevel@tonic-gate      * <li> flags
422*0Sstevel@tonic-gate      *</ul>
423*0Sstevel@tonic-gate      */
424*0Sstevel@tonic-gate     public String toString() {
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate         StringBuffer sb = new StringBuffer();
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate         sb.append(getString("Principal Name:") + "  " + PrName).append('\n');
429*0Sstevel@tonic-gate         sb.append(getString("Account Expires:") + "  "
430*0Sstevel@tonic-gate               + getExpiry()).append('\n');
431*0Sstevel@tonic-gate         sb.append(getString("Policy:") + "  " + Policy).append('\n');
432*0Sstevel@tonic-gate         sb.append(getString("Comments:") + "  " + Comments).append('\n');
433*0Sstevel@tonic-gate         sb.append(getString("Key Version:") + "	" + Kvno).append('\t');
434*0Sstevel@tonic-gate         sb.append(getString("Password Expires:") + "  "
435*0Sstevel@tonic-gate               + getPwExpireTime()).append('\n');
436*0Sstevel@tonic-gate         sb.append(getString("Maximum Lifetime (seconds):")
437*0Sstevel@tonic-gate 	      + "	 " + getMaxLife()).append('\t');
438*0Sstevel@tonic-gate         sb.append(getString("Maximum Renewal (seconds):")
439*0Sstevel@tonic-gate 	      + "	 " + getMaxRenew()).append('\n');
440*0Sstevel@tonic-gate         sb.append(getString("Flags:")).append('\n').append(flags.toString());
441*0Sstevel@tonic-gate 
442*0Sstevel@tonic-gate         return sb.toString();
443*0Sstevel@tonic-gate     }
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate     /**
446*0Sstevel@tonic-gate      * Call rb.getString(), but catch exception and return English
447*0Sstevel@tonic-gate      * key so that small spelling errors don't cripple the GUI
448*0Sstevel@tonic-gate      *
449*0Sstevel@tonic-gate      */
450*0Sstevel@tonic-gate     private static final String getString(String key) {
451*0Sstevel@tonic-gate         try {
452*0Sstevel@tonic-gate     	    String res = rb.getString(key);
453*0Sstevel@tonic-gate 	    return res;
454*0Sstevel@tonic-gate         } catch (MissingResourceException e) {
455*0Sstevel@tonic-gate 	    System.out.println("Missing resource "+key+", using English.");
456*0Sstevel@tonic-gate 	    return key;
457*0Sstevel@tonic-gate         }
458*0Sstevel@tonic-gate     }
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate     static {
461*0Sstevel@tonic-gate         rb = ResourceBundle.getBundle("GuiResource" /* NOI18N */);
462*0Sstevel@tonic-gate         df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
463*0Sstevel@tonic-gate                                             DateFormat.MEDIUM);
464*0Sstevel@tonic-gate         nf = NumberFormat.getInstance();
465*0Sstevel@tonic-gate         neverString = getString("Never");
466*0Sstevel@tonic-gate     }
467*0Sstevel@tonic-gate 
468*0Sstevel@tonic-gate }
469