xref: /onnv-gate/usr/src/lib/krb5/kadm5/srv/svr_policy.c (revision 7934:6aeeafc994de)
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