Home | History | Annotate | Download | only in srv
      1 
      2 /*
      3  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
      4  *
      5  *	Openvision retains the copyright to derivative works of
      6  *	this source code.  Do *NOT* create a derivative of this
      7  *	source code before consulting with your legal department.
      8  *	Do *NOT* integrate *ANY* of this source code into another
      9  *	product before consulting with your legal department.
     10  *
     11  *	For further information, read the top-level Openvision
     12  *	copyright which is contained in the top-level MIT Kerberos
     13  *	copyright.
     14  *
     15  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
     16  *
     17  */
     18 
     19 
     20 /*
     21  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
     22  *
     23  * $Header$
     24  */
     25 
     26 #if !defined(lint) && !defined(__CODECENTER__)
     27 static char *rcsid = "$Header$";
     28 #endif
     29 
     30 #include    "k5-int.h"
     31 #include    <krb5/kdb.h>
     32 #include    <ctype.h>
     33 #include    <pwd.h>
     34 
     35 /* for strcasecmp */
     36 #include    <string.h>
     37 
     38 #include    "server_internal.h"
     39 
     40 kadm5_ret_t
     41 adb_policy_init(kadm5_server_handle_t handle)
     42 {
     43     /* now policy is initialized as part of database. No seperate call needed */
     44     /* Solaris Kerberos: krb5_db_inited returns 0 when db has been inited */
     45     if( krb5_db_inited( handle->context ) == 0 )
     46 	return KADM5_OK;
     47 
     48     return krb5_db_open( handle->context, NULL,
     49 			 KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN );
     50 }
     51 
     52 kadm5_ret_t
     53 adb_policy_close(kadm5_server_handle_t handle)
     54 {
     55     /* will be taken care by database close */
     56     return KADM5_OK;
     57 }
     58 
     59 #ifdef HESIOD
     60 /* stolen from v4sever/kadm_funcs.c */
     61 static char *
     62 reverse(str)
     63 	char	*str;
     64 {
     65 	static char newstr[80];
     66 	char	*p, *q;
     67 	int	i;
     68 
     69 	i = strlen(str);
     70 	if (i >= sizeof(newstr))
     71 		i = sizeof(newstr)-1;
     72 	p = str+i-1;
     73 	q = newstr;
     74 	q[i]='\0';
     75 	for(; i > 0; i--)
     76 		*q++ = *p--;
     77 
     78 	return(newstr);
     79 }
     80 #endif /* HESIOD */
     81 
     82 #if 0
     83 static int
     84 lower(str)
     85 	char	*str;
     86 {
     87 	register char	*cp;
     88 	int	effect=0;
     89 
     90 	for (cp = str; *cp; cp++) {
     91 		if (isupper(*cp)) {
     92 			*cp = tolower(*cp);
     93 			effect++;
     94 		}
     95 	}
     96 	return(effect);
     97 }
     98 #endif
     99 
    100 #ifdef HESIOD
    101 static int
    102 str_check_gecos(gecos, pwstr)
    103 	char	*gecos;
    104 	char	*pwstr;
    105 {
    106 	char		*cp, *ncp, *tcp;
    107 
    108 	for (cp = gecos; *cp; ) {
    109 		/* Skip past punctuation */
    110 		for (; *cp; cp++)
    111 			if (isalnum(*cp))
    112 				break;
    113 		/* Skip to the end of the word */
    114 		for (ncp = cp; *ncp; ncp++)
    115 			if (!isalnum(*ncp) && *ncp != '\'')
    116 				break;
    117 		/* Delimit end of word */
    118 		if (*ncp)
    119 			*ncp++ = '\0';
    120 		/* Check word to see if it's the password */
    121 		if (*cp) {
    122 			if (!strcasecmp(pwstr, cp))
    123 				return 1;
    124 			tcp = reverse(cp);
    125 			if (!strcasecmp(pwstr, tcp))
    126 				return 1;
    127 			cp = ncp;
    128 		} else
    129 			break;
    130 	}
    131 	return 0;
    132 }
    133 #endif /* HESIOD */
    134 
    135 /* some of this is stolen from gatekeeper ... */
    136 kadm5_ret_t
    137 passwd_check(kadm5_server_handle_t handle,
    138 	     char *password, int use_policy, kadm5_policy_ent_t pol,
    139 	     krb5_principal principal)
    140 {
    141     int	    nupper = 0,
    142 	    nlower = 0,
    143 	    ndigit = 0,
    144 	    npunct = 0,
    145 	    nspec = 0;
    146     char    c, *s, *cp;
    147 #ifdef HESIOD
    148     extern  struct passwd *hes_getpwnam();
    149     struct  passwd *ent;
    150 #endif
    151 
    152     if(use_policy) {
    153 	if(strlen(password) < pol->pw_min_length)
    154 	    return KADM5_PASS_Q_TOOSHORT;
    155 	s = password;
    156 	while ((c = *s++)) {
    157 	    if (islower((unsigned char) c)) {
    158 		nlower = 1;
    159 		continue;
    160 	    }
    161 	    else if (isupper((unsigned char) c)) {
    162 		nupper = 1;
    163 		continue;
    164 	    } else if (isdigit((unsigned char) c)) {
    165 		ndigit = 1;
    166 		continue;
    167 	    } else if (ispunct((unsigned char) c)) {
    168 		npunct = 1;
    169 		continue;
    170 	    } else {
    171 		nspec = 1;
    172 		continue;
    173 	    }
    174 	}
    175 	if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
    176 	    return KADM5_PASS_Q_CLASS;
    177 	if((find_word(password) == KADM5_OK))
    178 	    return KADM5_PASS_Q_DICT;
    179 	else {
    180 	    int	i, n = krb5_princ_size(handle->context, principal);
    181 	    cp = krb5_princ_realm(handle->context, principal)->data;
    182 	    if (strcasecmp(cp, password) == 0)
    183 		return KADM5_PASS_Q_DICT;
    184 	    for (i = 0; i < n ; i++) {
    185 		cp = krb5_princ_component(handle->context, principal, i)->data;
    186 		if (strcasecmp(cp, password) == 0)
    187 		    return KADM5_PASS_Q_DICT;
    188 #ifdef HESIOD
    189 		ent = hes_getpwnam(cp);
    190 		if (ent && ent->pw_gecos)
    191 		    if (str_check_gecos(ent->pw_gecos, password))
    192 			return KADM5_PASS_Q_DICT; /* XXX new error code? */
    193 #endif
    194 	    }
    195 	    return KADM5_OK;
    196 	}
    197     } else {
    198 	if (strlen(password) < 1)
    199 	    return KADM5_PASS_Q_TOOSHORT;
    200     }
    201     return KADM5_OK;
    202 }
    203 
    204 void
    205 trunc_name(size_t *len, char **dots)
    206 {
    207     *dots = *len > MAXPRINCLEN ? "..." : "";
    208     *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
    209 }
    210