*/
#include <config.h>
+#include <portable/kadmin.h>
+#include <portable/krb5.h>
#include <portable/system.h>
#include <ctype.h>
+#include <errno.h>
#include <plugin/api.h>
+/* Heimdal doesn't define KADM5_PASS_Q_GENERIC. */
+#ifndef KADM5_PASS_Q_GENERIC
+# define KADM5_PASS_Q_GENERIC KADM5_PASS_Q_DICT
+#endif
+
/*
* Used to store local state. Currently, all we have is the dictionary path,
* which we get from kadmind rather than from krb5.conf since it's already a
* The dictionary file should not include the trailing .pwd extension.
* Currently, we don't cope with a NULL dictionary path.
*/
-int
+krb5_error_code
pwcheck_init(void **context, const char *dictionary)
{
char *path;
struct context *ctx;
if (dictionary == NULL)
- return 1;
+ return KADM5_MISSING_CONF_PARAMS;
length = strlen(dictionary) + strlen(".pwd") + 1;
path = malloc(length);
if (path == NULL)
- return 1;
+ return errno;
snprintf(path, length, "%s.pwd", dictionary);
if (access(path, R_OK) != 0)
- return 1;
+ return errno;
path[strlen(path) - strlen(".pwd")] = '\0';
ctx = malloc(sizeof(struct context));
if (ctx == NULL)
- return 1;
+ return errno;
ctx->dictionary = path;
*context = ctx;
return 0;
* principal the password is for, and a buffer and buffer length into which to
* put any failure message.
*/
-int
+krb5_error_code
pwcheck_check(void *context, const char *password, const char *principal,
char *errstr, int errstrlen)
{
const char *q;
size_t i, j;
char c;
+ int err;
const char *result;
struct context *ctx = context;
* have to copy the string so that we can manipulate it a bit.
*/
if (strcasecmp(password, principal) == 0) {
- snprintf(errstr, errstrlen, "Password based on username");
- return 1;
+ snprintf(errstr, errstrlen, "Password based on username");
+ return KADM5_PASS_Q_GENERIC;
}
user = strdup(principal);
if (user == NULL) {
+ err = errno;
snprintf(errstr, errstrlen, "Cannot allocate memory");
- return 1;
+ return err;
}
for (p = user; p[0] != '\0'; p++) {
if (p[0] == '\\' && p[1] != '\0') {
if (strcasecmp(password, user) == 0) {
free(user);
snprintf(errstr, errstrlen, "Password based on username");
- return 1;
+ return KADM5_PASS_Q_GENERIC;
}
/* Check against the reversed username. */
if (strcasecmp(password, user) == 0) {
free(user);
snprintf(errstr, errstrlen, "Password based on username");
- return 1;
+ return KADM5_PASS_Q_GENERIC;
}
}
if (strlen(password) > strlen(user))
if (*q == '\0') {
free(user);
snprintf(errstr, errstrlen, "Password based on username");
- return 1;
+ return KADM5_PASS_Q_GENERIC;
}
}
free(user);
result = FascistCheck(password, ctx->dictionary);
if (result != NULL) {
strlcpy(errstr, result, errstrlen);
- return 1;
+ return KADM5_PASS_Q_GENERIC;
}
return 0;
}