xref: /freebsd/crypto/heimdal/lib/kadm5/password_quality.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*
2  * Copyright (c) 1997-1999 Kungliga Tekniska H�gskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include "kadm5_locl.h"
35 
36 RCSID("$Id: password_quality.c,v 1.4 2000/07/05 13:14:45 joda Exp $");
37 
38 #ifdef HAVE_DLFCN_H
39 #include <dlfcn.h>
40 #endif
41 
42 static const char *
43 simple_passwd_quality (krb5_context context,
44 		       krb5_principal principal,
45 		       krb5_data *pwd)
46 {
47     if (pwd->length < 6)
48 	return "Password too short";
49     else
50 	return NULL;
51 }
52 
53 typedef const char* (*passwd_quality_check_func)(krb5_context,
54 						 krb5_principal,
55 						 krb5_data*);
56 
57 static passwd_quality_check_func passwd_quality_check = simple_passwd_quality;
58 
59 #ifdef HAVE_DLOPEN
60 
61 #define PASSWD_VERSION 0
62 
63 #endif
64 
65 /*
66  * setup the password quality hook
67  */
68 
69 void
70 kadm5_setup_passwd_quality_check(krb5_context context,
71 				 const char *check_library,
72 				 const char *check_function)
73 {
74 #ifdef HAVE_DLOPEN
75     void *handle;
76     void *sym;
77     int *version;
78     int flags;
79     const char *tmp;
80 
81 #ifdef RTLD_NOW
82     flags = RTLD_NOW;
83 #else
84     flags = 0;
85 #endif
86 
87     if(check_library == NULL) {
88 	tmp = krb5_config_get_string(context, NULL,
89 				     "password_quality",
90 				     "check_library",
91 				     NULL);
92 	if(tmp != NULL)
93 	    check_library = tmp;
94     }
95     if(check_function == NULL) {
96 	tmp = krb5_config_get_string(context, NULL,
97 				     "password_quality",
98 				     "check_function",
99 				     NULL);
100 	if(tmp != NULL)
101 	    check_function = tmp;
102     }
103     if(check_library != NULL && check_function == NULL)
104 	check_function = "passwd_check";
105 
106     if(check_library == NULL)
107 	return;
108     handle = dlopen(check_library, flags);
109     if(handle == NULL) {
110 	krb5_warnx(context, "failed to open `%s'", check_library);
111 	return;
112     }
113     version = dlsym(handle, "version");
114     if(version == NULL) {
115 	krb5_warnx(context,
116 		   "didn't find `version' symbol in `%s'", check_library);
117 	dlclose(handle);
118 	return;
119     }
120     if(*version != PASSWD_VERSION) {
121 	krb5_warnx(context,
122 		   "version of loaded library is %d (expected %d)",
123 		   *version, PASSWD_VERSION);
124 	dlclose(handle);
125 	return;
126     }
127     sym = dlsym(handle, check_function);
128     if(sym == NULL) {
129 	krb5_warnx(context,
130 		   "didn't find `%s' symbol in `%s'",
131 		   check_function, check_library);
132 	dlclose(handle);
133 	return;
134     }
135     passwd_quality_check = (passwd_quality_check_func) sym;
136 #endif /* HAVE_DLOPEN */
137 }
138 
139 const char *
140 kadm5_check_password_quality (krb5_context context,
141 			      krb5_principal principal,
142 			      krb5_data *pwd_data)
143 {
144     return (*passwd_quality_check) (context, principal, pwd_data);
145 }
146