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