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 209 void 210 trunc_name(size_t *len, char **dots) 211 { 212 *dots = *len > MAXPRINCLEN ? "..." : ""; 213 *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len; 214 } 215