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