Path: blob/main/crypto/krb5/src/lib/kadm5/srv/pwqual_hesiod.c
39566 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* lib/kadm5/srv/pwqual_hesiod.c */2/*3* Copyright (C) 2010 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Export of this software from the United States of America may7* require a specific license from the United States Government.8* It is the responsibility of any person or organization contemplating9* export to obtain such a license before exporting.10*11* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and12* distribute this software and its documentation for any purpose and13* without fee is hereby granted, provided that the above copyright14* notice appear in all copies and that both that copyright notice and15* this permission notice appear in supporting documentation, and that16* the name of M.I.T. not be used in advertising or publicity pertaining17* to distribution of the software without specific, written prior18* permission. Furthermore if you modify this software you must label19* your software as modified software and not distribute it in such a20* fashion that it might be confused with the original M.I.T. software.21* M.I.T. makes no representations about the suitability of22* this software for any purpose. It is provided "as is" without express23* or implied warranty.24*/2526/*27* Password quality module to check passwords against GECOS fields of Hesiod28* passwd information, if the tree is compiled with Hesiod support.29*/3031#include "k5-int.h"32#include <krb5/pwqual_plugin.h>33#include "server_internal.h"34#include <ctype.h>3536#ifdef HESIOD37#include <pwd.h>3839static char *40reverse(char *str, char *newstr, size_t newstr_size)41{42char *p, *q;43size_t i;4445i = strlen(str);46if (i >= newstr_size)47i = newstr_size - 1;48p = str + i - 1;49q = newstr;50q[i] = '\0';51for (; i > 0; i--)52*q++ = *p--;5354return newstr;55}5657static int58str_check_gecos(char *gecos, const char *pwstr)59{60char *cp, *ncp, *tcp, revbuf[80];6162for (cp = gecos; *cp; ) {63/* Skip past punctuation */64for (; *cp; cp++)65if (isalnum(*cp))66break;6768/* Skip to the end of the word */69for (ncp = cp; *ncp; ncp++) {70if (!isalnum(*ncp) && *ncp != '\'')71break;72}7374/* Delimit end of word */75if (*ncp)76*ncp++ = '\0';7778/* Check word to see if it's the password */79if (*cp) {80if (!strcasecmp(pwstr, cp))81return 1;82tcp = reverse(cp, revbuf, sizeof(revbuf));83if (!strcasecmp(pwstr, tcp))84return 1;85cp = ncp;86} else87break;88}89return 0;90}91#endif /* HESIOD */9293static krb5_error_code94hesiod_check(krb5_context context, krb5_pwqual_moddata data,95const char *password, const char *policy_name,96krb5_principal princ, const char **languages)97{98#ifdef HESIOD99extern struct passwd *hes_getpwnam();100struct passwd *ent;101int i, n;102const char *cp;103104/* Don't check for principals with no password policy. */105if (policy_name == NULL)106return 0;107108n = krb5_princ_size(handle->context, princ);109for (i = 0; i < n; i++) {110ent = hes_getpwnam(cp);111if (ent && ent->pw_gecos && str_check_gecos(ent->pw_gecos, password)) {112k5_setmsg(context, KADM5_PASS_Q_DICT,113_("Password may not match user information."));114return KADM5_PASS_Q_DICT;115}116}117#endif /* HESIOD */118return 0;119}120121krb5_error_code122pwqual_hesiod_initvt(krb5_context context, int maj_ver, int min_ver,123krb5_plugin_vtable vtable)124{125krb5_pwqual_vtable vt;126127if (maj_ver != 1)128return KRB5_PLUGIN_VER_NOTSUPP;129vt = (krb5_pwqual_vtable)vtable;130vt->name = "hesiod";131vt->check = hesiod_check;132return 0;133}134135136