Path: blob/main/crypto/krb5/src/lib/kadm5/srv/server_misc.c
39566 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* Copyright (C) 2010 by the Massachusetts Institute of Technology.3* All rights reserved.4*5* Export of this software from the United States of America may6* require a specific license from the United States Government.7* It is the responsibility of any person or organization contemplating8* export to obtain such a license before exporting.9*10* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and11* distribute this software and its documentation for any purpose and12* without fee is hereby granted, provided that the above copyright13* notice appear in all copies and that both that copyright notice and14* this permission notice appear in supporting documentation, and that15* the name of M.I.T. not be used in advertising or publicity pertaining16* to distribution of the software without specific, written prior17* permission. Furthermore if you modify this software you must label18* your software as modified software and not distribute it in such a19* fashion that it might be confused with the original M.I.T. software.20* M.I.T. makes no representations about the suitability of21* this software for any purpose. It is provided "as is" without express22* or implied warranty.23*/24/*25* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved26*/2728#include "k5-int.h"29#include <kdb.h>30#include <ctype.h>31#include <pwd.h>32#include <syslog.h>33#include "server_internal.h"34#include <adm_proto.h>3536kadm5_ret_t37init_pwqual(kadm5_server_handle_t handle)38{39krb5_error_code ret;40pwqual_handle *list;41const char *dict_file = NULL;4243/* Register the built-in password quality modules. */44ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,45"dict", pwqual_dict_initvt);46if (ret != 0)47return ret;48ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,49"empty", pwqual_empty_initvt);50if (ret != 0)51return ret;52ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,53"hesiod", pwqual_hesiod_initvt);54if (ret != 0)55return ret;56ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,57"princ", pwqual_princ_initvt);58if (ret != 0)59return ret;6061/* Load all available password quality modules. */62if (handle->params.mask & KADM5_CONFIG_DICT_FILE)63dict_file = handle->params.dict_file;64ret = k5_pwqual_load(handle->context, dict_file, &list);65if (ret != 0)66return ret;6768handle->qual_handles = list;69return 0;70}7172/* Check that a password meets the quality constraints given in pol. */73static kadm5_ret_t74check_against_policy(kadm5_server_handle_t handle, const char *password,75kadm5_policy_ent_t pol)76{77int hasupper = 0, haslower = 0, hasdigit = 0, haspunct = 0, hasspec = 0;78int c, nclasses;7980/* Check against the policy's minimum length. */81if (strlen(password) < (size_t)pol->pw_min_length)82return KADM5_PASS_Q_TOOSHORT;8384/* Check against the policy's minimum number of character classes. */85while ((c = (unsigned char)*password++) != '\0') {86if (islower(c))87haslower = 1;88else if (isupper(c))89hasupper = 1;90else if (isdigit(c))91hasdigit = 1;92else if (ispunct(c))93haspunct = 1;94else95hasspec = 1;96}97nclasses = hasupper + haslower + hasdigit + haspunct + hasspec;98if (nclasses < pol->pw_min_classes)99return KADM5_PASS_Q_CLASS;100return KADM5_OK;101}102103/* Check a password against all available password quality plugin modules104* and against policy. */105kadm5_ret_t106passwd_check(kadm5_server_handle_t handle, const char *password,107kadm5_policy_ent_t policy, krb5_principal princ)108{109krb5_error_code ret;110pwqual_handle *h;111const char *polname = (policy == NULL) ? NULL : policy->policy;112113if (policy != NULL) {114ret = check_against_policy(handle, password, policy);115if (ret != 0)116return ret;117}118for (h = handle->qual_handles; *h != NULL; h++) {119ret = k5_pwqual_check(handle->context, *h, password, polname, princ);120if (ret != 0) {121const char *e = krb5_get_error_message(handle->context, ret);122const char *modname = k5_pwqual_name(handle->context, *h);123char *princname;124if (krb5_unparse_name(handle->context, princ, &princname) != 0)125princname = NULL;126krb5_klog_syslog(LOG_ERR,127_("password quality module %s rejected password "128"for %s: %s"), modname,129princname ? princname : "(can't unparse)", e);130krb5_free_error_message(handle->context, e);131free(princname);132return ret;133}134}135return 0;136}137138void139destroy_pwqual(kadm5_server_handle_t handle)140{141k5_pwqual_free_handles(handle->context, handle->qual_handles);142handle->qual_handles = NULL;143}144145kadm5_ret_t146kadm5_get_privs(void *server_handle, long *privs)147{148CHECK_HANDLE(server_handle);149150/* this is impossible to do with the current interface. For now,151return all privs, which will confuse some clients, but not152deny any access to users of "smart" clients which try to cache */153154*privs = ~0;155156return KADM5_OK;157}158159160