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
adb_policy_init(kadm5_server_handle_t handle)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
adb_policy_close(kadm5_server_handle_t handle)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 *
reverse(str)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
str_check_gecos(gecos,pwstr)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
passwd_check(kadm5_server_handle_t handle,char * password,int use_policy,kadm5_policy_ent_t pol,krb5_principal principal)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
trunc_name(size_t * len,char ** dots)205 trunc_name(size_t *len, char **dots)
206 {
207 *dots = *len > MAXPRINCLEN ? "..." : "";
208 *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
209 }
210