summaryrefslogtreecommitdiff
path: root/usr.sbin/ldapd
diff options
context:
space:
mode:
authorMartin Hedenfal <martinh@cvs.openbsd.org>2010-09-20 17:26:48 +0000
committerMartin Hedenfal <martinh@cvs.openbsd.org>2010-09-20 17:26:48 +0000
commitbfd863edcaadd3a7a36f6a148650568c392904bb (patch)
tree3ce93a7a16c9fb69066b9a824b1052472625d3e7 /usr.sbin/ldapd
parent1204a315f0ee81ad6a88b52df29c00e0a0da3501 (diff)
Implement support for bsdauth authentication via simple binds, not only
SASL. This works by prefixing the userPassword attribute with {BSDAUTH}, followed by the (bsd) username. For example: userPassword: {BSDAUTH}username Idea by william@. Tested by william@.
Diffstat (limited to 'usr.sbin/ldapd')
-rw-r--r--usr.sbin/ldapd/auth.c105
1 files changed, 60 insertions, 45 deletions
diff --git a/usr.sbin/ldapd/auth.c b/usr.sbin/ldapd/auth.c
index d1b7d373d85..ff8e9a05c0e 100644
--- a/usr.sbin/ldapd/auth.c
+++ b/usr.sbin/ldapd/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.6 2010/09/01 17:34:15 martinh Exp $ */
+/* $OpenBSD: auth.c,v 1.7 2010/09/20 17:26:47 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -159,14 +159,43 @@ authorized(struct conn *conn, struct namespace *ns, int rights, char *dn,
}
static int
-check_password(const char *stored_passwd, const char *passwd)
+send_auth_request(struct request *req, const char *username,
+ const char *password)
{
- int sz;
+ struct auth_req auth_req;
+
+ bzero(&auth_req, sizeof(auth_req));
+ if (strlcpy(auth_req.name, username,
+ sizeof(auth_req.name)) >= sizeof(auth_req.name))
+ goto fail;
+ if (strlcpy(auth_req.password, password,
+ sizeof(auth_req.password)) >= sizeof(auth_req.password))
+ goto fail;
+ auth_req.fd = req->conn->fd;
+ auth_req.msgid = req->msgid;
+
+ if (imsgev_compose(iev_ldapd, IMSG_LDAPD_AUTH, 0, 0, -1, &auth_req,
+ sizeof(auth_req)) == -1)
+ goto fail;
+
+ req->conn->bind_req = req;
+ return 0;
+
+fail:
+ bzero(&auth_req, sizeof(auth_req));
+ return -1;
+}
+
+static int
+check_password(struct request *req, const char *stored_passwd,
+ const char *passwd)
+{
+ unsigned char tmp[128];
+ unsigned char md[SHA_DIGEST_LENGTH];
char *encpw;
unsigned char *salt;
- unsigned char md[SHA_DIGEST_LENGTH];
- unsigned char tmp[128];
SHA_CTX ctx;
+ int sz;
if (stored_passwd == NULL)
return -1;
@@ -174,41 +203,41 @@ check_password(const char *stored_passwd, const char *passwd)
if (strncmp(stored_passwd, "{SHA}", 5) == 0) {
sz = b64_pton(stored_passwd + 5, tmp, sizeof(tmp));
if (sz != SHA_DIGEST_LENGTH)
- return -1;
+ return (-1);
SHA1_Init(&ctx);
SHA1_Update(&ctx, passwd, strlen(passwd));
SHA1_Final(md, &ctx);
- return memcmp(md, tmp, SHA_DIGEST_LENGTH);
- }
- else if (strncmp(stored_passwd, "{SSHA}", 6) == 0) {
+ return (bcmp(md, tmp, SHA_DIGEST_LENGTH) ? 1 : 0);
+ } else if (strncmp(stored_passwd, "{SSHA}", 6) == 0) {
sz = b64_pton(stored_passwd + 6, tmp, sizeof(tmp));
if (sz <= SHA_DIGEST_LENGTH)
- return -1;
+ return (-1);
salt = tmp + SHA_DIGEST_LENGTH;
SHA1_Init(&ctx);
SHA1_Update(&ctx, passwd, strlen(passwd));
SHA1_Update(&ctx, salt, sz - SHA_DIGEST_LENGTH);
SHA1_Final(md, &ctx);
- return memcmp(md, tmp, SHA_DIGEST_LENGTH);
- }
- else if (strncmp(stored_passwd, "{CRYPT}", 7) == 0) {
+ return (bcmp(md, tmp, SHA_DIGEST_LENGTH) ? 1 : 0);
+ } else if (strncmp(stored_passwd, "{CRYPT}", 7) == 0) {
encpw = crypt(passwd, stored_passwd + 7);
if (encpw == NULL)
- return -1;
- return strcmp(encpw, stored_passwd + 7);
- }
- else
- return strcmp(stored_passwd, passwd);
+ return (-1);
+ return (strcmp(encpw, stored_passwd + 7) == 0 ? 1 : 0);
+ } else if (strncmp(stored_passwd, "{BSDAUTH}", 9) == 0) {
+ if (send_auth_request(req, stored_passwd + 9, passwd) == -1)
+ return (-1);
+ return 2; /* Operation in progress. */
+ } else
+ return (strcmp(stored_passwd, passwd) == 0 ? 1 : 0);
}
static int
ldap_auth_sasl(struct request *req, char *binddn, struct ber_element *params)
{
- size_t len;
char *method;
char *authzid, *authcid, *password;
char *creds;
- struct auth_req auth_req;
+ size_t len;
if (ber_scanf_elements(params, "{sx", &method, &creds, &len) != 0)
return LDAP_PROTOCOL_ERROR;
@@ -234,23 +263,9 @@ ldap_auth_sasl(struct request *req, char *binddn, struct ber_element *params)
log_debug("sasl authorization id = [%s]", authzid);
log_debug("sasl authentication id = [%s]", authcid);
- bzero(&auth_req, sizeof(auth_req));
- if (strlcpy(auth_req.name, authcid, sizeof(auth_req.name)) >=
- sizeof(auth_req.name))
- return LDAP_OPERATIONS_ERROR;
- if (strlcpy(auth_req.password, password, sizeof(auth_req.password)) >=
- sizeof(auth_req.password))
- return LDAP_OPERATIONS_ERROR;
- auth_req.fd = req->conn->fd;
- auth_req.msgid = req->msgid;
- bzero(password, strlen(password));
-
- if (imsgev_compose(iev_ldapd, IMSG_LDAPD_AUTH, 0, 0, -1, &auth_req,
- sizeof(auth_req)) == -1)
+ if (send_auth_request(req, authcid, password) != 0)
return LDAP_OPERATIONS_ERROR;
- req->conn->bind_req = req;
-
return LDAP_SUCCESS;
}
@@ -285,13 +300,11 @@ ldap_auth_simple(struct request *req, char *binddn, struct ber_element *auth)
}
if (conf->rootdn != NULL && strcmp(conf->rootdn, binddn) == 0) {
- if (check_password(conf->rootpw, password) == 0)
- ok = 1;
+ ok = check_password(req, conf->rootpw, password);
} else if ((ns = namespace_lookup_base(binddn, 1)) == NULL) {
return LDAP_INVALID_CREDENTIALS;
} else if (ns->rootdn != NULL && strcmp(ns->rootdn, binddn) == 0) {
- if (check_password(ns->rootpw, password) == 0)
- ok = 1;
+ ok = check_password(req, ns->rootpw, password);
} else if (namespace_has_referrals(ns)) {
return LDAP_INVALID_CREDENTIALS;
} else {
@@ -313,24 +326,26 @@ ldap_auth_simple(struct request *req, char *binddn, struct ber_element *auth)
elm = elm->be_next) {
if (ber_get_string(elm, &user_password) != 0)
continue;
- if (check_password(user_password,
- password) == 0) {
- ok = 1;
+ ok = check_password(req, user_password, password);
+ if (ok)
break;
- }
}
}
}
- if (ok) {
+ if (ok == 1) {
free(req->conn->binddn);
if ((req->conn->binddn = strdup(binddn)) == NULL)
return LDAP_OTHER;
log_debug("successfully authenticated as %s",
req->conn->binddn);
return LDAP_SUCCESS;
- } else
+ } else if (ok == 2)
+ return -LDAP_SASL_BIND_IN_PROGRESS;
+ else if (ok == 0)
return LDAP_INVALID_CREDENTIALS;
+ else
+ return LDAP_OPERATIONS_ERROR;
}
void