1*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate /* 4*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 5*0Sstevel@tonic-gate * 6*0Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 7*0Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 8*0Sstevel@tonic-gate * source code before consulting with your legal department. 9*0Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 10*0Sstevel@tonic-gate * product before consulting with your legal department. 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * For further information, read the top-level Openvision 13*0Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 14*0Sstevel@tonic-gate * copyright. 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 17*0Sstevel@tonic-gate * 18*0Sstevel@tonic-gate */ 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gate /* 22*0Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 23*0Sstevel@tonic-gate * 24*0Sstevel@tonic-gate * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_misc.c,v 1.2 1997/08/07 00:23:11 tlyu Exp $ 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__) 28*0Sstevel@tonic-gate 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*0Sstevel@tonic-gate #endif 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #include "k5-int.h" 32*0Sstevel@tonic-gate #include <krb5/kdb.h> 33*0Sstevel@tonic-gate #include <ctype.h> 34*0Sstevel@tonic-gate #include "adb.h" 35*0Sstevel@tonic-gate #include <pwd.h> 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate /* for strcasecmp */ 38*0Sstevel@tonic-gate #include <string.h> 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #include "server_internal.h" 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate kadm5_ret_t 43*0Sstevel@tonic-gate adb_policy_init(kadm5_server_handle_t handle) 44*0Sstevel@tonic-gate { 45*0Sstevel@tonic-gate osa_adb_ret_t ret; 46*0Sstevel@tonic-gate if(handle->policy_db == (osa_adb_policy_t) NULL) 47*0Sstevel@tonic-gate if((ret = osa_adb_open_policy(&handle->policy_db, 48*0Sstevel@tonic-gate &handle->params)) != OSA_ADB_OK) 49*0Sstevel@tonic-gate return ret; 50*0Sstevel@tonic-gate return KADM5_OK; 51*0Sstevel@tonic-gate } 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate kadm5_ret_t 54*0Sstevel@tonic-gate adb_policy_close(kadm5_server_handle_t handle) 55*0Sstevel@tonic-gate { 56*0Sstevel@tonic-gate osa_adb_ret_t ret; 57*0Sstevel@tonic-gate if(handle->policy_db != (osa_adb_policy_t) NULL) 58*0Sstevel@tonic-gate if((ret = osa_adb_close_policy(handle->policy_db)) != OSA_ADB_OK) 59*0Sstevel@tonic-gate return ret; 60*0Sstevel@tonic-gate handle->policy_db = NULL; 61*0Sstevel@tonic-gate return KADM5_OK; 62*0Sstevel@tonic-gate } 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* stolen from v4sever/kadm_funcs.c */ 65*0Sstevel@tonic-gate static char * 66*0Sstevel@tonic-gate reverse(str) 67*0Sstevel@tonic-gate char *str; 68*0Sstevel@tonic-gate { 69*0Sstevel@tonic-gate static char newstr[80]; 70*0Sstevel@tonic-gate char *p, *q; 71*0Sstevel@tonic-gate int i; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate i = strlen(str); 74*0Sstevel@tonic-gate if (i >= sizeof(newstr)) 75*0Sstevel@tonic-gate i = sizeof(newstr)-1; 76*0Sstevel@tonic-gate p = str+i-1; 77*0Sstevel@tonic-gate q = newstr; 78*0Sstevel@tonic-gate q[i]='\0'; 79*0Sstevel@tonic-gate for(; i > 0; i--) 80*0Sstevel@tonic-gate *q++ = *p--; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate return(newstr); 83*0Sstevel@tonic-gate } 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate static int 86*0Sstevel@tonic-gate lower(str) 87*0Sstevel@tonic-gate char *str; 88*0Sstevel@tonic-gate { 89*0Sstevel@tonic-gate register char *cp; 90*0Sstevel@tonic-gate int effect=0; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate for (cp = str; *cp; cp++) { 93*0Sstevel@tonic-gate if (isupper(*cp)) { 94*0Sstevel@tonic-gate *cp = tolower(*cp); 95*0Sstevel@tonic-gate effect++; 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate return(effect); 99*0Sstevel@tonic-gate } 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate static int 102*0Sstevel@tonic-gate str_check_gecos(gecos, pwstr) 103*0Sstevel@tonic-gate char *gecos; 104*0Sstevel@tonic-gate char *pwstr; 105*0Sstevel@tonic-gate { 106*0Sstevel@tonic-gate char *cp, *ncp, *tcp; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate for (cp = gecos; *cp; ) { 109*0Sstevel@tonic-gate /* Skip past punctuation */ 110*0Sstevel@tonic-gate for (; *cp; cp++) 111*0Sstevel@tonic-gate if (isalnum(*cp)) 112*0Sstevel@tonic-gate break; 113*0Sstevel@tonic-gate /* Skip to the end of the word */ 114*0Sstevel@tonic-gate for (ncp = cp; *ncp; ncp++) 115*0Sstevel@tonic-gate if (!isalnum(*ncp) && *ncp != '\'') 116*0Sstevel@tonic-gate break; 117*0Sstevel@tonic-gate /* Delimit end of word */ 118*0Sstevel@tonic-gate if (*ncp) 119*0Sstevel@tonic-gate *ncp++ = '\0'; 120*0Sstevel@tonic-gate /* Check word to see if it's the password */ 121*0Sstevel@tonic-gate if (*cp) { 122*0Sstevel@tonic-gate if (!strcasecmp(pwstr, cp)) 123*0Sstevel@tonic-gate return 1; 124*0Sstevel@tonic-gate tcp = reverse(cp); 125*0Sstevel@tonic-gate if (!strcasecmp(pwstr, tcp)) 126*0Sstevel@tonic-gate return 1; 127*0Sstevel@tonic-gate cp = ncp; 128*0Sstevel@tonic-gate } else 129*0Sstevel@tonic-gate break; 130*0Sstevel@tonic-gate } 131*0Sstevel@tonic-gate return 0; 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate /* some of this is stolen from gatekeeper ... */ 135*0Sstevel@tonic-gate kadm5_ret_t 136*0Sstevel@tonic-gate passwd_check(kadm5_server_handle_t handle, 137*0Sstevel@tonic-gate char *password, int use_policy, kadm5_policy_ent_t pol, 138*0Sstevel@tonic-gate krb5_principal principal) 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate int nupper = 0, 141*0Sstevel@tonic-gate nlower = 0, 142*0Sstevel@tonic-gate ndigit = 0, 143*0Sstevel@tonic-gate npunct = 0, 144*0Sstevel@tonic-gate nspec = 0; 145*0Sstevel@tonic-gate char c, *s, *cp; 146*0Sstevel@tonic-gate #ifdef HESIOD 147*0Sstevel@tonic-gate extern struct passwd *hes_getpwnam(); 148*0Sstevel@tonic-gate struct passwd *ent; 149*0Sstevel@tonic-gate #endif 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate if(use_policy) { 152*0Sstevel@tonic-gate if(strlen(password) < pol->pw_min_length) 153*0Sstevel@tonic-gate return KADM5_PASS_Q_TOOSHORT; 154*0Sstevel@tonic-gate s = password; 155*0Sstevel@tonic-gate while ((c = *s++)) { 156*0Sstevel@tonic-gate if (islower(c)) { 157*0Sstevel@tonic-gate nlower = 1; 158*0Sstevel@tonic-gate continue; 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate else if (isupper(c)) { 161*0Sstevel@tonic-gate nupper = 1; 162*0Sstevel@tonic-gate continue; 163*0Sstevel@tonic-gate } else if (isdigit(c)) { 164*0Sstevel@tonic-gate ndigit = 1; 165*0Sstevel@tonic-gate continue; 166*0Sstevel@tonic-gate } else if (ispunct(c)) { 167*0Sstevel@tonic-gate npunct = 1; 168*0Sstevel@tonic-gate continue; 169*0Sstevel@tonic-gate } else { 170*0Sstevel@tonic-gate nspec = 1; 171*0Sstevel@tonic-gate continue; 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate } 174*0Sstevel@tonic-gate if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes) 175*0Sstevel@tonic-gate return KADM5_PASS_Q_CLASS; 176*0Sstevel@tonic-gate if((find_word(password) == KADM5_OK)) 177*0Sstevel@tonic-gate return KADM5_PASS_Q_DICT; 178*0Sstevel@tonic-gate else { 179*0Sstevel@tonic-gate char *cp; 180*0Sstevel@tonic-gate int c, n = krb5_princ_size(handle->context, principal); 181*0Sstevel@tonic-gate cp = krb5_princ_realm(handle->context, principal)->data; 182*0Sstevel@tonic-gate if (strcasecmp(cp, password) == 0) 183*0Sstevel@tonic-gate return KADM5_PASS_Q_DICT; 184*0Sstevel@tonic-gate for (c = 0; c < n ; c++) { 185*0Sstevel@tonic-gate cp = krb5_princ_component(handle->context, principal, c)->data; 186*0Sstevel@tonic-gate if (strcasecmp(cp, password) == 0) 187*0Sstevel@tonic-gate return KADM5_PASS_Q_DICT; 188*0Sstevel@tonic-gate #ifdef HESIOD 189*0Sstevel@tonic-gate ent = hes_getpwnam(cp); 190*0Sstevel@tonic-gate if (ent && ent->pw_gecos) 191*0Sstevel@tonic-gate if (str_check_gecos(ent->pw_gecos, password)) 192*0Sstevel@tonic-gate return KADM5_PASS_Q_DICT; /* XXX new error code? */ 193*0Sstevel@tonic-gate #endif 194*0Sstevel@tonic-gate } 195*0Sstevel@tonic-gate return KADM5_OK; 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate } else { 198*0Sstevel@tonic-gate if (strlen(password) < 1) 199*0Sstevel@tonic-gate return KADM5_PASS_Q_TOOSHORT; 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate return KADM5_OK; 202*0Sstevel@tonic-gate } 203