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