17c478bd9Sstevel@tonic-gate 
27c478bd9Sstevel@tonic-gate /*
3*55fea89dSDan Cross  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
67c478bd9Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
77c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
87c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
97c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
127c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
137c478bd9Sstevel@tonic-gate  *	copyright.
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
167c478bd9Sstevel@tonic-gate  *
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /*
217c478bd9Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
227c478bd9Sstevel@tonic-gate  *
23159d09a2SMark Phalan  * $Header$
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
27159d09a2SMark Phalan static char *rcsid = "$Header$";
287c478bd9Sstevel@tonic-gate #endif
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include    "k5-int.h"
317c478bd9Sstevel@tonic-gate #include    <krb5/kdb.h>
327c478bd9Sstevel@tonic-gate #include    <ctype.h>
337c478bd9Sstevel@tonic-gate #include    <pwd.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate /* for strcasecmp */
367c478bd9Sstevel@tonic-gate #include    <string.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include    "server_internal.h"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate kadm5_ret_t
adb_policy_init(kadm5_server_handle_t handle)417c478bd9Sstevel@tonic-gate adb_policy_init(kadm5_server_handle_t handle)
427c478bd9Sstevel@tonic-gate {
4354925bf6Swillf     /* now policy is initialized as part of database. No seperate call needed */
4478894ffcSmp     /* Solaris Kerberos: krb5_db_inited returns 0 when db has been inited */
4578894ffcSmp     if( krb5_db_inited( handle->context ) == 0 )
4654925bf6Swillf 	return KADM5_OK;
4754925bf6Swillf 
48*55fea89dSDan Cross     return krb5_db_open( handle->context, NULL,
4954925bf6Swillf 			 KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN );
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate kadm5_ret_t
adb_policy_close(kadm5_server_handle_t handle)537c478bd9Sstevel@tonic-gate adb_policy_close(kadm5_server_handle_t handle)
547c478bd9Sstevel@tonic-gate {
5554925bf6Swillf     /* will be taken care by database close */
567c478bd9Sstevel@tonic-gate     return KADM5_OK;
577c478bd9Sstevel@tonic-gate }
587c478bd9Sstevel@tonic-gate 
5956a424ccSmp #ifdef HESIOD
607c478bd9Sstevel@tonic-gate /* stolen from v4sever/kadm_funcs.c */
617c478bd9Sstevel@tonic-gate static char *
reverse(str)627c478bd9Sstevel@tonic-gate reverse(str)
637c478bd9Sstevel@tonic-gate 	char	*str;
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate 	static char newstr[80];
667c478bd9Sstevel@tonic-gate 	char	*p, *q;
677c478bd9Sstevel@tonic-gate 	int	i;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 	i = strlen(str);
707c478bd9Sstevel@tonic-gate 	if (i >= sizeof(newstr))
717c478bd9Sstevel@tonic-gate 		i = sizeof(newstr)-1;
727c478bd9Sstevel@tonic-gate 	p = str+i-1;
737c478bd9Sstevel@tonic-gate 	q = newstr;
747c478bd9Sstevel@tonic-gate 	q[i]='\0';
75*55fea89dSDan Cross 	for(; i > 0; i--)
767c478bd9Sstevel@tonic-gate 		*q++ = *p--;
77*55fea89dSDan Cross 
787c478bd9Sstevel@tonic-gate 	return(newstr);
797c478bd9Sstevel@tonic-gate }
8056a424ccSmp #endif /* HESIOD */
817c478bd9Sstevel@tonic-gate 
8256a424ccSmp #if 0
837c478bd9Sstevel@tonic-gate static int
847c478bd9Sstevel@tonic-gate lower(str)
857c478bd9Sstevel@tonic-gate 	char	*str;
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 	register char	*cp;
887c478bd9Sstevel@tonic-gate 	int	effect=0;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	for (cp = str; *cp; cp++) {
917c478bd9Sstevel@tonic-gate 		if (isupper(*cp)) {
927c478bd9Sstevel@tonic-gate 			*cp = tolower(*cp);
937c478bd9Sstevel@tonic-gate 			effect++;
947c478bd9Sstevel@tonic-gate 		}
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 	return(effect);
977c478bd9Sstevel@tonic-gate }
9856a424ccSmp #endif
997c478bd9Sstevel@tonic-gate 
10056a424ccSmp #ifdef HESIOD
1017c478bd9Sstevel@tonic-gate static int
str_check_gecos(gecos,pwstr)1027c478bd9Sstevel@tonic-gate str_check_gecos(gecos, pwstr)
1037c478bd9Sstevel@tonic-gate 	char	*gecos;
1047c478bd9Sstevel@tonic-gate 	char	*pwstr;
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	char		*cp, *ncp, *tcp;
107*55fea89dSDan Cross 
1087c478bd9Sstevel@tonic-gate 	for (cp = gecos; *cp; ) {
1097c478bd9Sstevel@tonic-gate 		/* Skip past punctuation */
1107c478bd9Sstevel@tonic-gate 		for (; *cp; cp++)
1117c478bd9Sstevel@tonic-gate 			if (isalnum(*cp))
1127c478bd9Sstevel@tonic-gate 				break;
1137c478bd9Sstevel@tonic-gate 		/* Skip to the end of the word */
1147c478bd9Sstevel@tonic-gate 		for (ncp = cp; *ncp; ncp++)
1157c478bd9Sstevel@tonic-gate 			if (!isalnum(*ncp) && *ncp != '\'')
1167c478bd9Sstevel@tonic-gate 				break;
1177c478bd9Sstevel@tonic-gate 		/* Delimit end of word */
1187c478bd9Sstevel@tonic-gate 		if (*ncp)
1197c478bd9Sstevel@tonic-gate 			*ncp++ = '\0';
1207c478bd9Sstevel@tonic-gate 		/* Check word to see if it's the password */
1217c478bd9Sstevel@tonic-gate 		if (*cp) {
1227c478bd9Sstevel@tonic-gate 			if (!strcasecmp(pwstr, cp))
1237c478bd9Sstevel@tonic-gate 				return 1;
1247c478bd9Sstevel@tonic-gate 			tcp = reverse(cp);
1257c478bd9Sstevel@tonic-gate 			if (!strcasecmp(pwstr, tcp))
1267c478bd9Sstevel@tonic-gate 				return 1;
127*55fea89dSDan Cross 			cp = ncp;
1287c478bd9Sstevel@tonic-gate 		} else
1297c478bd9Sstevel@tonic-gate 			break;
1307c478bd9Sstevel@tonic-gate 	}
1317c478bd9Sstevel@tonic-gate 	return 0;
1327c478bd9Sstevel@tonic-gate }
13356a424ccSmp #endif /* HESIOD */
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /* some of this is stolen from gatekeeper ... */
1367c478bd9Sstevel@tonic-gate kadm5_ret_t
passwd_check(kadm5_server_handle_t handle,char * password,int use_policy,kadm5_policy_ent_t pol,krb5_principal principal)1377c478bd9Sstevel@tonic-gate passwd_check(kadm5_server_handle_t handle,
1387c478bd9Sstevel@tonic-gate 	     char *password, int use_policy, kadm5_policy_ent_t pol,
1397c478bd9Sstevel@tonic-gate 	     krb5_principal principal)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate     int	    nupper = 0,
1427c478bd9Sstevel@tonic-gate 	    nlower = 0,
143*55fea89dSDan Cross 	    ndigit = 0,
1447c478bd9Sstevel@tonic-gate 	    npunct = 0,
1457c478bd9Sstevel@tonic-gate 	    nspec = 0;
1467c478bd9Sstevel@tonic-gate     char    c, *s, *cp;
1477c478bd9Sstevel@tonic-gate #ifdef HESIOD
1487c478bd9Sstevel@tonic-gate     extern  struct passwd *hes_getpwnam();
1497c478bd9Sstevel@tonic-gate     struct  passwd *ent;
1507c478bd9Sstevel@tonic-gate #endif
151*55fea89dSDan Cross 
1527c478bd9Sstevel@tonic-gate     if(use_policy) {
1537c478bd9Sstevel@tonic-gate 	if(strlen(password) < pol->pw_min_length)
1547c478bd9Sstevel@tonic-gate 	    return KADM5_PASS_Q_TOOSHORT;
1557c478bd9Sstevel@tonic-gate 	s = password;
1567c478bd9Sstevel@tonic-gate 	while ((c = *s++)) {
15754925bf6Swillf 	    if (islower((unsigned char) c)) {
1587c478bd9Sstevel@tonic-gate 		nlower = 1;
1597c478bd9Sstevel@tonic-gate 		continue;
1607c478bd9Sstevel@tonic-gate 	    }
16154925bf6Swillf 	    else if (isupper((unsigned char) c)) {
1627c478bd9Sstevel@tonic-gate 		nupper = 1;
1637c478bd9Sstevel@tonic-gate 		continue;
16454925bf6Swillf 	    } else if (isdigit((unsigned char) c)) {
1657c478bd9Sstevel@tonic-gate 		ndigit = 1;
1667c478bd9Sstevel@tonic-gate 		continue;
16754925bf6Swillf 	    } else if (ispunct((unsigned char) c)) {
1687c478bd9Sstevel@tonic-gate 		npunct = 1;
1697c478bd9Sstevel@tonic-gate 		continue;
1707c478bd9Sstevel@tonic-gate 	    } else {
1717c478bd9Sstevel@tonic-gate 		nspec = 1;
1727c478bd9Sstevel@tonic-gate 		continue;
1737c478bd9Sstevel@tonic-gate 	    }
1747c478bd9Sstevel@tonic-gate 	}
175*55fea89dSDan Cross 	if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
1767c478bd9Sstevel@tonic-gate 	    return KADM5_PASS_Q_CLASS;
1777c478bd9Sstevel@tonic-gate 	if((find_word(password) == KADM5_OK))
1787c478bd9Sstevel@tonic-gate 	    return KADM5_PASS_Q_DICT;
179*55fea89dSDan Cross 	else {
18056a424ccSmp 	    int	i, n = krb5_princ_size(handle->context, principal);
1817c478bd9Sstevel@tonic-gate 	    cp = krb5_princ_realm(handle->context, principal)->data;
1827c478bd9Sstevel@tonic-gate 	    if (strcasecmp(cp, password) == 0)
1837c478bd9Sstevel@tonic-gate 		return KADM5_PASS_Q_DICT;
18456a424ccSmp 	    for (i = 0; i < n ; i++) {
18556a424ccSmp 		cp = krb5_princ_component(handle->context, principal, i)->data;
1867c478bd9Sstevel@tonic-gate 		if (strcasecmp(cp, password) == 0)
1877c478bd9Sstevel@tonic-gate 		    return KADM5_PASS_Q_DICT;
1887c478bd9Sstevel@tonic-gate #ifdef HESIOD
1897c478bd9Sstevel@tonic-gate 		ent = hes_getpwnam(cp);
1907c478bd9Sstevel@tonic-gate 		if (ent && ent->pw_gecos)
1917c478bd9Sstevel@tonic-gate 		    if (str_check_gecos(ent->pw_gecos, password))
1927c478bd9Sstevel@tonic-gate 			return KADM5_PASS_Q_DICT; /* XXX new error code? */
1937c478bd9Sstevel@tonic-gate #endif
1947c478bd9Sstevel@tonic-gate 	    }
1957c478bd9Sstevel@tonic-gate 	    return KADM5_OK;
1967c478bd9Sstevel@tonic-gate 	}
1977c478bd9Sstevel@tonic-gate     } else {
1987c478bd9Sstevel@tonic-gate 	if (strlen(password) < 1)
1997c478bd9Sstevel@tonic-gate 	    return KADM5_PASS_Q_TOOSHORT;
2007c478bd9Sstevel@tonic-gate     }
201*55fea89dSDan Cross     return KADM5_OK;
2027c478bd9Sstevel@tonic-gate }
20346736d35Ssemery 
20446736d35Ssemery void
trunc_name(size_t * len,char ** dots)20546736d35Ssemery trunc_name(size_t *len, char **dots)
20646736d35Ssemery {
20746736d35Ssemery     *dots = *len > MAXPRINCLEN ? "..." : "";
20846736d35Ssemery     *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
20946736d35Ssemery }
210