xref: /onnv-gate/usr/src/lib/krb5/kadm5/srv/server_misc.c (revision 2881:ea6360e7e1c5)
10Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
20Sstevel@tonic-gate 
30Sstevel@tonic-gate /*
40Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
50Sstevel@tonic-gate  *
60Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
70Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
80Sstevel@tonic-gate  *	source code before consulting with your legal department.
90Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
100Sstevel@tonic-gate  *	product before consulting with your legal department.
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  *	For further information, read the top-level Openvision
130Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
140Sstevel@tonic-gate  *	copyright.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
170Sstevel@tonic-gate  *
180Sstevel@tonic-gate  */
190Sstevel@tonic-gate 
200Sstevel@tonic-gate 
210Sstevel@tonic-gate /*
220Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
230Sstevel@tonic-gate  *
24*2881Smp153739  * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_misc.c,v 1.4 2001/06/18 18:58:00 epeisach Exp $
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
28*2881Smp153739 static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_misc.c,v 1.4 2001/06/18 18:58:00 epeisach Exp $";
290Sstevel@tonic-gate #endif
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include    "k5-int.h"
320Sstevel@tonic-gate #include    <krb5/kdb.h>
330Sstevel@tonic-gate #include    <ctype.h>
340Sstevel@tonic-gate #include    "adb.h"
350Sstevel@tonic-gate #include    <pwd.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate /* for strcasecmp */
380Sstevel@tonic-gate #include    <string.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include    "server_internal.h"
410Sstevel@tonic-gate 
420Sstevel@tonic-gate kadm5_ret_t
430Sstevel@tonic-gate adb_policy_init(kadm5_server_handle_t handle)
440Sstevel@tonic-gate {
450Sstevel@tonic-gate     osa_adb_ret_t   ret;
460Sstevel@tonic-gate     if(handle->policy_db == (osa_adb_policy_t) NULL)
470Sstevel@tonic-gate 	if((ret = osa_adb_open_policy(&handle->policy_db,
480Sstevel@tonic-gate 				      &handle->params)) != OSA_ADB_OK)
490Sstevel@tonic-gate 	     return ret;
500Sstevel@tonic-gate     return KADM5_OK;
510Sstevel@tonic-gate }
520Sstevel@tonic-gate 
530Sstevel@tonic-gate kadm5_ret_t
540Sstevel@tonic-gate adb_policy_close(kadm5_server_handle_t handle)
550Sstevel@tonic-gate {
560Sstevel@tonic-gate     osa_adb_ret_t   ret;
570Sstevel@tonic-gate     if(handle->policy_db != (osa_adb_policy_t) NULL)
580Sstevel@tonic-gate 	if((ret = osa_adb_close_policy(handle->policy_db)) != OSA_ADB_OK)
590Sstevel@tonic-gate 	    return ret;
600Sstevel@tonic-gate     handle->policy_db = NULL;
610Sstevel@tonic-gate     return KADM5_OK;
620Sstevel@tonic-gate }
630Sstevel@tonic-gate 
64*2881Smp153739 #ifdef HESIOD
650Sstevel@tonic-gate /* stolen from v4sever/kadm_funcs.c */
660Sstevel@tonic-gate static char *
670Sstevel@tonic-gate reverse(str)
680Sstevel@tonic-gate 	char	*str;
690Sstevel@tonic-gate {
700Sstevel@tonic-gate 	static char newstr[80];
710Sstevel@tonic-gate 	char	*p, *q;
720Sstevel@tonic-gate 	int	i;
730Sstevel@tonic-gate 
740Sstevel@tonic-gate 	i = strlen(str);
750Sstevel@tonic-gate 	if (i >= sizeof(newstr))
760Sstevel@tonic-gate 		i = sizeof(newstr)-1;
770Sstevel@tonic-gate 	p = str+i-1;
780Sstevel@tonic-gate 	q = newstr;
790Sstevel@tonic-gate 	q[i]='\0';
800Sstevel@tonic-gate 	for(; i > 0; i--)
810Sstevel@tonic-gate 		*q++ = *p--;
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	return(newstr);
840Sstevel@tonic-gate }
85*2881Smp153739 #endif /* HESIOD */
860Sstevel@tonic-gate 
87*2881Smp153739 #if 0
880Sstevel@tonic-gate static int
890Sstevel@tonic-gate lower(str)
900Sstevel@tonic-gate 	char	*str;
910Sstevel@tonic-gate {
920Sstevel@tonic-gate 	register char	*cp;
930Sstevel@tonic-gate 	int	effect=0;
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	for (cp = str; *cp; cp++) {
960Sstevel@tonic-gate 		if (isupper(*cp)) {
970Sstevel@tonic-gate 			*cp = tolower(*cp);
980Sstevel@tonic-gate 			effect++;
990Sstevel@tonic-gate 		}
1000Sstevel@tonic-gate 	}
1010Sstevel@tonic-gate 	return(effect);
1020Sstevel@tonic-gate }
103*2881Smp153739 #endif
1040Sstevel@tonic-gate 
105*2881Smp153739 #ifdef HESIOD
1060Sstevel@tonic-gate static int
1070Sstevel@tonic-gate str_check_gecos(gecos, pwstr)
1080Sstevel@tonic-gate 	char	*gecos;
1090Sstevel@tonic-gate 	char	*pwstr;
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate 	char		*cp, *ncp, *tcp;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	for (cp = gecos; *cp; ) {
1140Sstevel@tonic-gate 		/* Skip past punctuation */
1150Sstevel@tonic-gate 		for (; *cp; cp++)
1160Sstevel@tonic-gate 			if (isalnum(*cp))
1170Sstevel@tonic-gate 				break;
1180Sstevel@tonic-gate 		/* Skip to the end of the word */
1190Sstevel@tonic-gate 		for (ncp = cp; *ncp; ncp++)
1200Sstevel@tonic-gate 			if (!isalnum(*ncp) && *ncp != '\'')
1210Sstevel@tonic-gate 				break;
1220Sstevel@tonic-gate 		/* Delimit end of word */
1230Sstevel@tonic-gate 		if (*ncp)
1240Sstevel@tonic-gate 			*ncp++ = '\0';
1250Sstevel@tonic-gate 		/* Check word to see if it's the password */
1260Sstevel@tonic-gate 		if (*cp) {
1270Sstevel@tonic-gate 			if (!strcasecmp(pwstr, cp))
1280Sstevel@tonic-gate 				return 1;
1290Sstevel@tonic-gate 			tcp = reverse(cp);
1300Sstevel@tonic-gate 			if (!strcasecmp(pwstr, tcp))
1310Sstevel@tonic-gate 				return 1;
1320Sstevel@tonic-gate 			cp = ncp;
1330Sstevel@tonic-gate 		} else
1340Sstevel@tonic-gate 			break;
1350Sstevel@tonic-gate 	}
1360Sstevel@tonic-gate 	return 0;
1370Sstevel@tonic-gate }
138*2881Smp153739 #endif /* HESIOD */
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate /* some of this is stolen from gatekeeper ... */
1410Sstevel@tonic-gate kadm5_ret_t
1420Sstevel@tonic-gate passwd_check(kadm5_server_handle_t handle,
1430Sstevel@tonic-gate 	     char *password, int use_policy, kadm5_policy_ent_t pol,
1440Sstevel@tonic-gate 	     krb5_principal principal)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate     int	    nupper = 0,
1470Sstevel@tonic-gate 	    nlower = 0,
1480Sstevel@tonic-gate 	    ndigit = 0,
1490Sstevel@tonic-gate 	    npunct = 0,
1500Sstevel@tonic-gate 	    nspec = 0;
1510Sstevel@tonic-gate     char    c, *s, *cp;
1520Sstevel@tonic-gate #ifdef HESIOD
1530Sstevel@tonic-gate     extern  struct passwd *hes_getpwnam();
1540Sstevel@tonic-gate     struct  passwd *ent;
1550Sstevel@tonic-gate #endif
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate     if(use_policy) {
1580Sstevel@tonic-gate 	if(strlen(password) < pol->pw_min_length)
1590Sstevel@tonic-gate 	    return KADM5_PASS_Q_TOOSHORT;
1600Sstevel@tonic-gate 	s = password;
1610Sstevel@tonic-gate 	while ((c = *s++)) {
162*2881Smp153739 	    if (islower((int) c)) {
1630Sstevel@tonic-gate 		nlower = 1;
1640Sstevel@tonic-gate 		continue;
1650Sstevel@tonic-gate 	    }
166*2881Smp153739 	    else if (isupper((int) c)) {
1670Sstevel@tonic-gate 		nupper = 1;
1680Sstevel@tonic-gate 		continue;
169*2881Smp153739 	    } else if (isdigit((int) c)) {
1700Sstevel@tonic-gate 		ndigit = 1;
1710Sstevel@tonic-gate 		continue;
172*2881Smp153739 	    } else if (ispunct((int) c)) {
1730Sstevel@tonic-gate 		npunct = 1;
1740Sstevel@tonic-gate 		continue;
1750Sstevel@tonic-gate 	    } else {
1760Sstevel@tonic-gate 		nspec = 1;
1770Sstevel@tonic-gate 		continue;
1780Sstevel@tonic-gate 	    }
1790Sstevel@tonic-gate 	}
1800Sstevel@tonic-gate 	if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
1810Sstevel@tonic-gate 	    return KADM5_PASS_Q_CLASS;
1820Sstevel@tonic-gate 	if((find_word(password) == KADM5_OK))
1830Sstevel@tonic-gate 	    return KADM5_PASS_Q_DICT;
1840Sstevel@tonic-gate 	else {
185*2881Smp153739 	    int	i, n = krb5_princ_size(handle->context, principal);
1860Sstevel@tonic-gate 	    cp = krb5_princ_realm(handle->context, principal)->data;
1870Sstevel@tonic-gate 	    if (strcasecmp(cp, password) == 0)
1880Sstevel@tonic-gate 		return KADM5_PASS_Q_DICT;
189*2881Smp153739 	    for (i = 0; i < n ; i++) {
190*2881Smp153739 		cp = krb5_princ_component(handle->context, principal, i)->data;
1910Sstevel@tonic-gate 		if (strcasecmp(cp, password) == 0)
1920Sstevel@tonic-gate 		    return KADM5_PASS_Q_DICT;
1930Sstevel@tonic-gate #ifdef HESIOD
1940Sstevel@tonic-gate 		ent = hes_getpwnam(cp);
1950Sstevel@tonic-gate 		if (ent && ent->pw_gecos)
1960Sstevel@tonic-gate 		    if (str_check_gecos(ent->pw_gecos, password))
1970Sstevel@tonic-gate 			return KADM5_PASS_Q_DICT; /* XXX new error code? */
1980Sstevel@tonic-gate #endif
1990Sstevel@tonic-gate 	    }
2000Sstevel@tonic-gate 	    return KADM5_OK;
2010Sstevel@tonic-gate 	}
2020Sstevel@tonic-gate     } else {
2030Sstevel@tonic-gate 	if (strlen(password) < 1)
2040Sstevel@tonic-gate 	    return KADM5_PASS_Q_TOOSHORT;
2050Sstevel@tonic-gate     }
2060Sstevel@tonic-gate     return KADM5_OK;
2070Sstevel@tonic-gate }
208