17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 57c478bd9Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 67c478bd9Sstevel@tonic-gate * source code before consulting with your legal department. 77c478bd9Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 87c478bd9Sstevel@tonic-gate * product before consulting with your legal department. 97c478bd9Sstevel@tonic-gate * 107c478bd9Sstevel@tonic-gate * For further information, read the top-level Openvision 117c478bd9Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 127c478bd9Sstevel@tonic-gate * copyright. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 157c478bd9Sstevel@tonic-gate * 167c478bd9Sstevel@tonic-gate */ 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate /* 207c478bd9Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 217c478bd9Sstevel@tonic-gate * 22*159d09a2SMark Phalan * $Header$ 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__) 26*159d09a2SMark Phalan static char *rcsid = "$Header$"; 277c478bd9Sstevel@tonic-gate #endif 287c478bd9Sstevel@tonic-gate 29*159d09a2SMark Phalan #include "server_internal.h" 307c478bd9Sstevel@tonic-gate #include <sys/types.h> 317c478bd9Sstevel@tonic-gate #include <kadm5/admin.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 33*159d09a2SMark Phalan #include <errno.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #define MAX_PW_HISTORY 10 367c478bd9Sstevel@tonic-gate #define MIN_PW_HISTORY 1 377c478bd9Sstevel@tonic-gate #define MIN_PW_CLASSES 1 387c478bd9Sstevel@tonic-gate #define MAX_PW_CLASSES 5 397c478bd9Sstevel@tonic-gate #define MIN_PW_LENGTH 1 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /* 427c478bd9Sstevel@tonic-gate * Function: kadm5_create_policy 437c478bd9Sstevel@tonic-gate * 447c478bd9Sstevel@tonic-gate * Purpose: Create Policies in the policy DB. 457c478bd9Sstevel@tonic-gate * 467c478bd9Sstevel@tonic-gate * Arguments: 477c478bd9Sstevel@tonic-gate * entry (input) The policy entry to be written out to the DB. 487c478bd9Sstevel@tonic-gate * mask (input) Specifies which fields in entry are to ge written out 497c478bd9Sstevel@tonic-gate * and which get default values. 5056a424ccSmp153739 * <return value> 0 if successful otherwise an error code is returned. 517c478bd9Sstevel@tonic-gate * 527c478bd9Sstevel@tonic-gate * Requires: 537c478bd9Sstevel@tonic-gate * Entry must be a valid principal entry, and mask have a valid value. 547c478bd9Sstevel@tonic-gate * 557c478bd9Sstevel@tonic-gate * Effects: 567c478bd9Sstevel@tonic-gate * Verifies that mask does not specify that the refcount should 577c478bd9Sstevel@tonic-gate * be set as part of the creation, and calls 587c478bd9Sstevel@tonic-gate * kadm5_create_policy_internal. If the refcount *is* 597c478bd9Sstevel@tonic-gate * specified, returns KADM5_BAD_MASK. 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate kadm5_ret_t 637c478bd9Sstevel@tonic-gate kadm5_create_policy(void *server_handle, 647c478bd9Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask) 657c478bd9Sstevel@tonic-gate { 667c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 677c478bd9Sstevel@tonic-gate 6854925bf6Swillf krb5_clear_error_message(((kadm5_server_handle_t)server_handle)->context); 6954925bf6Swillf 707c478bd9Sstevel@tonic-gate if (mask & KADM5_REF_COUNT) 717c478bd9Sstevel@tonic-gate return KADM5_BAD_MASK; 727c478bd9Sstevel@tonic-gate else 737c478bd9Sstevel@tonic-gate return kadm5_create_policy_internal(server_handle, entry, mask); 747c478bd9Sstevel@tonic-gate } 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate /* 777c478bd9Sstevel@tonic-gate * Function: kadm5_create_policy_internal 787c478bd9Sstevel@tonic-gate * 797c478bd9Sstevel@tonic-gate * Purpose: Create Policies in the policy DB. 807c478bd9Sstevel@tonic-gate * 817c478bd9Sstevel@tonic-gate * Arguments: 827c478bd9Sstevel@tonic-gate * entry (input) The policy entry to be written out to the DB. 837c478bd9Sstevel@tonic-gate * mask (input) Specifies which fields in entry are to ge written out 847c478bd9Sstevel@tonic-gate * and which get default values. 8556a424ccSmp153739 * <return value> 0 if successful otherwise an error code is returned. 867c478bd9Sstevel@tonic-gate * 877c478bd9Sstevel@tonic-gate * Requires: 887c478bd9Sstevel@tonic-gate * Entry must be a valid principal entry, and mask have a valid value. 897c478bd9Sstevel@tonic-gate * 907c478bd9Sstevel@tonic-gate * Effects: 917c478bd9Sstevel@tonic-gate * Writes the data to the database, and does a database sync if 9256a424ccSmp153739 * successful. 937c478bd9Sstevel@tonic-gate * 947c478bd9Sstevel@tonic-gate */ 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate kadm5_ret_t 977c478bd9Sstevel@tonic-gate kadm5_create_policy_internal(void *server_handle, 987c478bd9Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask) 997c478bd9Sstevel@tonic-gate { 1007c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle; 1017c478bd9Sstevel@tonic-gate osa_policy_ent_rec pent; 1027c478bd9Sstevel@tonic-gate int ret; 1037c478bd9Sstevel@tonic-gate char *p; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate if ((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL)) 1087c478bd9Sstevel@tonic-gate return EINVAL; 1097c478bd9Sstevel@tonic-gate if(strlen(entry->policy) == 0) 1107c478bd9Sstevel@tonic-gate return KADM5_BAD_POLICY; 1117c478bd9Sstevel@tonic-gate if (!(mask & KADM5_POLICY)) 1127c478bd9Sstevel@tonic-gate return KADM5_BAD_MASK; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate pent.name = entry->policy; 1157c478bd9Sstevel@tonic-gate p = entry->policy; 1167c478bd9Sstevel@tonic-gate while(*p != '\0') { 1177c478bd9Sstevel@tonic-gate if(*p < ' ' || *p > '~') 1187c478bd9Sstevel@tonic-gate return KADM5_BAD_POLICY; 1197c478bd9Sstevel@tonic-gate else 1207c478bd9Sstevel@tonic-gate p++; 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate if (!(mask & KADM5_PW_MAX_LIFE)) 1237c478bd9Sstevel@tonic-gate pent.pw_max_life = 0; 1247c478bd9Sstevel@tonic-gate else 1257c478bd9Sstevel@tonic-gate pent.pw_max_life = entry->pw_max_life; 1267c478bd9Sstevel@tonic-gate if (!(mask & KADM5_PW_MIN_LIFE)) 1277c478bd9Sstevel@tonic-gate pent.pw_min_life = 0; 1287c478bd9Sstevel@tonic-gate else { 1297c478bd9Sstevel@tonic-gate if((mask & KADM5_PW_MAX_LIFE)) { 1307c478bd9Sstevel@tonic-gate if(entry->pw_min_life > entry->pw_max_life && entry->pw_max_life != 0) 1317c478bd9Sstevel@tonic-gate return KADM5_BAD_MIN_PASS_LIFE; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate pent.pw_min_life = entry->pw_min_life; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate if (!(mask & KADM5_PW_MIN_LENGTH)) 1367c478bd9Sstevel@tonic-gate pent.pw_min_length = MIN_PW_LENGTH; 1377c478bd9Sstevel@tonic-gate else { 1387c478bd9Sstevel@tonic-gate if(entry->pw_min_length < MIN_PW_LENGTH) 1397c478bd9Sstevel@tonic-gate return KADM5_BAD_LENGTH; 1407c478bd9Sstevel@tonic-gate pent.pw_min_length = entry->pw_min_length; 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate if (!(mask & KADM5_PW_MIN_CLASSES)) 1437c478bd9Sstevel@tonic-gate pent.pw_min_classes = MIN_PW_CLASSES; 1447c478bd9Sstevel@tonic-gate else { 1457c478bd9Sstevel@tonic-gate if(entry->pw_min_classes > MAX_PW_CLASSES || entry->pw_min_classes < MIN_PW_CLASSES) 1467c478bd9Sstevel@tonic-gate return KADM5_BAD_CLASS; 1477c478bd9Sstevel@tonic-gate pent.pw_min_classes = entry->pw_min_classes; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate if (!(mask & KADM5_PW_HISTORY_NUM)) 1507c478bd9Sstevel@tonic-gate pent.pw_history_num = MIN_PW_HISTORY; 1517c478bd9Sstevel@tonic-gate else { 1527c478bd9Sstevel@tonic-gate if(entry->pw_history_num < MIN_PW_HISTORY || 1537c478bd9Sstevel@tonic-gate entry->pw_history_num > MAX_PW_HISTORY) 1547c478bd9Sstevel@tonic-gate return KADM5_BAD_HISTORY; 1557c478bd9Sstevel@tonic-gate else 1567c478bd9Sstevel@tonic-gate pent.pw_history_num = entry->pw_history_num; 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate if (!(mask & KADM5_REF_COUNT)) 1597c478bd9Sstevel@tonic-gate pent.policy_refcnt = 0; 1607c478bd9Sstevel@tonic-gate else 1617c478bd9Sstevel@tonic-gate pent.policy_refcnt = entry->policy_refcnt; 16254925bf6Swillf if ((ret = krb5_db_create_policy(handle->context, &pent))) 1637c478bd9Sstevel@tonic-gate return ret; 16454925bf6Swillf else 16554925bf6Swillf return KADM5_OK; 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate kadm5_ret_t 1697c478bd9Sstevel@tonic-gate kadm5_delete_policy(void *server_handle, kadm5_policy_t name) 1707c478bd9Sstevel@tonic-gate { 1717c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle; 1727c478bd9Sstevel@tonic-gate osa_policy_ent_t entry; 1737c478bd9Sstevel@tonic-gate int ret; 17454925bf6Swillf int cnt=1; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 1777c478bd9Sstevel@tonic-gate 17854925bf6Swillf krb5_clear_error_message(handle->context); 17954925bf6Swillf 1807c478bd9Sstevel@tonic-gate if(name == (kadm5_policy_t) NULL) 1817c478bd9Sstevel@tonic-gate return EINVAL; 1827c478bd9Sstevel@tonic-gate if(strlen(name) == 0) 1837c478bd9Sstevel@tonic-gate return KADM5_BAD_POLICY; 18454925bf6Swillf if((ret = krb5_db_get_policy(handle->context, name, &entry,&cnt))) 1857c478bd9Sstevel@tonic-gate return ret; 18654925bf6Swillf if( cnt != 1 ) 18754925bf6Swillf return KADM5_UNK_POLICY; 18854925bf6Swillf 1897c478bd9Sstevel@tonic-gate if(entry->policy_refcnt != 0) { 19054925bf6Swillf krb5_db_free_policy(handle->context, entry); 1917c478bd9Sstevel@tonic-gate return KADM5_POLICY_REF; 1927c478bd9Sstevel@tonic-gate } 19354925bf6Swillf krb5_db_free_policy(handle->context, entry); 19454925bf6Swillf if ((ret = krb5_db_delete_policy(handle->context, name))) 1957c478bd9Sstevel@tonic-gate return ret; 19654925bf6Swillf else 19754925bf6Swillf return KADM5_OK; 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate kadm5_ret_t 2017c478bd9Sstevel@tonic-gate kadm5_modify_policy(void *server_handle, 2027c478bd9Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask) 2037c478bd9Sstevel@tonic-gate { 2047c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 2057c478bd9Sstevel@tonic-gate 20654925bf6Swillf krb5_clear_error_message(((kadm5_server_handle_t)server_handle)->context); 20754925bf6Swillf 2087c478bd9Sstevel@tonic-gate if (mask & KADM5_REF_COUNT) 2097c478bd9Sstevel@tonic-gate return KADM5_BAD_MASK; 2107c478bd9Sstevel@tonic-gate else 2117c478bd9Sstevel@tonic-gate return kadm5_modify_policy_internal(server_handle, entry, mask); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate kadm5_ret_t 2157c478bd9Sstevel@tonic-gate kadm5_modify_policy_internal(void *server_handle, 2167c478bd9Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask) 2177c478bd9Sstevel@tonic-gate { 2187c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle; 2197c478bd9Sstevel@tonic-gate osa_policy_ent_t p; 2207c478bd9Sstevel@tonic-gate int ret; 22154925bf6Swillf int cnt=1; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate if((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL)) 2267c478bd9Sstevel@tonic-gate return EINVAL; 2277c478bd9Sstevel@tonic-gate if(strlen(entry->policy) == 0) 2287c478bd9Sstevel@tonic-gate return KADM5_BAD_POLICY; 2297c478bd9Sstevel@tonic-gate if((mask & KADM5_POLICY)) 2307c478bd9Sstevel@tonic-gate return KADM5_BAD_MASK; 2317c478bd9Sstevel@tonic-gate 23254925bf6Swillf if ((ret = krb5_db_get_policy(handle->context, entry->policy, &p, &cnt))) 23354925bf6Swillf return ret; 23454925bf6Swillf if (cnt != 1) 2357c478bd9Sstevel@tonic-gate return KADM5_UNK_POLICY; 23654925bf6Swillf 2377c478bd9Sstevel@tonic-gate if ((mask & KADM5_PW_MAX_LIFE)) 2387c478bd9Sstevel@tonic-gate p->pw_max_life = entry->pw_max_life; 2397c478bd9Sstevel@tonic-gate if ((mask & KADM5_PW_MIN_LIFE)) { 2407c478bd9Sstevel@tonic-gate if(entry->pw_min_life > p->pw_max_life && p->pw_max_life != 0) { 24154925bf6Swillf krb5_db_free_policy(handle->context, p); 2427c478bd9Sstevel@tonic-gate return KADM5_BAD_MIN_PASS_LIFE; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate p->pw_min_life = entry->pw_min_life; 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate if ((mask & KADM5_PW_MIN_LENGTH)) { 2477c478bd9Sstevel@tonic-gate if(entry->pw_min_length < MIN_PW_LENGTH) { 24854925bf6Swillf krb5_db_free_policy(handle->context, p); 2497c478bd9Sstevel@tonic-gate return KADM5_BAD_LENGTH; 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate p->pw_min_length = entry->pw_min_length; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate if ((mask & KADM5_PW_MIN_CLASSES)) { 2547c478bd9Sstevel@tonic-gate if(entry->pw_min_classes > MAX_PW_CLASSES || 2557c478bd9Sstevel@tonic-gate entry->pw_min_classes < MIN_PW_CLASSES) { 25654925bf6Swillf krb5_db_free_policy(handle->context, p); 2577c478bd9Sstevel@tonic-gate return KADM5_BAD_CLASS; 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate p->pw_min_classes = entry->pw_min_classes; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate if ((mask & KADM5_PW_HISTORY_NUM)) { 2627c478bd9Sstevel@tonic-gate if(entry->pw_history_num < MIN_PW_HISTORY || 2637c478bd9Sstevel@tonic-gate entry->pw_history_num > MAX_PW_HISTORY) { 26454925bf6Swillf krb5_db_free_policy(handle->context, p); 2657c478bd9Sstevel@tonic-gate return KADM5_BAD_HISTORY; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate p->pw_history_num = entry->pw_history_num; 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate if ((mask & KADM5_REF_COUNT)) 2707c478bd9Sstevel@tonic-gate p->policy_refcnt = entry->policy_refcnt; 27154925bf6Swillf ret = krb5_db_put_policy(handle->context, p); 27254925bf6Swillf krb5_db_free_policy(handle->context, p); 2737c478bd9Sstevel@tonic-gate return ret; 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate kadm5_ret_t 2777c478bd9Sstevel@tonic-gate kadm5_get_policy(void *server_handle, kadm5_policy_t name, 2787c478bd9Sstevel@tonic-gate kadm5_policy_ent_t entry) 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate osa_policy_ent_t t; 2817c478bd9Sstevel@tonic-gate kadm5_policy_ent_rec entry_local, **entry_orig, *new; 2827c478bd9Sstevel@tonic-gate int ret; 2837c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle; 28454925bf6Swillf int cnt=1; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 2877c478bd9Sstevel@tonic-gate 28854925bf6Swillf krb5_clear_error_message(handle->context); 28954925bf6Swillf 2907c478bd9Sstevel@tonic-gate /* 2917c478bd9Sstevel@tonic-gate * In version 1, entry is a pointer to a kadm5_policy_ent_t that 2927c478bd9Sstevel@tonic-gate * should be filled with allocated memory. 2937c478bd9Sstevel@tonic-gate */ 2947c478bd9Sstevel@tonic-gate if (handle->api_version == KADM5_API_VERSION_1) { 2957c478bd9Sstevel@tonic-gate entry_orig = (kadm5_policy_ent_rec **) entry; 2967c478bd9Sstevel@tonic-gate *entry_orig = NULL; 2977c478bd9Sstevel@tonic-gate entry = &entry_local; 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate if (name == (kadm5_policy_t) NULL) 3017c478bd9Sstevel@tonic-gate return EINVAL; 3027c478bd9Sstevel@tonic-gate if(strlen(name) == 0) 3037c478bd9Sstevel@tonic-gate return KADM5_BAD_POLICY; 30454925bf6Swillf if((ret = krb5_db_get_policy(handle->context, name, &t, &cnt))) 3057c478bd9Sstevel@tonic-gate return ret; 30654925bf6Swillf 30754925bf6Swillf if( cnt != 1 ) 30854925bf6Swillf return KADM5_UNK_POLICY; 30954925bf6Swillf 3107c478bd9Sstevel@tonic-gate if ((entry->policy = (char *) malloc(strlen(t->name) + 1)) == NULL) { 31154925bf6Swillf krb5_db_free_policy(handle->context, t); 3127c478bd9Sstevel@tonic-gate return ENOMEM; 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate strcpy(entry->policy, t->name); 3157c478bd9Sstevel@tonic-gate entry->pw_min_life = t->pw_min_life; 3167c478bd9Sstevel@tonic-gate entry->pw_max_life = t->pw_max_life; 3177c478bd9Sstevel@tonic-gate entry->pw_min_length = t->pw_min_length; 3187c478bd9Sstevel@tonic-gate entry->pw_min_classes = t->pw_min_classes; 3197c478bd9Sstevel@tonic-gate entry->pw_history_num = t->pw_history_num; 3207c478bd9Sstevel@tonic-gate entry->policy_refcnt = t->policy_refcnt; 32154925bf6Swillf krb5_db_free_policy(handle->context, t); 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate if (handle->api_version == KADM5_API_VERSION_1) { 3247c478bd9Sstevel@tonic-gate new = (kadm5_policy_ent_t) malloc(sizeof(kadm5_policy_ent_rec)); 3257c478bd9Sstevel@tonic-gate if (new == NULL) { 3267c478bd9Sstevel@tonic-gate free(entry->policy); 32754925bf6Swillf krb5_db_free_policy(handle->context, t); 3287c478bd9Sstevel@tonic-gate return ENOMEM; 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate *new = *entry; 3317c478bd9Sstevel@tonic-gate *entry_orig = new; 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate return KADM5_OK; 3357c478bd9Sstevel@tonic-gate } 336