Files
Maison/RdpBroker/src/auth.c
2026-02-10 12:12:11 +01:00

110 lines
3.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ldap.h>
#include "rdp_broker.h"
int authenticate_user(const char *username, const char *password,
const char *samba_server, int samba_port,
const char *base_dn) {
LOG(LOG_DEBUG, "Authenticating user: %s", username);
if (!username || !password || strlen(password) == 0) {
LOG(LOG_WARN, "Empty username or password");
return -1;
}
/* Perform LDAP bind to validate credentials */
int result = ldap_bind_check(samba_server, samba_port, username,
password, base_dn);
if (result == 0) {
LOG(LOG_INFO, "Authentication successful for user: %s", username);
return 0;
} else {
LOG(LOG_WARN, "Authentication failed for user: %s", username);
return -1;
}
}
int ldap_bind_check(const char *server, int port, const char *username,
const char *password, const char *base_dn) {
LDAP *ld = NULL;
int rc;
char ldap_uri[512];
char bind_dn[512];
int version = LDAP_VERSION3;
/* Construct LDAP URI */
snprintf(ldap_uri, sizeof(ldap_uri), "ldap://%s:%d", server, port);
/* Initialize LDAP connection */
rc = ldap_initialize(&ld, ldap_uri);
if (rc != LDAP_SUCCESS) {
LOG(LOG_ERROR, "LDAP initialization failed: %s", ldap_err2string(rc));
return -1;
}
/* Set LDAP version */
rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
if (rc != LDAP_OPT_SUCCESS) {
LOG(LOG_ERROR, "Failed to set LDAP version: %s", ldap_err2string(rc));
ldap_unbind_ext_s(ld, NULL, NULL);
return -1;
}
/* Construct bind DN - typically cn=username,base_dn or username@domain */
/* For Samba AD, we can use username@domain format or userPrincipalName */
/* Here we'll try simple bind with CN format first */
snprintf(bind_dn, sizeof(bind_dn), "cn=%s,%s", username, base_dn);
/* Attempt to bind */
struct berval cred;
cred.bv_val = (char *)password;
cred.bv_len = strlen(password);
rc = ldap_sasl_bind_s(ld, bind_dn, LDAP_SASL_SIMPLE, &cred,
NULL, NULL, NULL);
if (rc != LDAP_SUCCESS) {
/* Try alternative format: username@domain */
/* Extract domain from base_dn (DC=example,DC=com -> example.com) */
char domain[256] = {0};
const char *dc = strstr(base_dn, "DC=");
if (dc) {
const char *ptr = dc + 3;
char *out = domain;
while (*ptr && (out - domain) < sizeof(domain) - 1) {
if (*ptr == ',') {
ptr++;
if (strncmp(ptr, "DC=", 3) == 0) {
*out++ = '.';
ptr += 3;
continue;
}
break;
}
*out++ = *ptr++;
}
*out = '\0';
}
if (strlen(domain) > 0) {
snprintf(bind_dn, sizeof(bind_dn), "%s@%s", username, domain);
rc = ldap_sasl_bind_s(ld, bind_dn, LDAP_SASL_SIMPLE, &cred,
NULL, NULL, NULL);
}
}
ldap_unbind_ext_s(ld, NULL, NULL);
if (rc == LDAP_SUCCESS) {
LOG(LOG_DEBUG, "LDAP bind successful for: %s", username);
return 0;
} else {
LOG(LOG_DEBUG, "LDAP bind failed: %s", ldap_err2string(rc));
return -1;
}
}