<?php error_reporting(E_ALL | E_STRICT); ini_set('track_errors', 'On'); $rg_cache_debug = TRUE; $rg_util_debug = TRUE; $rg_sql_debug = 100; $test_normal = TRUE; $INC = dirname(__FILE__) . '/../inc'; require_once(dirname(__FILE__) . '/config.php'); require_once($INC . '/init.inc.php'); require_once($INC . '/util.inc.php'); require_once($INC . '/ldap.inc.php'); require_once($INC . '/ldap_sync.inc.php'); require_once('helpers.inc.php'); require_once('http.inc.php'); rg_log_set_file('ldap.log'); require_once('common.php'); $_testns = 'admin_ldap'; function rg_ldap_start_server(&$l) { $prep = 'ldap/chroot-' . $l['rg_ldap_ns'] . '/prep.done'; $r = @unlink($prep); rg_log('unlinking prep.done returned ' . ($r === FALSE ? 'false' : 'true')); $log = __DIR__ . '/ldap-' . $l['rg_ldap_port']; $pid = pcntl_fork(); if ($pid == 0) { // child foreach ($l as $k => $v) { rg_log($k . '=' . $v); putenv($k . '=' . $v); } rg_exec('cd ldap && bash -x start.sh &> ' . $log . '.log', '', FALSE, FALSE, FALSE); rg_exec('cd ldap && bash -x prepare.sh &> ' . $log . '.prep.log', '', FALSE, FALSE, FALSE); exit(0); } rg_log('Child started with pid ' . $pid); rg_log('Waiting for preparation to finish...'); $tries = 200; while ($tries-- > 0) { $x = @file_get_contents($prep); if ($x !== FALSE) break; rg_log('prep file [' . $prep . '] is not present, wait.'); usleep(100000); } if ($tries == 0) { rg_log('Could not prepare! Exit!'); posix_kill($pid, SIGKILL); exit(1); } $l['log'] = $log; } function clean($log) { rg_log_set_file('ldap-clean.log'); rg_log('Cleaning processes attached to file ' . $log . '.log...'); $r = rg_exec('fuser -k -v -9 ' . escapeshellarg($log . '.log'), '', FALSE, FALSE, FALSE); rg_log_ml('fuser returned: ' . print_r($r, TRUE)); } prepare_http(); $rg_ui = array('is_admin' => 1); rg_test_create_user($db, $rg_ui); $r = test_login($test_url, $rg_ui); if ($r === FALSE) { rg_log("Cannot login!"); exit(1); } rg_log(''); rg_log('Generating certificates...'); $r = rg_exec('./ca.sh ldap', '', FALSE, FALSE, FALSE); if (!strstr($r['data'], 'CA_SH_OK')) { rg_log_ml('data: ' . $r['data']); rg_log('Cannot generate certificates!'); exit(1); } $bind_addr = '127.' . rand(1, 255) . '.' . rand(1,255) . '.' . rand(2,255); $bind_port = 65100; $bind_ports = 65101; $pass = rg_id(16); $user_pass = rg_id(16); $user_key = rg_id(16); rg_log('bind_addr=' . $bind_addr . ' bind_port=' . $bind_port . ' bind_ports=' . $bind_ports . ' pass=' . $pass . ' user_pass=' . $user_pass . ' user_key=' . $user_key); rg_log(''); rg_log_enter('Deleting all LDAP servers'); $sql = 'TRUNCATE ldap_servers'; $res = rg_sql_query($db, $sql); if ($res === FALSE) { rg_log('Cannot delete all LDAP servers'); exit(1); } rg_sql_free_result($res); rg_cache_unset('ldap', RG_SOCKET_NO_WAIT); rg_log_exit(); rg_log(''); rg_log_enter('Deleting LDAP cache'); $sql = 'TRUNCATE ldap_cache'; $res = rg_sql_query($db, $sql); if ($res === FALSE) { rg_log('Cannot delete LDAP cache'); exit(1); } rg_sql_free_result($res); //TODO rg_cache_unset('ldap_cache', RG_SOCKET_NO_WAIT); rg_log_exit(); rg_log(''); rg_log_enter('Loading Admin -> LDAP -> Add...'); $data = array(); $headers = array(); $r = do_req($test_url . '/op/admin/ldap/add', $data, $headers); if ($r === FALSE) { rg_log('Cannot load add page!'); exit(1); } if (!isset($r['tokens']['ldap_add'])) { rg_log_ml('r:' . print_r($r, TRUE)); rg_log('No ldap_add token?!'); exit(1); } $token = $r['tokens']['ldap_add']; $id = rg_id(8); $name = 'server-' . $id . ' <xss>'; rg_log('Posting the form...'); $data = array( 'doit' => 1, 'token' => $token, 'ldap::id' => 0, 'ldap::plan_id' => 0, 'ldap::prio' => 10, 'ldap::session_time' => 600, 'ldap::name' => $name, 'ldap::url' => 'ldap://' . $bind_addr . ':' . $bind_port, 'ldap::bind_dn' => '', 'ldap::bind_pass' => '', 'ldap::user_base' => 'dc=my-domain,dc=com', 'ldap::uid_attr' => 'uid', 'ldap::filter' => 'memberOf=cn=group1,ou=Group,dc=my-domain,dc=com', 'ldap::group_base' => 'dc=my-domain,dc=com', 'ldap::group_attr' => 'memberOf', 'ldap::group_filter' => '', 'ldap::admin_group' => 'cn=(Admins|Admins2),ou=Group,dc=my-domain,dc=com', 'ldap::ca_cert' => '' ); $r = do_req($test_url . '/op/admin/ldap/add', $data, $headers); if (!strstr($r['body'], 'LDAP server has been successfully added/edited.')) { rg_log_ml('body: ' . $r['body']); rg_log('Success message not found!'); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('Loading Admin -> LDAP -> List...'); $data = array(); $headers = array(); $r = do_req($test_url . '/op/admin/ldap/list', $data, $headers); if ($r === FALSE) { rg_log('Cannot load list page!'); exit(1); } // TODO, here test that everything is present in the list $token = $r['tokens']['ldap_list']; rg_log_exit(); rg_log(''); rg_log_enter('Setting up two LDAP servers in mirror mode...'); // We are forced to close the connection, else will get a nasty error, // Even if the child is not doing anything with the connection. rg_sql_close($db); $l1 = array( 'rg_ldap_ns' => 's1', 'rg_ldap_addr' => $bind_addr, 'rg_ldap_port' => $bind_port, 'rg_ldap_ports' => $bind_ports, 'rg_ldap_server_id' => '001', 'rg_ldap_producer_url' => 'ldap://' . $bind_addr . ':' . ($bind_port + 2), 'rg_ldap_producer_rid' => '002', 'rg_ldap_add_data' => 1, 'rg_ldap_pass' => $pass, 'rg_ldap_user_pass' => $user_pass, 'rg_ldap_user_key' => $user_key ); rg_ldap_start_server($l1); $l2 = array( 'rg_ldap_ns' => 's2', 'rg_ldap_addr' => $bind_addr, 'rg_ldap_port' => $bind_port + 2, 'rg_ldap_ports' => $bind_ports + 2, 'rg_ldap_server_id' => '002', 'rg_ldap_producer_url' => 'ldap://' . $bind_addr . ':' . $bind_port, 'rg_ldap_producer_rid' => '001', 'rg_ldap_add_data' => 0, 'rg_ldap_pass' => $pass, 'rg_ldap_user_pass' => $user_pass, 'rg_ldap_user_key' => $user_key ); rg_ldap_start_server($l2); register_shutdown_function('clean', $l1['log']); register_shutdown_function('clean', $l2['log']); $data = array( 'addr' => $bind_addr, 'port' => $bind_port, 'bind_user' => 'cn=Manager,dc=my-domain,dc=com', 'bind_pass' => $pass, 'base' => 'dc=my-domain,dc=com' ); rg_log_exit(); rg_log(''); rg_log_enter('Find out the id of the server...'); $r = rg_ldap_list($db); if ($r['ok'] !== 1) { rg_log('Cannot get the ldap servers list: ' . $r['errmsg']); exit(1); } $found = FALSE; foreach ($r['list'] as $id => $info) { if (strcmp($info['url'], 'ldap://' . $bind_addr . ':' . $bind_port) != 0) continue; $found = TRUE; break; } if (!$found) { rg_log('Could not find the server in database!'); exit(1); } $data['server_id'] = $id; rg_log_exit(); /* TODO: this has to be made available after I deal with the sync rg_log(''); rg_log_enter('sync_ro...'); $r = rg_ldap_sync_ro($db, $data); if ($r['ok'] != 1) { rg_log('Cannot sync: ' . $r['errmsg'] . '!'); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('Deleting user user4...'); $r = rg_ldap_core_connect('ldap://' . $l1['rg_ldap_addr'] . ':' . $l1['rg_ldap_port'], 3); if ($r['ok'] !== 1) { rg_log('Cannot connect to second server: ' . $r['errmsg'] . '!'); exit(1); } $con = $r['con']; $r = rg_ldap_core_bind($con, 'cn=Manager,dc=my-domain,dc=com', $pass); if ($r['ok'] !== 1) { rg_log('cannot bind: ' . $r['errmsg']); exit(1); } $r = rg_ldap_core_del($con, 'uid=user4,ou=People,dc=my-domain,dc=com'); if ($r['ok'] !== 1) { rg_log('Cannot delete: ' . $r['errmsg'] . '!'); exit(1); } rg_log_exit(); // TODO: needed?! sleep(3); rg_log(''); rg_log_enter('get server CSN field...'); $res = rg_sql_query($db, 'SELECT csn FROM ldap_servers' . ' WHERE id = ' . $data['server_id']); if ($res === FALSE) { rg_log('Cannot select csn from db: ' . rg_sql_error() . '!'); exit(1); } $row = rg_sql_fetch_array($res); rg_sql_free_result($res); $csn = $row['csn']; rg_log('csn: ' . $csn); rg_log_exit(); rg_log(''); rg_log_enter('sync_ro (after a delete)...'); $data['rid'] = '001'; $data['csn'] = $csn; // not sure if rid is correct TODO $r = rg_ldap_sync_ro($db, $data); if ($r['ok'] != 1) { rg_log('Cannot sync: ' . $r['errmsg'] . '!'); exit(1); } rg_log_exit(); */ rg_log(''); rg_log_enter('Login using a LDAP user using ldap uid (first login)'); $_ui = array( 'username' => 'user1-' . $user_key, 'pass' => $user_pass, 't' => 'first login by uid' ); $r = test_login($test_url, $_ui); if ($r === FALSE) exit(1); rg_log_exit(); rg_log(''); rg_log_enter('Setting ldap_cache.uid to 0 to trigger a conflict in inserting' . ' in \'users\' table'); $params = array('user' => 'user1-' . $user_key); $sql = 'UPDATE ldap_cache SET uid = 0 WHERE ldap_uid = @@user@@'; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_log('Cannot update ldap_cache.uid!'); exit(1); } rg_sql_free_result($res); rg_log_exit(); rg_log(''); // User will not be found in 'users' table because we search by e-mail rg_log_enter('Login using a LDAP user: mail'); $_ui = array( 'username' => 'user1-' . $user_key . '@my-domain.com', 'pass' => $user_pass, 't' => 'login by e-mail expecting conflict inserting into users table' ); $r = test_login($test_url, $_ui); if ($r === FALSE) exit(1); rg_log_exit(); rg_log(''); rg_log_enter('Login using a LDAP user: uid (second time, expect user present)'); $_ui = array( 'username' => 'user1-' . $user_key, 'pass' => $user_pass, 't' => 'second login by uid, expecting user present in users table' ); $r = test_login($test_url, $_ui); if ($r === FALSE) { rg_log('Cannot login!'); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('Login using a LDAP user: uid (third time, but delete from' . ' \'users\' table first)'); $params = array( 'new' => 'user1-fake-' . $user_key, 'old' => 'user1-' . $user_key ); // First, find out the uid $sql = 'SELECT uid FROM users WHERE username = @@old@@'; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_log('Cannot get info user1 username!'); exit(1); } $row = rg_sql_fetch_array($res); rg_sql_free_result($res); $params['uid'] = $row['uid']; $sql = 'UPDATE users SET username = @@new@@ WHERE uid = @@uid@@'; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_log('Cannot update user1 username!'); exit(1); } $k = 'username_to_uid::user1-' . $user_key; rg_cache_unset($k, RG_SOCKET_NO_WAIT); $k = 'user::' . $params['uid']; rg_cache_unset($k, RG_SOCKET_NO_WAIT); $_ui = array( 'username' => 'user1-' . $user_key, 'pass' => $user_pass, 't' => 'login by uid, but delete from users before' ); $r = test_login($test_url, $_ui); if ($r === FALSE) { rg_log('Cannot login!'); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('We try to login with user2, which have the description as the uid'); rg_log('Updating LDAP server...'); rg_cache_set('ldap::list::' . $data['server_id'] . '::uid_attr', 'DescriptioN', RG_SOCKET_NO_WAIT); $_ui = array( 'username' => 'user2-' . $user_key, 'pass' => $user_pass, 't' => 'now, the uid attr field is description' ); $r = test_login($test_url, $_ui); if ($r === FALSE) { rg_log('Cannot login!'); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('Login again as the admin user...'); $r = test_login($test_url, $rg_ui); if ($r === FALSE) { rg_log("Cannot login!"); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('Loading Admin -> LDAP -> List -> [Edit]...'); $data = array(); $headers = array(); $r = do_req($test_url . '/op/admin/ldap/edit/' . $id, $data, $headers); if ($r === FALSE) { rg_log('Cannot load edit page!'); exit(1); } $token = $r['tokens']['ldap_add']; rg_log_exit(); rg_log(''); rg_log_enter('Posting new data...'); $data = array( 'doit' => 1, 'token' => $token, 'ldap::id' => $id, 'ldap::plan_id' => 9, 'ldap::prio' => 11, 'ldap::session_time' => 700, 'ldap::name' => $name . '<xss>', 'ldap::url' => 'ldaps://' . $bind_addr . ':' . $bind_port, 'ldap::bind_dn' => 'binddn', 'ldap::bind_pass' => 'bind_pass', 'ldap::user_base' => 'o=a,dc=my-domain,dc=com', 'ldap::uid_attr' => 'uid2', 'ldap::filter' => 'memberOf=cn=groupX,ou=Group,dc=my-domain,dc=com', 'ldap::group_base' => 'o=b,dc=my-domain,dc=com', 'ldap::group_attr' => 'memberOfNot', 'ldap::group_filter' => 'group_filter', 'ldap::admin_group' => 'cn=(Admins4|Admins5),ou=Group,dc=my-domain,dc=com', 'ldap::timeout' => 13, 'ldap::ca_cert' => 'ca_cert' ); $headers = array(); $r = do_req($test_url . '/op/admin/ldap/add', $data, $headers); if ($r === FALSE) { rg_log('Cannot load edit page!'); exit(1); } if (!strstr($r['body'], 'LDAP server has been successfully added/edited.')) { rg_log_ml('body: ' . $r['body']); rg_log('Success message not found!'); exit(1); } $sql = 'SELECT * FROM ldap_servers WHERE id = ' . $id; $res = rg_sql_query($db, $sql); $row = rg_sql_fetch_array($res); rg_sql_free_result($res); $key = 'ldap::list::' . $id; $c = test_wait_cache($key); foreach ($data as $k => $v) { // ignore some fields if (strncmp($k, 'ldap::', 6) != 0) continue; $k = substr($k, 6); if (!isset($row[$k])) { rg_log('Field [' . $k . '] was not found in db!'); exit(1); } if (strcmp($row[$k], $v) != 0) { rg_log('Field [' . $k . '] seems was missed in edit (db)!'); rg_log('db=' . $row[$k] . ' sent=' . $v); exit(1); } if (!isset($c[$k])) { rg_log('Field [' . $k . '] was not found in cache!'); exit(1); } if (strcmp($c[$k], $v) != 0) { rg_log('Field [' . $k . '] seems was missed in edit (cache)!'); rg_log('cache=' . $c[$k] . ' sent=' . $v); exit(1); } } // Testing if all fields in the database were updated unset($row['itime']); unset($row['who']); unset($row['csn']); foreach ($row as $k => $v) { if (isset($data['ldap::' . $k])) continue; rg_log('Field [' . $k . '] was missing from the http update!'); exit(1); } rg_log_exit(); rg_log(''); rg_log_enter('Loading Admin -> LDAP -> List (for delete)...'); $data = array(); $headers = array(); $r = do_req($test_url . '/op/admin/ldap/list', $data, $headers); if ($r === FALSE) { rg_log('Cannot load list page!'); exit(1); } $token = $r['tokens']['ldap_list']; rg_log_exit(); rg_log(''); rg_log_enter('Deleting a LDAP server...'); $data = array( 'delete' => 1, 'token' => $token, 'delete_list[' . $id . ']' => 'on' ); $headers = array(); $r = do_req($test_url . '/op/admin/ldap/list', $data, $headers); if ($r === FALSE) { rg_log('Cannot load list page!'); exit(1); } if (!strstr($r['body'], 'The selected LDAP servers have been successfully deleted.')) { rg_log_ml('r: ' . print_r($r, TRUE)); rg_log('Cannot delete LDAP server(s)!'); exit(1); } rg_log_exit(); rg_log('OK!'); ?>