2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2N/A/*
2N/A * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
2N/A *
2N/A * $Header$
2N/A */
2N/A
2N/A/*
2N/A * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
2N/A *
2N/A * Openvision retains the copyright to derivative works of
2N/A * this source code. Do *NOT* create a derivative of this
2N/A * source code before consulting with your legal department.
2N/A * Do *NOT* integrate *ANY* of this source code into another
2N/A * product before consulting with your legal department.
2N/A *
2N/A * For further information, read the top-level Openvision
2N/A * copyright which is contained in the top-level MIT Kerberos
2N/A * copyright.
2N/A *
2N/A * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
2N/A *
2N/A */
2N/A
2N/A#if !defined(lint) && !defined(__CODECENTER__)
2N/Astatic char *rcsid = "$Header$";
2N/A#endif
2N/A
2N/A#include "k5-int.h"
2N/A#include <kdb.h>
2N/A#include <ctype.h>
2N/A#include <pwd.h>
2N/A
2N/A/* for strcasecmp */
2N/A#include <string.h>
2N/A
2N/A#include "server_internal.h"
2N/A
2N/Akadm5_ret_t
2N/Aadb_policy_init(kadm5_server_handle_t handle)
2N/A{
2N/A /* now policy is initialized as part of database. No separate call needed */
2N/A /* Solaris Kerberos: krb5_db_inited returns 0 when db has been inited */
2N/A if( krb5_db_inited( handle->context ) == 0 )
2N/A return KADM5_OK;
2N/A
2N/A return krb5_db_open( handle->context, NULL,
2N/A KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN );
2N/A}
2N/A
2N/Akadm5_ret_t
2N/Aadb_policy_close(kadm5_server_handle_t handle)
2N/A{
2N/A /* will be taken care by database close */
2N/A return KADM5_OK;
2N/A}
2N/A
2N/A#ifdef HESIOD
2N/A/* stolen from v4sever/kadm_funcs.c */
2N/Astatic char *
2N/Areverse(str)
2N/A char *str;
2N/A{
2N/A static char newstr[80];
2N/A char *p, *q;
2N/A int i;
2N/A
2N/A i = strlen(str);
2N/A if (i >= sizeof(newstr))
2N/A i = sizeof(newstr)-1;
2N/A p = str+i-1;
2N/A q = newstr;
2N/A q[i]='\0';
2N/A for(; i > 0; i--)
2N/A *q++ = *p--;
2N/A
2N/A return(newstr);
2N/A}
2N/A#endif /* HESIOD */
2N/A
2N/A#if 0
2N/Astatic int
2N/Alower(str)
2N/A char *str;
2N/A{
2N/A register char *cp;
2N/A int effect=0;
2N/A
2N/A for (cp = str; *cp; cp++) {
2N/A if (isupper(*cp)) {
2N/A *cp = tolower(*cp);
2N/A effect++;
2N/A }
2N/A }
2N/A return(effect);
2N/A}
2N/A#endif
2N/A
2N/A#ifdef HESIOD
2N/Astatic int
2N/Astr_check_gecos(gecos, pwstr)
2N/A char *gecos;
2N/A char *pwstr;
2N/A{
2N/A char *cp, *ncp, *tcp;
2N/A
2N/A for (cp = gecos; *cp; ) {
2N/A /* Skip past punctuation */
2N/A for (; *cp; cp++)
2N/A if (isalnum(*cp))
2N/A break;
2N/A /* Skip to the end of the word */
2N/A for (ncp = cp; *ncp; ncp++)
2N/A if (!isalnum(*ncp) && *ncp != '\'')
2N/A break;
2N/A /* Delimit end of word */
2N/A if (*ncp)
2N/A *ncp++ = '\0';
2N/A /* Check word to see if it's the password */
2N/A if (*cp) {
2N/A if (!strcasecmp(pwstr, cp))
2N/A return 1;
2N/A tcp = reverse(cp);
2N/A if (!strcasecmp(pwstr, tcp))
2N/A return 1;
2N/A cp = ncp;
2N/A } else
2N/A break;
2N/A }
2N/A return 0;
2N/A}
2N/A#endif /* HESIOD */
2N/A
2N/A/* some of this is stolen from gatekeeper ... */
2N/Akadm5_ret_t
2N/Apasswd_check(kadm5_server_handle_t handle,
2N/A char *password, int use_policy, kadm5_policy_ent_t pol,
2N/A krb5_principal principal)
2N/A{
2N/A int nupper = 0,
2N/A nlower = 0,
2N/A ndigit = 0,
2N/A npunct = 0,
2N/A nspec = 0;
2N/A char c, *s, *cp;
2N/A#ifdef HESIOD
2N/A extern struct passwd *hes_getpwnam();
2N/A struct passwd *ent;
2N/A#endif
2N/A
2N/A if(use_policy) {
2N/A if(strlen(password) < pol->pw_min_length)
2N/A return KADM5_PASS_Q_TOOSHORT;
2N/A s = password;
2N/A while ((c = *s++)) {
2N/A if (islower((unsigned char) c)) {
2N/A nlower = 1;
2N/A continue;
2N/A }
2N/A else if (isupper((unsigned char) c)) {
2N/A nupper = 1;
2N/A continue;
2N/A } else if (isdigit((unsigned char) c)) {
2N/A ndigit = 1;
2N/A continue;
2N/A } else if (ispunct((unsigned char) c)) {
2N/A npunct = 1;
2N/A continue;
2N/A } else {
2N/A nspec = 1;
2N/A continue;
2N/A }
2N/A }
2N/A if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
2N/A return KADM5_PASS_Q_CLASS;
2N/A if((find_word(password) == KADM5_OK))
2N/A return KADM5_PASS_Q_DICT;
2N/A else {
2N/A int i, n = krb5_princ_size(handle->context, principal);
2N/A cp = krb5_princ_realm(handle->context, principal)->data;
2N/A if (strcasecmp(cp, password) == 0)
2N/A return KADM5_PASS_Q_DICT;
2N/A for (i = 0; i < n ; i++) {
2N/A cp = krb5_princ_component(handle->context, principal, i)->data;
2N/A if (strcasecmp(cp, password) == 0)
2N/A return KADM5_PASS_Q_DICT;
2N/A#ifdef HESIOD
2N/A ent = hes_getpwnam(cp);
2N/A if (ent && ent->pw_gecos)
2N/A if (str_check_gecos(ent->pw_gecos, password))
2N/A return KADM5_PASS_Q_DICT; /* XXX new error code? */
2N/A#endif
2N/A }
2N/A return KADM5_OK;
2N/A }
2N/A } else {
2N/A if (strlen(password) < 1)
2N/A return KADM5_PASS_Q_TOOSHORT;
2N/A }
2N/A return KADM5_OK;
2N/A}
2N/A
2N/A/* Solaris Kerberos */
2N/Avoid
2N/Atrunc_name(size_t *len, char **dots)
2N/A{
2N/A *dots = *len > MAXPRINCLEN ? "..." : "";
2N/A *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
2N/A}
2N/A