17c478bd9Sstevel@tonic-gate /* 2*a49a392fSps57422 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 77c478bd9Sstevel@tonic-gate 87c478bd9Sstevel@tonic-gate /* 97c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 127c478bd9Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 137c478bd9Sstevel@tonic-gate * source code before consulting with your legal department. 147c478bd9Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 157c478bd9Sstevel@tonic-gate * product before consulting with your legal department. 167c478bd9Sstevel@tonic-gate * 177c478bd9Sstevel@tonic-gate * For further information, read the top-level Openvision 187c478bd9Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 197c478bd9Sstevel@tonic-gate * copyright. 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 227c478bd9Sstevel@tonic-gate * 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * kadmin/ktutil/ktutil.c 287c478bd9Sstevel@tonic-gate * 297c478bd9Sstevel@tonic-gate * Copyright 1995, 1996 by the Massachusetts Institute of Technology. 307c478bd9Sstevel@tonic-gate * All Rights Reserved. 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 337c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 347c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 357c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 387c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 397c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 407c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 417c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 427c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 437c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 447c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 457c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 467c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 477c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 487c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 497c478bd9Sstevel@tonic-gate * or implied warranty. 507c478bd9Sstevel@tonic-gate * 517c478bd9Sstevel@tonic-gate * SS user interface for ktutil. 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include "k5-int.h" 557c478bd9Sstevel@tonic-gate #include "ktutil.h" 567c478bd9Sstevel@tonic-gate #include <com_err.h> 577c478bd9Sstevel@tonic-gate #include <ss/ss.h> 587c478bd9Sstevel@tonic-gate #include <stdio.h> 597c478bd9Sstevel@tonic-gate #ifdef HAVE_STDLIB_H 607c478bd9Sstevel@tonic-gate #include <stdlib.h> 617c478bd9Sstevel@tonic-gate #endif 627c478bd9Sstevel@tonic-gate #include <libintl.h> 637c478bd9Sstevel@tonic-gate #include <locale.h> 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate extern ss_request_table ktutil_cmds; 667c478bd9Sstevel@tonic-gate krb5_context kcontext; 677c478bd9Sstevel@tonic-gate krb5_kt_list ktlist = NULL; 687c478bd9Sstevel@tonic-gate 6956a424ccSmp153739 int main(argc, argv) 707c478bd9Sstevel@tonic-gate int argc; 717c478bd9Sstevel@tonic-gate char *argv[]; 727c478bd9Sstevel@tonic-gate { 737c478bd9Sstevel@tonic-gate krb5_error_code retval; 747c478bd9Sstevel@tonic-gate int sci_idx; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 797c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 807c478bd9Sstevel@tonic-gate #endif 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate retval = krb5_init_context(&kcontext); 857c478bd9Sstevel@tonic-gate if (retval) { 867c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing krb5")); 877c478bd9Sstevel@tonic-gate exit(1); 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate retval = ktutil_initialize_cmds_table (&ktutil_cmds); 907c478bd9Sstevel@tonic-gate if (retval) { 917c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 927c478bd9Sstevel@tonic-gate gettext("while localizing command description messages")); 937c478bd9Sstevel@tonic-gate exit(1); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate sci_idx = ss_create_invocation("ktutil", "5.0", (char *) NULL, 967c478bd9Sstevel@tonic-gate &ktutil_cmds, &retval); 977c478bd9Sstevel@tonic-gate if (retval) { 987c478bd9Sstevel@tonic-gate ss_perror(sci_idx, retval, gettext("creating invocation")); 997c478bd9Sstevel@tonic-gate exit(1); 1007c478bd9Sstevel@tonic-gate } 10156a424ccSmp153739 retval = ss_listen(sci_idx); 1027c478bd9Sstevel@tonic-gate ktutil_free_kt_list(kcontext, ktlist); 1037c478bd9Sstevel@tonic-gate exit(0); 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate 10656a424ccSmp153739 void ktutil_clear_list(argc, argv) 1077c478bd9Sstevel@tonic-gate int argc; 1087c478bd9Sstevel@tonic-gate char *argv[]; 1097c478bd9Sstevel@tonic-gate { 1107c478bd9Sstevel@tonic-gate krb5_error_code retval; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate if (argc != 1) { 1137c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: invalid arguments\n"), argv[0]); 1147c478bd9Sstevel@tonic-gate return; 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate retval = ktutil_free_kt_list(kcontext, ktlist); 1177c478bd9Sstevel@tonic-gate if (retval) 1187c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while freeing ktlist")); 1197c478bd9Sstevel@tonic-gate ktlist = NULL; 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate 12256a424ccSmp153739 void ktutil_read_v5(argc, argv) 1237c478bd9Sstevel@tonic-gate int argc; 1247c478bd9Sstevel@tonic-gate char *argv[]; 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate krb5_error_code retval; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate if (argc != 2) { 1297c478bd9Sstevel@tonic-gate fprintf(stderr, 1307c478bd9Sstevel@tonic-gate gettext("%s: must specify keytab to read\n"), argv[0]); 1317c478bd9Sstevel@tonic-gate return; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate retval = ktutil_read_keytab(kcontext, argv[1], &ktlist); 1347c478bd9Sstevel@tonic-gate if (retval) 1357c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 1367c478bd9Sstevel@tonic-gate gettext("while reading keytab \"%s\""), argv[1]); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 13956a424ccSmp153739 void ktutil_read_v4(argc, argv) 1407c478bd9Sstevel@tonic-gate int argc; 1417c478bd9Sstevel@tonic-gate char *argv[]; 1427c478bd9Sstevel@tonic-gate { 1437c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1447c478bd9Sstevel@tonic-gate krb5_error_code retval; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate if (argc != 2) { 1477c478bd9Sstevel@tonic-gate fprintf(stderr, 1487c478bd9Sstevel@tonic-gate gettext("%s: must specify the srvtab to read\n"), argv[0]); 1497c478bd9Sstevel@tonic-gate return; 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate retval = ktutil_read_srvtab(kcontext, argv[1], &ktlist); 1527c478bd9Sstevel@tonic-gate if (retval) 1537c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 1547c478bd9Sstevel@tonic-gate gettext("while reading srvtab \"%s\""), argv[1]); 1557c478bd9Sstevel@tonic-gate #else 1567c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]); 1577c478bd9Sstevel@tonic-gate #endif 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 16056a424ccSmp153739 void ktutil_write_v5(argc, argv) 1617c478bd9Sstevel@tonic-gate int argc; 1627c478bd9Sstevel@tonic-gate char *argv[]; 1637c478bd9Sstevel@tonic-gate { 1647c478bd9Sstevel@tonic-gate krb5_error_code retval; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate if (argc != 2) { 1677c478bd9Sstevel@tonic-gate fprintf(stderr, 1687c478bd9Sstevel@tonic-gate gettext("%s: must specify keytab to write\n"), argv[0]); 1697c478bd9Sstevel@tonic-gate return; 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate retval = ktutil_write_keytab(kcontext, ktlist, argv[1]); 1727c478bd9Sstevel@tonic-gate if (retval) 1737c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 1747c478bd9Sstevel@tonic-gate gettext("while writing keytab \"%s\""), argv[1]); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 17756a424ccSmp153739 void ktutil_write_v4(argc, argv) 1787c478bd9Sstevel@tonic-gate int argc; 1797c478bd9Sstevel@tonic-gate char *argv[]; 1807c478bd9Sstevel@tonic-gate { 1817c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1827c478bd9Sstevel@tonic-gate krb5_error_code retval; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (argc != 2) { 1857c478bd9Sstevel@tonic-gate fprintf(stderr, 1867c478bd9Sstevel@tonic-gate gettext("%s: must specify srvtab to write\n"), argv[0]); 1877c478bd9Sstevel@tonic-gate return; 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate retval = ktutil_write_srvtab(kcontext, ktlist, argv[1]); 1907c478bd9Sstevel@tonic-gate if (retval) 1917c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 1927c478bd9Sstevel@tonic-gate gettext("while writing srvtab \"%s\""), argv[1]); 1937c478bd9Sstevel@tonic-gate #else 1947c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]); 1957c478bd9Sstevel@tonic-gate #endif 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate void ktutil_add_entry(argc, argv) 1997c478bd9Sstevel@tonic-gate int argc; 2007c478bd9Sstevel@tonic-gate char *argv[]; 2017c478bd9Sstevel@tonic-gate { 2027c478bd9Sstevel@tonic-gate krb5_error_code retval; 2037c478bd9Sstevel@tonic-gate char *princ = NULL; 2047c478bd9Sstevel@tonic-gate char *enctype = NULL; 2057c478bd9Sstevel@tonic-gate krb5_kvno kvno = 0; 2067c478bd9Sstevel@tonic-gate int use_pass = 0, use_key = 0, i; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i++) { 2097c478bd9Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { 2107c478bd9Sstevel@tonic-gate princ = argv[++i]; 2117c478bd9Sstevel@tonic-gate continue; 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { 2147c478bd9Sstevel@tonic-gate kvno = (krb5_kvno) atoi(argv[++i]); 2157c478bd9Sstevel@tonic-gate continue; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { 2187c478bd9Sstevel@tonic-gate enctype = argv[++i]; 2197c478bd9Sstevel@tonic-gate continue; 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate if ((strlen(argv[i]) == 9) && !strncmp(argv[i], "-password", 9)) { 2227c478bd9Sstevel@tonic-gate use_pass++; 2237c478bd9Sstevel@tonic-gate continue; 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate if ((strlen(argv[i]) == 4) && !strncmp(argv[i], "-key", 4)) { 2267c478bd9Sstevel@tonic-gate use_key++; 2277c478bd9Sstevel@tonic-gate continue; 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) { 2327c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s (-key | -password) -p principal " 2337c478bd9Sstevel@tonic-gate "-k kvno -e enctype\n", gettext("usage"), argv[0]); 2347c478bd9Sstevel@tonic-gate return; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass); 2387c478bd9Sstevel@tonic-gate if (retval) 2397c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while adding new entry")); 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate 24256a424ccSmp153739 void ktutil_delete_entry(argc, argv) 2437c478bd9Sstevel@tonic-gate int argc; 2447c478bd9Sstevel@tonic-gate char *argv[]; 2457c478bd9Sstevel@tonic-gate { 2467c478bd9Sstevel@tonic-gate krb5_error_code retval; 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate if (argc != 2) { 2497c478bd9Sstevel@tonic-gate fprintf(stderr, 2507c478bd9Sstevel@tonic-gate gettext("%s: must specify entry to delete\n"), argv[0]); 2517c478bd9Sstevel@tonic-gate return; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate retval = ktutil_delete(kcontext, &ktlist, atoi(argv[1])); 2547c478bd9Sstevel@tonic-gate if (retval) 2557c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 2567c478bd9Sstevel@tonic-gate gettext("while deleting entry %d"), atoi(argv[1])); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 25956a424ccSmp153739 void ktutil_list(argc, argv) 2607c478bd9Sstevel@tonic-gate int argc; 2617c478bd9Sstevel@tonic-gate char *argv[]; 2627c478bd9Sstevel@tonic-gate { 2637c478bd9Sstevel@tonic-gate krb5_error_code retval; 2647c478bd9Sstevel@tonic-gate krb5_kt_list lp; 2657c478bd9Sstevel@tonic-gate int show_time = 0, show_keys = 0, show_enctype = 0; 2667c478bd9Sstevel@tonic-gate int i, j; 2677c478bd9Sstevel@tonic-gate char *pname; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i++) { 27056a424ccSmp153739 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-t", 2)) { 2717c478bd9Sstevel@tonic-gate show_time++; 2727c478bd9Sstevel@tonic-gate continue; 2737c478bd9Sstevel@tonic-gate } 27456a424ccSmp153739 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { 2757c478bd9Sstevel@tonic-gate show_keys++; 2767c478bd9Sstevel@tonic-gate continue; 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { 2797c478bd9Sstevel@tonic-gate show_enctype++; 2807c478bd9Sstevel@tonic-gate continue; 2817c478bd9Sstevel@tonic-gate } 28256a424ccSmp153739 28356a424ccSmp153739 fprintf(stderr, "%s: %s [-t] [-k] [-e]\n", gettext("usage"), argv[0]); 2847c478bd9Sstevel@tonic-gate return; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate if (show_time) { 2877c478bd9Sstevel@tonic-gate printf(gettext("slot KVNO Timestamp Principal\n")); 2887c478bd9Sstevel@tonic-gate printf("---- ---- ----------------- ---------------------------------------------------\n"); 2897c478bd9Sstevel@tonic-gate } else { 2907c478bd9Sstevel@tonic-gate printf(gettext("slot KVNO Principal\n")); 2917c478bd9Sstevel@tonic-gate printf("---- ---- ---------------------------------------------------------------------\n"); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate for (i = 1, lp = ktlist; lp; i++, lp = lp->next) { 29456a424ccSmp153739 retval = krb5_unparse_name(kcontext, lp->entry->principal, &pname); 2957c478bd9Sstevel@tonic-gate if (retval) { 2967c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 2977c478bd9Sstevel@tonic-gate gettext("while unparsing principal name")); 2987c478bd9Sstevel@tonic-gate return; 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate printf("%4d %4d ", i, lp->entry->vno); 3017c478bd9Sstevel@tonic-gate if (show_time) { 3027c478bd9Sstevel@tonic-gate char fmtbuf[18]; 3037c478bd9Sstevel@tonic-gate char fill; 30456a424ccSmp153739 time_t tstamp; 3057c478bd9Sstevel@tonic-gate 30656a424ccSmp153739 (void) localtime(&tstamp); 30756a424ccSmp153739 lp->entry->timestamp = tstamp; 3087c478bd9Sstevel@tonic-gate fill = ' '; 30956a424ccSmp153739 if (!krb5_timestamp_to_sfstring((krb5_timestamp)lp->entry-> 31056a424ccSmp153739 timestamp, 3117c478bd9Sstevel@tonic-gate fmtbuf, 3127c478bd9Sstevel@tonic-gate sizeof(fmtbuf), 3137c478bd9Sstevel@tonic-gate &fill)) 3147c478bd9Sstevel@tonic-gate printf("%s ", fmtbuf); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate printf("%40s", pname); 3177c478bd9Sstevel@tonic-gate if (show_enctype) { 3187c478bd9Sstevel@tonic-gate static char buf[256]; 3197c478bd9Sstevel@tonic-gate if ((retval = krb5_enctype_to_string( 3207c478bd9Sstevel@tonic-gate lp->entry->key.enctype, buf, 256))) { 321*a49a392fSps57422 if (retval == EINVAL) 322*a49a392fSps57422 snprintf(buf, sizeof(buf), gettext("unsupported encryption type %d"), 323*a49a392fSps57422 lp->entry->key.enctype); 324*a49a392fSps57422 else { 3257c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 3267c478bd9Sstevel@tonic-gate gettext("While converting " 3277c478bd9Sstevel@tonic-gate "enctype to string")); 3287c478bd9Sstevel@tonic-gate return; 3297c478bd9Sstevel@tonic-gate } 330*a49a392fSps57422 } 3317c478bd9Sstevel@tonic-gate printf(" (%s) ", buf); 3327c478bd9Sstevel@tonic-gate } 33356a424ccSmp153739 3347c478bd9Sstevel@tonic-gate if (show_keys) { 3357c478bd9Sstevel@tonic-gate printf(" (0x"); 3367c478bd9Sstevel@tonic-gate for (j = 0; j < lp->entry->key.length; j++) 3377c478bd9Sstevel@tonic-gate printf("%02x", lp->entry->key.contents[j]); 3387c478bd9Sstevel@tonic-gate printf(")"); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate printf("\n"); 3417c478bd9Sstevel@tonic-gate krb5_xfree(pname); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate 354