$feature["op"] === $page)); $page_content = __PREFIX__makePage( $features, $css, $page, [__PREFIX__makePageHeader( $feature[0]["title"], $feature[0]["description"] ), __PREFIX__makeForm( $page, $_SERVER["REQUEST_URI"], [__PREFIX__makeInput( "text", "Domain controller", "__PARAM_1__", "hostname or IP address", "The domain controller to connect to.", true ), __PREFIX__makeInput( "text", "LDAP port", "__PARAM_2__", "389", "The port to connect to." ), __PREFIX__makeInput( "text", "Domain", "__PARAM_3__", "example.com", "The domain to connect to.", true ), __PREFIX__makeInput( "text", "Username", "__PARAM_4__", "admin", "The username to connect with." ), __PREFIX__makeInput( "password", "Password", "__PARAM_5__", "••••••••", "The password to connect with." ), __PREFIX__makeInput( "textarea", "Query", "__PARAM_6__", "(&(objectClass=user)(sAMAccountName=*))", "The LDAP query to run against the domain controller.", true )] )] ); } /** * Handle the login operation * * @param $operation string The operation to handle * @param $features array{title: string, description: string, svg: string, hidden?: bool, op: string}[] The features * * @return void */ function __PREFIX__handleQueryLDAP($operation, $features) { __PREFIX__runLDAPQuery( $_POST["__PARAM_1__"], !empty($_POST["__PARAM_2__"]) ? intval($_POST["__PARAM_2__"]) : null, !empty($_POST["__PARAM_4__"]) ? $_POST["__PARAM_4__"] : null, !empty($_POST["__PARAM_5__"]) ? $_POST["__PARAM_5__"] : null, $_POST["__PARAM_3__"], $_POST["__PARAM_6__"] ); } /** * @param $server string LDAP server * @param $port int|null LDAP port * @param $username string|null LDAP username * @param $password string|null LDAP password * @param $domain string LDAP domain * @param $query string LDAP query * * @return void */ function __PREFIX__runLDAPQuery($server, $port, $username, $password, $domain, $query) { $port = $port ?: 389; // Connect to LDAP server $ldap_conn = ldap_connect("ldap://$server", $port); if (!$ldap_conn) { echo "Connection failed: " . htmlentities(ldap_error($ldap_conn)); return; } $base_dn = "DC=" . implode(",DC=", explode(".", $domain)); echo "Connected successfully to LDAP server " . htmlentities($server) . ":" . htmlentities($port) . PHP_EOL; echo "Base DN: " . htmlentities($base_dn) . PHP_EOL; // Set LDAP options ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 1); ldap_set_option($ldap_conn, LDAP_DEREF_ALWAYS, 1); // Bind to LDAP server if (!empty($username) && !empty($password)) { $username = "CN=$username,$base_dn"; echo "Binding with username: " . htmlentities($username) . PHP_EOL; // Bind with username and password (authenticating) $ldap_bind = ldap_bind($ldap_conn, $username, $password); } else { echo "Binding anonymously\n"; $ldap_bind = ldap_bind($ldap_conn); } if (!$ldap_bind) { echo "Bind failed: " . htmlentities(ldap_error($ldap_conn)); return; } // Perform LDAP search $ldap_search = ldap_search($ldap_conn, $base_dn, trim($query), ["*"], 0, 0); if (!$ldap_search) { echo "Search failed: " . htmlentities(ldap_error($ldap_conn)); return; } // Get search result entries $ldap_entries = ldap_get_entries($ldap_conn, $ldap_search); if (!$ldap_entries) { echo "Search failed: " . htmlentities(ldap_error($ldap_conn)); return; } echo "Query executed successfully (Query: " . htmlentities($query) . ")\n"; echo json_encode($ldap_entries); // Close LDAP connection ldap_unbind($ldap_conn); } /** * Hook the features to add the login feature * * @param $features array{title: string, description: string, svg: string, hidden?: bool, op: string}[] The features * container * * @return void */ function __PREFIX__queryLdapHooksFeatures(&$features) { global $QUERY_LDAP; $features[] = ["title" => "Query LDAP", "description" => "Query LDAP using the provided credentials.", "svg" => ' ', "op" => $QUERY_LDAP]; } // section.functions.end // section.hooks add_hook("features", "__PREFIX__queryLdapHooksFeatures"); add_named_hook("GET_page", $QUERY_LDAP, "__PREFIX__makeQueryLDAPPage"); add_named_hook("POST_operation", $QUERY_LDAP, "__PREFIX__handleQueryLDAP"); // section.hooks.end