Initialisation depot
This commit is contained in:
109
RdpBroker/src/auth.c
Normal file
109
RdpBroker/src/auth.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user