xref: /titanic_41/usr/src/lib/krb5/kadm5/srv/server_misc.c (revision 0eb822a1c0c2bea495647510b75f77f0e57633eb)
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    "adb.h"
35 #include    <pwd.h>
36 
37 /* for strcasecmp */
38 #include    <string.h>
39 
40 #include    "server_internal.h"
41 
42 kadm5_ret_t
43 adb_policy_init(kadm5_server_handle_t handle)
44 {
45     osa_adb_ret_t   ret;
46     if(handle->policy_db == (osa_adb_policy_t) NULL)
47 	if((ret = osa_adb_open_policy(&handle->policy_db,
48 				      &handle->params)) != OSA_ADB_OK)
49 	     return ret;
50     return KADM5_OK;
51 }
52 
53 kadm5_ret_t
54 adb_policy_close(kadm5_server_handle_t handle)
55 {
56     osa_adb_ret_t   ret;
57     if(handle->policy_db != (osa_adb_policy_t) NULL)
58 	if((ret = osa_adb_close_policy(handle->policy_db)) != OSA_ADB_OK)
59 	    return ret;
60     handle->policy_db = NULL;
61     return KADM5_OK;
62 }
63 
64 #ifdef HESIOD
65 /* stolen from v4sever/kadm_funcs.c */
66 static char *
67 reverse(str)
68 	char	*str;
69 {
70 	static char newstr[80];
71 	char	*p, *q;
72 	int	i;
73 
74 	i = strlen(str);
75 	if (i >= sizeof(newstr))
76 		i = sizeof(newstr)-1;
77 	p = str+i-1;
78 	q = newstr;
79 	q[i]='\0';
80 	for(; i > 0; i--)
81 		*q++ = *p--;
82 
83 	return(newstr);
84 }
85 #endif /* HESIOD */
86 
87 #if 0
88 static int
89 lower(str)
90 	char	*str;
91 {
92 	register char	*cp;
93 	int	effect=0;
94 
95 	for (cp = str; *cp; cp++) {
96 		if (isupper(*cp)) {
97 			*cp = tolower(*cp);
98 			effect++;
99 		}
100 	}
101 	return(effect);
102 }
103 #endif
104 
105 #ifdef HESIOD
106 static int
107 str_check_gecos(gecos, pwstr)
108 	char	*gecos;
109 	char	*pwstr;
110 {
111 	char		*cp, *ncp, *tcp;
112 
113 	for (cp = gecos; *cp; ) {
114 		/* Skip past punctuation */
115 		for (; *cp; cp++)
116 			if (isalnum(*cp))
117 				break;
118 		/* Skip to the end of the word */
119 		for (ncp = cp; *ncp; ncp++)
120 			if (!isalnum(*ncp) && *ncp != '\'')
121 				break;
122 		/* Delimit end of word */
123 		if (*ncp)
124 			*ncp++ = '\0';
125 		/* Check word to see if it's the password */
126 		if (*cp) {
127 			if (!strcasecmp(pwstr, cp))
128 				return 1;
129 			tcp = reverse(cp);
130 			if (!strcasecmp(pwstr, tcp))
131 				return 1;
132 			cp = ncp;
133 		} else
134 			break;
135 	}
136 	return 0;
137 }
138 #endif /* HESIOD */
139 
140 /* some of this is stolen from gatekeeper ... */
141 kadm5_ret_t
142 passwd_check(kadm5_server_handle_t handle,
143 	     char *password, int use_policy, kadm5_policy_ent_t pol,
144 	     krb5_principal principal)
145 {
146     int	    nupper = 0,
147 	    nlower = 0,
148 	    ndigit = 0,
149 	    npunct = 0,
150 	    nspec = 0;
151     char    c, *s, *cp;
152 #ifdef HESIOD
153     extern  struct passwd *hes_getpwnam();
154     struct  passwd *ent;
155 #endif
156 
157     if(use_policy) {
158 	if(strlen(password) < pol->pw_min_length)
159 	    return KADM5_PASS_Q_TOOSHORT;
160 	s = password;
161 	while ((c = *s++)) {
162 	    if (islower((int) c)) {
163 		nlower = 1;
164 		continue;
165 	    }
166 	    else if (isupper((int) c)) {
167 		nupper = 1;
168 		continue;
169 	    } else if (isdigit((int) c)) {
170 		ndigit = 1;
171 		continue;
172 	    } else if (ispunct((int) c)) {
173 		npunct = 1;
174 		continue;
175 	    } else {
176 		nspec = 1;
177 		continue;
178 	    }
179 	}
180 	if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
181 	    return KADM5_PASS_Q_CLASS;
182 	if((find_word(password) == KADM5_OK))
183 	    return KADM5_PASS_Q_DICT;
184 	else {
185 	    int	i, n = krb5_princ_size(handle->context, principal);
186 	    cp = krb5_princ_realm(handle->context, principal)->data;
187 	    if (strcasecmp(cp, password) == 0)
188 		return KADM5_PASS_Q_DICT;
189 	    for (i = 0; i < n ; i++) {
190 		cp = krb5_princ_component(handle->context, principal, i)->data;
191 		if (strcasecmp(cp, password) == 0)
192 		    return KADM5_PASS_Q_DICT;
193 #ifdef HESIOD
194 		ent = hes_getpwnam(cp);
195 		if (ent && ent->pw_gecos)
196 		    if (str_check_gecos(ent->pw_gecos, password))
197 			return KADM5_PASS_Q_DICT; /* XXX new error code? */
198 #endif
199 	    }
200 	    return KADM5_OK;
201 	}
202     } else {
203 	if (strlen(password) < 1)
204 	    return KADM5_PASS_Q_TOOSHORT;
205     }
206     return KADM5_OK;
207 }
208