10Sstevel@tonic-gate
20Sstevel@tonic-gate /*
30Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * Openvision retains the copyright to derivative works of
60Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this
70Sstevel@tonic-gate * source code before consulting with your legal department.
80Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another
90Sstevel@tonic-gate * product before consulting with your legal department.
100Sstevel@tonic-gate *
110Sstevel@tonic-gate * For further information, read the top-level Openvision
120Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos
130Sstevel@tonic-gate * copyright.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
160Sstevel@tonic-gate *
170Sstevel@tonic-gate */
180Sstevel@tonic-gate
190Sstevel@tonic-gate
200Sstevel@tonic-gate /*
210Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
220Sstevel@tonic-gate *
23*7934SMark.Phalan@Sun.COM * $Header$
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
27*7934SMark.Phalan@Sun.COM static char *rcsid = "$Header$";
280Sstevel@tonic-gate #endif
290Sstevel@tonic-gate
300Sstevel@tonic-gate #include "k5-int.h"
310Sstevel@tonic-gate #include <krb5/kdb.h>
320Sstevel@tonic-gate #include <ctype.h>
330Sstevel@tonic-gate #include <pwd.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate /* for strcasecmp */
360Sstevel@tonic-gate #include <string.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include "server_internal.h"
390Sstevel@tonic-gate
400Sstevel@tonic-gate kadm5_ret_t
adb_policy_init(kadm5_server_handle_t handle)410Sstevel@tonic-gate adb_policy_init(kadm5_server_handle_t handle)
420Sstevel@tonic-gate {
434960Swillf /* now policy is initialized as part of database. No seperate call needed */
445867Smp153739 /* Solaris Kerberos: krb5_db_inited returns 0 when db has been inited */
455867Smp153739 if( krb5_db_inited( handle->context ) == 0 )
464960Swillf return KADM5_OK;
474960Swillf
484960Swillf return krb5_db_open( handle->context, NULL,
494960Swillf KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN );
500Sstevel@tonic-gate }
510Sstevel@tonic-gate
520Sstevel@tonic-gate kadm5_ret_t
adb_policy_close(kadm5_server_handle_t handle)530Sstevel@tonic-gate adb_policy_close(kadm5_server_handle_t handle)
540Sstevel@tonic-gate {
554960Swillf /* will be taken care by database close */
560Sstevel@tonic-gate return KADM5_OK;
570Sstevel@tonic-gate }
580Sstevel@tonic-gate
592881Smp153739 #ifdef HESIOD
600Sstevel@tonic-gate /* stolen from v4sever/kadm_funcs.c */
610Sstevel@tonic-gate static char *
reverse(str)620Sstevel@tonic-gate reverse(str)
630Sstevel@tonic-gate char *str;
640Sstevel@tonic-gate {
650Sstevel@tonic-gate static char newstr[80];
660Sstevel@tonic-gate char *p, *q;
670Sstevel@tonic-gate int i;
680Sstevel@tonic-gate
690Sstevel@tonic-gate i = strlen(str);
700Sstevel@tonic-gate if (i >= sizeof(newstr))
710Sstevel@tonic-gate i = sizeof(newstr)-1;
720Sstevel@tonic-gate p = str+i-1;
730Sstevel@tonic-gate q = newstr;
740Sstevel@tonic-gate q[i]='\0';
750Sstevel@tonic-gate for(; i > 0; i--)
760Sstevel@tonic-gate *q++ = *p--;
770Sstevel@tonic-gate
780Sstevel@tonic-gate return(newstr);
790Sstevel@tonic-gate }
802881Smp153739 #endif /* HESIOD */
810Sstevel@tonic-gate
822881Smp153739 #if 0
830Sstevel@tonic-gate static int
840Sstevel@tonic-gate lower(str)
850Sstevel@tonic-gate char *str;
860Sstevel@tonic-gate {
870Sstevel@tonic-gate register char *cp;
880Sstevel@tonic-gate int effect=0;
890Sstevel@tonic-gate
900Sstevel@tonic-gate for (cp = str; *cp; cp++) {
910Sstevel@tonic-gate if (isupper(*cp)) {
920Sstevel@tonic-gate *cp = tolower(*cp);
930Sstevel@tonic-gate effect++;
940Sstevel@tonic-gate }
950Sstevel@tonic-gate }
960Sstevel@tonic-gate return(effect);
970Sstevel@tonic-gate }
982881Smp153739 #endif
990Sstevel@tonic-gate
1002881Smp153739 #ifdef HESIOD
1010Sstevel@tonic-gate static int
str_check_gecos(gecos,pwstr)1020Sstevel@tonic-gate str_check_gecos(gecos, pwstr)
1030Sstevel@tonic-gate char *gecos;
1040Sstevel@tonic-gate char *pwstr;
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate char *cp, *ncp, *tcp;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate for (cp = gecos; *cp; ) {
1090Sstevel@tonic-gate /* Skip past punctuation */
1100Sstevel@tonic-gate for (; *cp; cp++)
1110Sstevel@tonic-gate if (isalnum(*cp))
1120Sstevel@tonic-gate break;
1130Sstevel@tonic-gate /* Skip to the end of the word */
1140Sstevel@tonic-gate for (ncp = cp; *ncp; ncp++)
1150Sstevel@tonic-gate if (!isalnum(*ncp) && *ncp != '\'')
1160Sstevel@tonic-gate break;
1170Sstevel@tonic-gate /* Delimit end of word */
1180Sstevel@tonic-gate if (*ncp)
1190Sstevel@tonic-gate *ncp++ = '\0';
1200Sstevel@tonic-gate /* Check word to see if it's the password */
1210Sstevel@tonic-gate if (*cp) {
1220Sstevel@tonic-gate if (!strcasecmp(pwstr, cp))
1230Sstevel@tonic-gate return 1;
1240Sstevel@tonic-gate tcp = reverse(cp);
1250Sstevel@tonic-gate if (!strcasecmp(pwstr, tcp))
1260Sstevel@tonic-gate return 1;
1270Sstevel@tonic-gate cp = ncp;
1280Sstevel@tonic-gate } else
1290Sstevel@tonic-gate break;
1300Sstevel@tonic-gate }
1310Sstevel@tonic-gate return 0;
1320Sstevel@tonic-gate }
1332881Smp153739 #endif /* HESIOD */
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate /* some of this is stolen from gatekeeper ... */
1360Sstevel@tonic-gate kadm5_ret_t
passwd_check(kadm5_server_handle_t handle,char * password,int use_policy,kadm5_policy_ent_t pol,krb5_principal principal)1370Sstevel@tonic-gate passwd_check(kadm5_server_handle_t handle,
1380Sstevel@tonic-gate char *password, int use_policy, kadm5_policy_ent_t pol,
1390Sstevel@tonic-gate krb5_principal principal)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate int nupper = 0,
1420Sstevel@tonic-gate nlower = 0,
1430Sstevel@tonic-gate ndigit = 0,
1440Sstevel@tonic-gate npunct = 0,
1450Sstevel@tonic-gate nspec = 0;
1460Sstevel@tonic-gate char c, *s, *cp;
1470Sstevel@tonic-gate #ifdef HESIOD
1480Sstevel@tonic-gate extern struct passwd *hes_getpwnam();
1490Sstevel@tonic-gate struct passwd *ent;
1500Sstevel@tonic-gate #endif
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate if(use_policy) {
1530Sstevel@tonic-gate if(strlen(password) < pol->pw_min_length)
1540Sstevel@tonic-gate return KADM5_PASS_Q_TOOSHORT;
1550Sstevel@tonic-gate s = password;
1560Sstevel@tonic-gate while ((c = *s++)) {
1574960Swillf if (islower((unsigned char) c)) {
1580Sstevel@tonic-gate nlower = 1;
1590Sstevel@tonic-gate continue;
1600Sstevel@tonic-gate }
1614960Swillf else if (isupper((unsigned char) c)) {
1620Sstevel@tonic-gate nupper = 1;
1630Sstevel@tonic-gate continue;
1644960Swillf } else if (isdigit((unsigned char) c)) {
1650Sstevel@tonic-gate ndigit = 1;
1660Sstevel@tonic-gate continue;
1674960Swillf } else if (ispunct((unsigned char) c)) {
1680Sstevel@tonic-gate npunct = 1;
1690Sstevel@tonic-gate continue;
1700Sstevel@tonic-gate } else {
1710Sstevel@tonic-gate nspec = 1;
1720Sstevel@tonic-gate continue;
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
1760Sstevel@tonic-gate return KADM5_PASS_Q_CLASS;
1770Sstevel@tonic-gate if((find_word(password) == KADM5_OK))
1780Sstevel@tonic-gate return KADM5_PASS_Q_DICT;
1790Sstevel@tonic-gate else {
1802881Smp153739 int i, n = krb5_princ_size(handle->context, principal);
1810Sstevel@tonic-gate cp = krb5_princ_realm(handle->context, principal)->data;
1820Sstevel@tonic-gate if (strcasecmp(cp, password) == 0)
1830Sstevel@tonic-gate return KADM5_PASS_Q_DICT;
1842881Smp153739 for (i = 0; i < n ; i++) {
1852881Smp153739 cp = krb5_princ_component(handle->context, principal, i)->data;
1860Sstevel@tonic-gate if (strcasecmp(cp, password) == 0)
1870Sstevel@tonic-gate return KADM5_PASS_Q_DICT;
1880Sstevel@tonic-gate #ifdef HESIOD
1890Sstevel@tonic-gate ent = hes_getpwnam(cp);
1900Sstevel@tonic-gate if (ent && ent->pw_gecos)
1910Sstevel@tonic-gate if (str_check_gecos(ent->pw_gecos, password))
1920Sstevel@tonic-gate return KADM5_PASS_Q_DICT; /* XXX new error code? */
1930Sstevel@tonic-gate #endif
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate return KADM5_OK;
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate } else {
1980Sstevel@tonic-gate if (strlen(password) < 1)
1990Sstevel@tonic-gate return KADM5_PASS_Q_TOOSHORT;
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate return KADM5_OK;
2020Sstevel@tonic-gate }
2033998Ssemery
2043998Ssemery void
trunc_name(size_t * len,char ** dots)2053998Ssemery trunc_name(size_t *len, char **dots)
2063998Ssemery {
2073998Ssemery *dots = *len > MAXPRINCLEN ? "..." : "";
2083998Ssemery *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
2093998Ssemery }
210