10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * Openvision retains the copyright to derivative works of
50Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this
60Sstevel@tonic-gate * source code before consulting with your legal department.
70Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another
80Sstevel@tonic-gate * product before consulting with your legal department.
90Sstevel@tonic-gate *
100Sstevel@tonic-gate * For further information, read the top-level Openvision
110Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos
120Sstevel@tonic-gate * copyright.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
150Sstevel@tonic-gate *
160Sstevel@tonic-gate */
170Sstevel@tonic-gate
180Sstevel@tonic-gate
190Sstevel@tonic-gate /*
200Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
210Sstevel@tonic-gate *
22*7934SMark.Phalan@Sun.COM * $Header$
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
26*7934SMark.Phalan@Sun.COM static char *rcsid = "$Header$";
270Sstevel@tonic-gate #endif
280Sstevel@tonic-gate
29*7934SMark.Phalan@Sun.COM #include "server_internal.h"
300Sstevel@tonic-gate #include <sys/types.h>
310Sstevel@tonic-gate #include <kadm5/admin.h>
320Sstevel@tonic-gate #include <stdlib.h>
33*7934SMark.Phalan@Sun.COM #include <errno.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate #define MAX_PW_HISTORY 10
360Sstevel@tonic-gate #define MIN_PW_HISTORY 1
370Sstevel@tonic-gate #define MIN_PW_CLASSES 1
380Sstevel@tonic-gate #define MAX_PW_CLASSES 5
390Sstevel@tonic-gate #define MIN_PW_LENGTH 1
400Sstevel@tonic-gate
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate * Function: kadm5_create_policy
430Sstevel@tonic-gate *
440Sstevel@tonic-gate * Purpose: Create Policies in the policy DB.
450Sstevel@tonic-gate *
460Sstevel@tonic-gate * Arguments:
470Sstevel@tonic-gate * entry (input) The policy entry to be written out to the DB.
480Sstevel@tonic-gate * mask (input) Specifies which fields in entry are to ge written out
490Sstevel@tonic-gate * and which get default values.
502881Smp153739 * <return value> 0 if successful otherwise an error code is returned.
510Sstevel@tonic-gate *
520Sstevel@tonic-gate * Requires:
530Sstevel@tonic-gate * Entry must be a valid principal entry, and mask have a valid value.
540Sstevel@tonic-gate *
550Sstevel@tonic-gate * Effects:
560Sstevel@tonic-gate * Verifies that mask does not specify that the refcount should
570Sstevel@tonic-gate * be set as part of the creation, and calls
580Sstevel@tonic-gate * kadm5_create_policy_internal. If the refcount *is*
590Sstevel@tonic-gate * specified, returns KADM5_BAD_MASK.
600Sstevel@tonic-gate */
610Sstevel@tonic-gate
620Sstevel@tonic-gate kadm5_ret_t
kadm5_create_policy(void * server_handle,kadm5_policy_ent_t entry,long mask)630Sstevel@tonic-gate kadm5_create_policy(void *server_handle,
640Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask)
650Sstevel@tonic-gate {
660Sstevel@tonic-gate CHECK_HANDLE(server_handle);
670Sstevel@tonic-gate
684960Swillf krb5_clear_error_message(((kadm5_server_handle_t)server_handle)->context);
694960Swillf
700Sstevel@tonic-gate if (mask & KADM5_REF_COUNT)
710Sstevel@tonic-gate return KADM5_BAD_MASK;
720Sstevel@tonic-gate else
730Sstevel@tonic-gate return kadm5_create_policy_internal(server_handle, entry, mask);
740Sstevel@tonic-gate }
750Sstevel@tonic-gate
760Sstevel@tonic-gate /*
770Sstevel@tonic-gate * Function: kadm5_create_policy_internal
780Sstevel@tonic-gate *
790Sstevel@tonic-gate * Purpose: Create Policies in the policy DB.
800Sstevel@tonic-gate *
810Sstevel@tonic-gate * Arguments:
820Sstevel@tonic-gate * entry (input) The policy entry to be written out to the DB.
830Sstevel@tonic-gate * mask (input) Specifies which fields in entry are to ge written out
840Sstevel@tonic-gate * and which get default values.
852881Smp153739 * <return value> 0 if successful otherwise an error code is returned.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * Requires:
880Sstevel@tonic-gate * Entry must be a valid principal entry, and mask have a valid value.
890Sstevel@tonic-gate *
900Sstevel@tonic-gate * Effects:
910Sstevel@tonic-gate * Writes the data to the database, and does a database sync if
922881Smp153739 * successful.
930Sstevel@tonic-gate *
940Sstevel@tonic-gate */
950Sstevel@tonic-gate
960Sstevel@tonic-gate kadm5_ret_t
kadm5_create_policy_internal(void * server_handle,kadm5_policy_ent_t entry,long mask)970Sstevel@tonic-gate kadm5_create_policy_internal(void *server_handle,
980Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask)
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle;
1010Sstevel@tonic-gate osa_policy_ent_rec pent;
1020Sstevel@tonic-gate int ret;
1030Sstevel@tonic-gate char *p;
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate CHECK_HANDLE(server_handle);
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate if ((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
1080Sstevel@tonic-gate return EINVAL;
1090Sstevel@tonic-gate if(strlen(entry->policy) == 0)
1100Sstevel@tonic-gate return KADM5_BAD_POLICY;
1110Sstevel@tonic-gate if (!(mask & KADM5_POLICY))
1120Sstevel@tonic-gate return KADM5_BAD_MASK;
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate pent.name = entry->policy;
1150Sstevel@tonic-gate p = entry->policy;
1160Sstevel@tonic-gate while(*p != '\0') {
1170Sstevel@tonic-gate if(*p < ' ' || *p > '~')
1180Sstevel@tonic-gate return KADM5_BAD_POLICY;
1190Sstevel@tonic-gate else
1200Sstevel@tonic-gate p++;
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate if (!(mask & KADM5_PW_MAX_LIFE))
1230Sstevel@tonic-gate pent.pw_max_life = 0;
1240Sstevel@tonic-gate else
1250Sstevel@tonic-gate pent.pw_max_life = entry->pw_max_life;
1260Sstevel@tonic-gate if (!(mask & KADM5_PW_MIN_LIFE))
1270Sstevel@tonic-gate pent.pw_min_life = 0;
1280Sstevel@tonic-gate else {
1290Sstevel@tonic-gate if((mask & KADM5_PW_MAX_LIFE)) {
1300Sstevel@tonic-gate if(entry->pw_min_life > entry->pw_max_life && entry->pw_max_life != 0)
1310Sstevel@tonic-gate return KADM5_BAD_MIN_PASS_LIFE;
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate pent.pw_min_life = entry->pw_min_life;
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate if (!(mask & KADM5_PW_MIN_LENGTH))
1360Sstevel@tonic-gate pent.pw_min_length = MIN_PW_LENGTH;
1370Sstevel@tonic-gate else {
1380Sstevel@tonic-gate if(entry->pw_min_length < MIN_PW_LENGTH)
1390Sstevel@tonic-gate return KADM5_BAD_LENGTH;
1400Sstevel@tonic-gate pent.pw_min_length = entry->pw_min_length;
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate if (!(mask & KADM5_PW_MIN_CLASSES))
1430Sstevel@tonic-gate pent.pw_min_classes = MIN_PW_CLASSES;
1440Sstevel@tonic-gate else {
1450Sstevel@tonic-gate if(entry->pw_min_classes > MAX_PW_CLASSES || entry->pw_min_classes < MIN_PW_CLASSES)
1460Sstevel@tonic-gate return KADM5_BAD_CLASS;
1470Sstevel@tonic-gate pent.pw_min_classes = entry->pw_min_classes;
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate if (!(mask & KADM5_PW_HISTORY_NUM))
1500Sstevel@tonic-gate pent.pw_history_num = MIN_PW_HISTORY;
1510Sstevel@tonic-gate else {
1520Sstevel@tonic-gate if(entry->pw_history_num < MIN_PW_HISTORY ||
1530Sstevel@tonic-gate entry->pw_history_num > MAX_PW_HISTORY)
1540Sstevel@tonic-gate return KADM5_BAD_HISTORY;
1550Sstevel@tonic-gate else
1560Sstevel@tonic-gate pent.pw_history_num = entry->pw_history_num;
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate if (!(mask & KADM5_REF_COUNT))
1590Sstevel@tonic-gate pent.policy_refcnt = 0;
1600Sstevel@tonic-gate else
1610Sstevel@tonic-gate pent.policy_refcnt = entry->policy_refcnt;
1624960Swillf if ((ret = krb5_db_create_policy(handle->context, &pent)))
1634960Swillf return ret;
1644960Swillf else
1650Sstevel@tonic-gate return KADM5_OK;
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate kadm5_ret_t
kadm5_delete_policy(void * server_handle,kadm5_policy_t name)1690Sstevel@tonic-gate kadm5_delete_policy(void *server_handle, kadm5_policy_t name)
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle;
1720Sstevel@tonic-gate osa_policy_ent_t entry;
1730Sstevel@tonic-gate int ret;
1744960Swillf int cnt=1;
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate CHECK_HANDLE(server_handle);
1770Sstevel@tonic-gate
1784960Swillf krb5_clear_error_message(handle->context);
1794960Swillf
1800Sstevel@tonic-gate if(name == (kadm5_policy_t) NULL)
1810Sstevel@tonic-gate return EINVAL;
1820Sstevel@tonic-gate if(strlen(name) == 0)
1830Sstevel@tonic-gate return KADM5_BAD_POLICY;
184*7934SMark.Phalan@Sun.COM if((ret = krb5_db_get_policy(handle->context, name, &entry,&cnt)))
1850Sstevel@tonic-gate return ret;
1864960Swillf if( cnt != 1 )
1874960Swillf return KADM5_UNK_POLICY;
1884960Swillf
1890Sstevel@tonic-gate if(entry->policy_refcnt != 0) {
1904960Swillf krb5_db_free_policy(handle->context, entry);
1910Sstevel@tonic-gate return KADM5_POLICY_REF;
1920Sstevel@tonic-gate }
1934960Swillf krb5_db_free_policy(handle->context, entry);
1944960Swillf if ((ret = krb5_db_delete_policy(handle->context, name)))
1954960Swillf return ret;
1964960Swillf else
1970Sstevel@tonic-gate return KADM5_OK;
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate kadm5_ret_t
kadm5_modify_policy(void * server_handle,kadm5_policy_ent_t entry,long mask)2010Sstevel@tonic-gate kadm5_modify_policy(void *server_handle,
2020Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask)
2030Sstevel@tonic-gate {
2040Sstevel@tonic-gate CHECK_HANDLE(server_handle);
2050Sstevel@tonic-gate
2064960Swillf krb5_clear_error_message(((kadm5_server_handle_t)server_handle)->context);
2074960Swillf
2080Sstevel@tonic-gate if (mask & KADM5_REF_COUNT)
2090Sstevel@tonic-gate return KADM5_BAD_MASK;
2100Sstevel@tonic-gate else
2110Sstevel@tonic-gate return kadm5_modify_policy_internal(server_handle, entry, mask);
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate kadm5_ret_t
kadm5_modify_policy_internal(void * server_handle,kadm5_policy_ent_t entry,long mask)2150Sstevel@tonic-gate kadm5_modify_policy_internal(void *server_handle,
2160Sstevel@tonic-gate kadm5_policy_ent_t entry, long mask)
2170Sstevel@tonic-gate {
2180Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle;
2190Sstevel@tonic-gate osa_policy_ent_t p;
2200Sstevel@tonic-gate int ret;
2214960Swillf int cnt=1;
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate CHECK_HANDLE(server_handle);
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate if((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
2260Sstevel@tonic-gate return EINVAL;
2270Sstevel@tonic-gate if(strlen(entry->policy) == 0)
2280Sstevel@tonic-gate return KADM5_BAD_POLICY;
2290Sstevel@tonic-gate if((mask & KADM5_POLICY))
2300Sstevel@tonic-gate return KADM5_BAD_MASK;
2310Sstevel@tonic-gate
232*7934SMark.Phalan@Sun.COM if ((ret = krb5_db_get_policy(handle->context, entry->policy, &p, &cnt)))
2334960Swillf return ret;
234*7934SMark.Phalan@Sun.COM if (cnt != 1)
2350Sstevel@tonic-gate return KADM5_UNK_POLICY;
2364960Swillf
2370Sstevel@tonic-gate if ((mask & KADM5_PW_MAX_LIFE))
2380Sstevel@tonic-gate p->pw_max_life = entry->pw_max_life;
2390Sstevel@tonic-gate if ((mask & KADM5_PW_MIN_LIFE)) {
2400Sstevel@tonic-gate if(entry->pw_min_life > p->pw_max_life && p->pw_max_life != 0) {
2414960Swillf krb5_db_free_policy(handle->context, p);
2420Sstevel@tonic-gate return KADM5_BAD_MIN_PASS_LIFE;
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate p->pw_min_life = entry->pw_min_life;
2450Sstevel@tonic-gate }
2460Sstevel@tonic-gate if ((mask & KADM5_PW_MIN_LENGTH)) {
2470Sstevel@tonic-gate if(entry->pw_min_length < MIN_PW_LENGTH) {
2484960Swillf krb5_db_free_policy(handle->context, p);
2490Sstevel@tonic-gate return KADM5_BAD_LENGTH;
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate p->pw_min_length = entry->pw_min_length;
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate if ((mask & KADM5_PW_MIN_CLASSES)) {
2540Sstevel@tonic-gate if(entry->pw_min_classes > MAX_PW_CLASSES ||
2550Sstevel@tonic-gate entry->pw_min_classes < MIN_PW_CLASSES) {
2564960Swillf krb5_db_free_policy(handle->context, p);
2570Sstevel@tonic-gate return KADM5_BAD_CLASS;
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate p->pw_min_classes = entry->pw_min_classes;
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate if ((mask & KADM5_PW_HISTORY_NUM)) {
2620Sstevel@tonic-gate if(entry->pw_history_num < MIN_PW_HISTORY ||
2630Sstevel@tonic-gate entry->pw_history_num > MAX_PW_HISTORY) {
2644960Swillf krb5_db_free_policy(handle->context, p);
2650Sstevel@tonic-gate return KADM5_BAD_HISTORY;
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate p->pw_history_num = entry->pw_history_num;
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate if ((mask & KADM5_REF_COUNT))
2700Sstevel@tonic-gate p->policy_refcnt = entry->policy_refcnt;
2714960Swillf ret = krb5_db_put_policy(handle->context, p);
2724960Swillf krb5_db_free_policy(handle->context, p);
2730Sstevel@tonic-gate return ret;
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate kadm5_ret_t
kadm5_get_policy(void * server_handle,kadm5_policy_t name,kadm5_policy_ent_t entry)2770Sstevel@tonic-gate kadm5_get_policy(void *server_handle, kadm5_policy_t name,
2780Sstevel@tonic-gate kadm5_policy_ent_t entry)
2790Sstevel@tonic-gate {
2800Sstevel@tonic-gate osa_policy_ent_t t;
2810Sstevel@tonic-gate kadm5_policy_ent_rec entry_local, **entry_orig, *new;
2820Sstevel@tonic-gate int ret;
2830Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle;
2844960Swillf int cnt=1;
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate CHECK_HANDLE(server_handle);
2870Sstevel@tonic-gate
2884960Swillf krb5_clear_error_message(handle->context);
2894960Swillf
2900Sstevel@tonic-gate /*
2910Sstevel@tonic-gate * In version 1, entry is a pointer to a kadm5_policy_ent_t that
2920Sstevel@tonic-gate * should be filled with allocated memory.
2930Sstevel@tonic-gate */
2940Sstevel@tonic-gate if (handle->api_version == KADM5_API_VERSION_1) {
2950Sstevel@tonic-gate entry_orig = (kadm5_policy_ent_rec **) entry;
2960Sstevel@tonic-gate *entry_orig = NULL;
2970Sstevel@tonic-gate entry = &entry_local;
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate if (name == (kadm5_policy_t) NULL)
3010Sstevel@tonic-gate return EINVAL;
3020Sstevel@tonic-gate if(strlen(name) == 0)
3030Sstevel@tonic-gate return KADM5_BAD_POLICY;
3044960Swillf if((ret = krb5_db_get_policy(handle->context, name, &t, &cnt)))
3054960Swillf return ret;
3064960Swillf
3074960Swillf if( cnt != 1 )
3080Sstevel@tonic-gate return KADM5_UNK_POLICY;
3094960Swillf
3100Sstevel@tonic-gate if ((entry->policy = (char *) malloc(strlen(t->name) + 1)) == NULL) {
3114960Swillf krb5_db_free_policy(handle->context, t);
3120Sstevel@tonic-gate return ENOMEM;
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate strcpy(entry->policy, t->name);
3150Sstevel@tonic-gate entry->pw_min_life = t->pw_min_life;
3160Sstevel@tonic-gate entry->pw_max_life = t->pw_max_life;
3170Sstevel@tonic-gate entry->pw_min_length = t->pw_min_length;
3180Sstevel@tonic-gate entry->pw_min_classes = t->pw_min_classes;
3190Sstevel@tonic-gate entry->pw_history_num = t->pw_history_num;
3200Sstevel@tonic-gate entry->policy_refcnt = t->policy_refcnt;
3214960Swillf krb5_db_free_policy(handle->context, t);
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate if (handle->api_version == KADM5_API_VERSION_1) {
3240Sstevel@tonic-gate new = (kadm5_policy_ent_t) malloc(sizeof(kadm5_policy_ent_rec));
3250Sstevel@tonic-gate if (new == NULL) {
3260Sstevel@tonic-gate free(entry->policy);
3274960Swillf krb5_db_free_policy(handle->context, t);
3280Sstevel@tonic-gate return ENOMEM;
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate *new = *entry;
3310Sstevel@tonic-gate *entry_orig = new;
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate return KADM5_OK;
3350Sstevel@tonic-gate }
336