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 2005 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 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 String EncTypes; // enc type list to be used for key gen 76 77 /** 78 * Initialize new principal to defaults - this one is for new creations 79 */ 80 public Principal() { 81 isNew = true; 82 dummy = true; 83 newComments = false; 84 PrName = new String(""); 85 PrPasswd = new String(""); 86 Calendar cal = Calendar.getInstance(); 87 cal.setTime(new Date()); /* start with now ... */ 88 cal.add(Calendar.YEAR, 1); /* ... add a year ... XXX */ 89 PrExpireTime = cal.getTime(); /* ... to get expiry */ 90 Policy = new String(""); 91 LastPwChange = new Date(0); /* never */ 92 PwExpireTime = null; // may be server side default 93 MaxLife = null; // may be server side default 94 MaxRenew = null; // may be server side default 95 ModTime = new Date(); /* now */ 96 ModName = System.getProperty("user.name"); 97 LastSuccess = new Date(0); /* never */ 98 LastFailure = new Date(0); /* never */ 99 NumFailures = new Integer(0); 100 Comments = new String(""); 101 Kvno = new Integer(0); 102 Mkvno = new Integer(0); 103 flags = new Flags(); 104 EncTypes = new String(""); 105 } 106 107 /* 108 * This is used for loading an existing principal 109 */ 110 public Principal(String Pname) { 111 /* Get some specific data from somewhere */ 112 this(); 113 isNew = false; 114 PrName = Pname; 115 PwExpireTime = new Date(0); 116 loadPrincipal(Pname); 117 } 118 119 /* 120 * This is used for duplicating a new principal from an old one 121 */ 122 public Principal(Principal old) { 123 /* Copy old principal to new one */ 124 this(); 125 copyPrincipal(old, this); 126 } 127 128 /* 129 * For real data, use Kadmin as a first argument 130 */ 131 public Principal(Kadmin session, Defaults defaults) { 132 this(); 133 dummy = false; 134 Kadmin = session; 135 setDefaults(defaults); 136 } 137 138 public Principal(Kadmin session, String Pname) { 139 this(); 140 isNew = false; 141 dummy = false; 142 Kadmin = session; 143 PrName = Pname; 144 PwExpireTime = new Date(0); 145 loadPrincipal(Pname); 146 } 147 148 public Principal(Kadmin session, Principal old) { 149 this(old); 150 dummy = false; 151 Kadmin = session; 152 } 153 154 public void setDefaults(Defaults defaults) { 155 flags = new Flags(defaults.getFlags().getBits()); 156 if (!defaults.getServerSide()) { 157 MaxLife = defaults.getMaxTicketLife(); 158 MaxRenew = defaults.getMaxTicketRenewableLife(); 159 } 160 PrExpireTime = defaults.getAccountExpiryDate(); 161 } 162 163 /** 164 * Copy relevant fields from old principal, overriding as necessary 165 */ 166 public static void copyPrincipal(Principal old, Principal curr) { 167 curr.PrName = new String(""); /* override */ 168 curr.PrPasswd = new String(""); /* override */ 169 curr.PrExpireTime = new Date(old.PrExpireTime.getTime()); 170 curr.Policy = new String(old.Policy); 171 curr.EncTypes = new String(old.EncTypes); 172 curr.LastPwChange = new Date(0); /* override: never */ 173 if (old.PwExpireTime == null) 174 curr.PwExpireTime = null; 175 else 176 curr.PwExpireTime = new Date(old.PwExpireTime.getTime()); 177 curr.MaxLife = new Integer(old.MaxLife.intValue()); 178 curr.MaxRenew = new Integer(old.MaxRenew.intValue()); 179 curr.ModTime = new Date(); /* override: now */ 180 curr.ModName = System.getProperty("user.name"); /* override */ 181 curr.LastSuccess = new Date(0); /* override: never */ 182 curr.LastFailure = new Date(0); /* override: never */ 183 curr.NumFailures = new Integer(0); /* override: none */ 184 curr.Comments = new String(old.Comments); 185 curr.Kvno = new Integer(old.Kvno.intValue()); 186 curr.Mkvno = new Integer(old.Mkvno.intValue()); 187 curr.flags = new Flags(old.flags.getBits()); 188 } 189 190 public boolean loadPrincipal(String name) { 191 if (dummy) 192 return true; 193 boolean b = Kadmin.loadPrincipal(name, this); 194 // System.out.println(this.toString()); 195 return b; 196 } 197 198 public boolean savePrincipal() { 199 // System.out.println(this.toString()); 200 if (dummy) 201 return true; 202 if (MaxLife == null) 203 MaxLife = INFINITE_LIFE; 204 if (MaxRenew == null) 205 MaxRenew = INFINITE_LIFE; 206 if (this.isNew) 207 return Kadmin.createPrincipal(this); 208 else 209 return Kadmin.savePrincipal(this); 210 } 211 212 213 public boolean setName(String name) { 214 // xxx: see where this gets called from to determine if a new Principal 215 // just added can have a duplicate name or whether that would have been 216 // screened out earlier. 217 218 PrName = name; 219 return true; 220 } 221 222 public boolean setComments(String comments) { 223 // xxx: check to see if all characters are in the allowable list of 224 // characters. The list needs to be I18N. No length restrictions on 225 // Java side but what about the c side? 226 Comments = comments; 227 newComments = true; 228 return true; 229 } 230 231 public boolean setPolicy(String pol) { 232 // xxx: is this a valid policy name? Should we assume that error is 233 // already trapped before this point? 234 Policy = pol; 235 return true; 236 } 237 238 public boolean setPassword(String pw) { 239 // xxx: check to see if the passwd follows the rules laid down by 240 // the policy 241 PrPasswd = pw; 242 return true; 243 } 244 245 public boolean setEncType(String enctype) { 246 EncTypes = enctype; 247 // Don't have to check enc type list provided given that list was 248 // populated from the checkbox list 249 return true; 250 } 251 252 /** 253 * @param exp Contains a date formatted by the default locale, 254 * representing the expiry time for the principal's expiration. 255 */ 256 public boolean setExpiry(String exp) { 257 exp = exp.trim(); 258 if (exp.equalsIgnoreCase(neverString)) 259 PrExpireTime = new Date(0); 260 else { 261 try { 262 PrExpireTime = df.parse(exp); 263 } catch (ParseException e) { 264 return false; 265 } catch (NullPointerException e) { 266 // gets thrown when parse string begins with text 267 // probable JDK bug 268 return false; 269 } catch (StringIndexOutOfBoundsException e) { 270 // gets thrown when parse string contains only one number 271 // probable JDK bug 272 return false; 273 } 274 } 275 return true; 276 } 277 278 /** 279 * @param exp Contains a date formatted by the default locale, 280 * representing the expiry time for the password expiration. 281 */ 282 public boolean setPwExpiry(String exp) { 283 exp = exp.trim(); 284 if (exp.equals("")) 285 PwExpireTime = null; 286 else if (exp.equalsIgnoreCase(neverString)) 287 PwExpireTime = new Date(0); 288 else { 289 try { 290 PwExpireTime = df.parse(exp); 291 } catch (ParseException e) { 292 return false; 293 } catch (NullPointerException e) { 294 // gets thrown when parse string begins with text 295 // probable JDK bug 296 return false; 297 } catch (StringIndexOutOfBoundsException e) { 298 // gets thrown when parse string contains only one number 299 // probable JDK bug 300 return false; 301 } 302 } 303 return true; 304 } 305 306 public String getModTime() { 307 if (ModTime.getTime() == 0) 308 return neverString; 309 else 310 return df.format(ModTime); 311 } 312 313 public String getEncType() { 314 return EncTypes; 315 } 316 317 public String getExpiry() { 318 if (PrExpireTime.getTime() == 0) 319 return neverString; 320 else 321 return df.format(PrExpireTime); 322 } 323 324 public String getLastSuccess() { 325 if (LastSuccess.getTime() == 0) 326 return neverString; 327 else 328 return df.format(LastSuccess); 329 } 330 331 public String getLastFailure() { 332 if (LastFailure.getTime() == 0) 333 return neverString; 334 else 335 return df.format(LastFailure); 336 } 337 338 public String getLastPwChange() { 339 if (LastPwChange.getTime() == 0) 340 return neverString; 341 else 342 return df.format(LastPwChange); 343 } 344 345 public String getPwExpireTime() { 346 if (PwExpireTime == null) 347 return new String(""); 348 else if (PwExpireTime.getTime() == 0) 349 return neverString; 350 else 351 return df.format(PwExpireTime); 352 } 353 354 public String getMaxLife() { 355 if (MaxLife != null) 356 return nf.format(MaxLife.longValue()); 357 else 358 return ""; 359 } 360 361 public String getMaxRenew() { 362 if (MaxRenew != null) 363 return nf.format(MaxRenew.longValue()); 364 else 365 return ""; 366 } 367 368 /** 369 * @param vers Contains a number representing the key version. 370 */ 371 public boolean setKvno(String vers) { 372 try { 373 Kvno = new Integer(nf.parse(vers.trim()).intValue()); 374 }catch (ParseException e) { 375 return false; 376 } 377 return true; 378 } 379 380 /** 381 * @param val Contains a number representing the maximum lifetime, in 382 * seconds, of a ticket for this principal. 383 */ 384 public boolean setMaxlife(String val) { 385 try { 386 String noSpace = val.trim(); 387 if (noSpace.length() == 0) 388 return true; 389 MaxLife = new Integer(nf.parse(noSpace).intValue()); 390 }catch (ParseException e) { 391 return false; 392 } 393 return true; 394 } 395 396 /** 397 * @param val Contains a number representing the maximum renewable lifetime, 398 * in seconds, of a ticket for this principal. 399 */ 400 public boolean setMaxrenew(String val) { 401 try { 402 String noSpace = val.trim(); 403 if (noSpace.length() == 0) 404 return true; 405 MaxRenew = new Integer(nf.parse(noSpace).intValue()); 406 }catch (ParseException e) { 407 return false; 408 } 409 return true; 410 } 411 412 /** 413 * Toggles a particular flag. 414 * @param mask one of the statically defined masks indicating which flag to 415 * toggle. 416 */ 417 public boolean setFlag(int mask) { 418 flags.toggleFlags(mask); 419 return true; 420 } 421 422 /** 423 * Obtain a string representation of this principal. 424 * @return a String containing the following information about this 425 * principal:<br> 426 * <ul> 427 * <li>principal name 428 *<li>policy being applied 429 *<li>expiry date 430 *<li>comments 431 *<li>key version number 432 *<li>password expire time 433 *<li>maximum lifetime 434 *<li>maximum renewable lifetime 435 * <li> flags 436 *</ul> 437 */ 438 public String toString() { 439 440 StringBuffer sb = new StringBuffer(); 441 442 sb.append(getString("Principal Name:") + " " + PrName).append('\n'); 443 sb.append(getString("Account Expires:") + " " 444 + getExpiry()).append('\n'); 445 sb.append(getString("Policy:") + " " + Policy).append('\n'); 446 sb.append(getString("Enc Types:") + " " + EncTypes).append('\n'); 447 sb.append(getString("Comments:") + " " + Comments).append('\n'); 448 sb.append(getString("Key Version:") + " " + Kvno).append('\t'); 449 sb.append(getString("Password Expires:") + " " 450 + getPwExpireTime()).append('\n'); 451 sb.append(getString("Maximum Lifetime (seconds):") 452 + " " + getMaxLife()).append('\t'); 453 sb.append(getString("Maximum Renewal (seconds):") 454 + " " + getMaxRenew()).append('\n'); 455 sb.append(getString("Flags:")).append('\n').append(flags.toString()); 456 457 return sb.toString(); 458 } 459 460 /** 461 * Call rb.getString(), but catch exception and return English 462 * key so that small spelling errors don't cripple the GUI 463 * 464 */ 465 private static final String getString(String key) { 466 try { 467 String res = rb.getString(key); 468 return res; 469 } catch (MissingResourceException e) { 470 System.out.println("Missing resource "+key+", using English."); 471 return key; 472 } 473 } 474 475 static { 476 rb = ResourceBundle.getBundle("GuiResource" /* NOI18N */); 477 df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, 478 DateFormat.MEDIUM); 479 nf = NumberFormat.getInstance(); 480 neverString = getString("Never"); 481 } 482 483 } 484