#include #include #include #include #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; } }