xref: /titanic_41/usr/src/lib/krb5/kadm5/srv/server_misc.c (revision d58fda4376e4bf67072ce2e69f6f47036f9dbb68)
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.2 1997/08/07 00:23:11 tlyu 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.2 1997/08/07 00:23:11 tlyu 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 /* stolen from v4sever/kadm_funcs.c */
65 static char *
66 reverse(str)
67 	char	*str;
68 {
69 	static char newstr[80];
70 	char	*p, *q;
71 	int	i;
72 
73 	i = strlen(str);
74 	if (i >= sizeof(newstr))
75 		i = sizeof(newstr)-1;
76 	p = str+i-1;
77 	q = newstr;
78 	q[i]='\0';
79 	for(; i > 0; i--)
80 		*q++ = *p--;
81 
82 	return(newstr);
83 }
84 
85 static int
86 lower(str)
87 	char	*str;
88 {
89 	register char	*cp;
90 	int	effect=0;
91 
92 	for (cp = str; *cp; cp++) {
93 		if (isupper(*cp)) {
94 			*cp = tolower(*cp);
95 			effect++;
96 		}
97 	}
98 	return(effect);
99 }
100 
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 
134 /* some of this is stolen from gatekeeper ... */
135 kadm5_ret_t
136 passwd_check(kadm5_server_handle_t handle,
137 	     char *password, int use_policy, kadm5_policy_ent_t pol,
138 	     krb5_principal principal)
139 {
140     int	    nupper = 0,
141 	    nlower = 0,
142 	    ndigit = 0,
143 	    npunct = 0,
144 	    nspec = 0;
145     char    c, *s, *cp;
146 #ifdef HESIOD
147     extern  struct passwd *hes_getpwnam();
148     struct  passwd *ent;
149 #endif
150 
151     if(use_policy) {
152 	if(strlen(password) < pol->pw_min_length)
153 	    return KADM5_PASS_Q_TOOSHORT;
154 	s = password;
155 	while ((c = *s++)) {
156 	    if (islower(c)) {
157 		nlower = 1;
158 		continue;
159 	    }
160 	    else if (isupper(c)) {
161 		nupper = 1;
162 		continue;
163 	    } else if (isdigit(c)) {
164 		ndigit = 1;
165 		continue;
166 	    } else if (ispunct(c)) {
167 		npunct = 1;
168 		continue;
169 	    } else {
170 		nspec = 1;
171 		continue;
172 	    }
173 	}
174 	if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
175 	    return KADM5_PASS_Q_CLASS;
176 	if((find_word(password) == KADM5_OK))
177 	    return KADM5_PASS_Q_DICT;
178 	else {
179 	    char	*cp;
180 	    int	c, 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 (c = 0; c < n ; c++) {
185 		cp = krb5_princ_component(handle->context, principal, c)->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