xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
<root> / inc / ldap_core.inc.php (ba34d06fab931777c90d572bd867eb2d5e133a90) (5,122B) (mode 100644) [raw]
<?php
require_once($INC . "/sql.inc.php");
require_once($INC . "/state.inc.php");
require_once($INC . "/prof.inc.php");

$rg_ldap_core_error = '';

function rg_ldap_core_set_error($str)
{
	global $rg_ldap_core_error;
	$rg_ldap_core_error = $str;
	rg_log($str);
}

function rg_ldap_core_error()
{
	global $rg_ldap_core_error;
	return $rg_ldap_core_error;
}

/*
 * Connects to a ldap server
 */
function rg_ldap_core_connect($server, $timeout)
{
	$ret = array('ok' => 0);
	while (1) {
		//ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);

		$r = ldap_connect($server);
		if ($r === FALSE) {
			$ret['errmsg'] = 'cannot connect to LDAP server';
			break;
		}

		// http://php.net/manual/en/function.ldap-set-option.php
		ldap_set_option($r, LDAP_OPT_PROTOCOL_VERSION, 3);
		ldap_set_option($r, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS);
		ldap_set_option($r, LDAP_OPT_TIMELIMIT, $timeout);
		ldap_set_option($r, LDAP_OPT_NETWORK_TIMEOUT, $timeout);
		//ldap_set_option($r, LDAP_OPT_DEBUG_LEVEL, 7);

		$ret['con'] = $r;
		$ret['ok'] = 1;
		break;
	}

	return $ret;
}

/*
 * LDAP bind
 */
function rg_ldap_core_bind($con, $rdn, $pass)
{
	$ret = array('ok' => 0);
	while (1) {
		$r = @ldap_bind($con, $rdn, $pass);
		if ($r !== TRUE) {
			ldap_get_option($con, LDAP_OPT_ERROR_STRING, $e);
			$ret['errmsg'] = ldap_error($con) . ' [' . $e . ']';
			break;
		}

		$ret['ok'] = 1;
		break;
	}

	return $ret;
}

/*
 * ldap_add wrapper
 */
function rg_ldap_core_add($con, $dn, $entry)
{
	$ret = array('ok' => 0);
	while (1) {
		$r = @ldap_add($con, $dn, $entry);
		if ($r !== TRUE) {
			ldap_get_option($con, LDAP_OPT_ERROR_STRING, $e);
			$ret['errmsg'] = ldap_error($con) . ' [' . $e . ']';
			break;
		}

		$ret['ok'] = 1;
		break;
	}

	return $ret;
}

/*
 * ldap_delete wrapper
 */
function rg_ldap_core_del($con, $dn)
{
	$ret = array('ok' => 0);
	while (1) {
		$r = @ldap_delete($con, $dn);
		if ($r !== TRUE) {
			ldap_get_option($con, LDAP_OPT_ERROR_STRING, $e);
			$ret['errmsg'] = ldap_error($con) . ' [' . $e . ']';
			break;
		}

		$ret['ok'] = 1;
		break;
	}

	return $ret;
}

/*
 * LDAP search
 * @attr - array('mail', 'sn' etc.)
 * @attronly - 1 to return only the attr types (no values). Else 0.
 * @sizelimit - 0 = all entries
 * @timelimit - in seconds, 0 = unlimited
 * @deref - LDAP_DEREF_ NEVER SEARCHING FINDING ALWAYS
 */
function rg_ldap_core_search($con, $base_dn, $filter, $attr, $attronly,
	$sizelimit, $timelimit, $deref)
{
	rg_log_enter('ldap_core_search');

	$ret = array();
	$ret['ok'] = 0;
	while (1) {
		$r = @ldap_search($con, $base_dn, $filter, $attr, $attronly,
			$sizelimit, $timelimit, $deref);
		if ($r === FALSE) {
			ldap_get_option($con, LDAP_OPT_ERROR_STRING, $e);
			$ret['errmsg'] = ldap_error($con) . ' [' . $e . ']';
			break;
		}

		$ret['data'] = @ldap_get_entries($con, $r);
		if ($ret['data'] === FALSE) {
			ldap_get_option($con, LDAP_OPT_ERROR_STRING, $e);
			$ret['errmsg'] = ldap_error($con) . ' [' . $e . ']';
			break;
		}
		//rg_log_ml('DEBUG: entries: ' . print_r($ret['data'], TRUE));

		$ret['ok'] = 1;
		break;
	}

	rg_log_exit();
	return $ret;
}

/*
 * Implemet ldap_list here! TODO - must faster than search (subtree)
 * ldap_list (one level)
 */


/*
 * LDIF -> array
 * Returns how many bytes were processed.
 */
function rg_ldap_core_ldif2array($data)
{
	$ret = array();
	$ret['ok'] = 0;
	$ret['data'] = array();

	$i = 0;
	$off = 0;
	while (1) {
		rg_log('off=' . $off);
		$ret['used'] = $off;

		// Do we have more data in buffer?
		if (strlen(substr($data, $off, 1)) == 0) {
			rg_log('buffer is empty');
			$ret['ok'] = 1;
			break;
		}

		// Check if we have a full block
		$end = strpos($data, "\n\n", $off);
		if ($end === FALSE) {
			rg_log('cannot find another \n\n');
			$ret['ok'] = 1;
			break;
		}
		$end += 1; // we will point to the second \n
		rg_log('end = ' . $end);

		$error = FALSE;
		while (1) {
			rg_log('DEBUG: looping again, off=' . $off);
			if ($off === $end) {
				rg_log('off is at the end');
				$off = $end + 1;
				$i++;
				break;
			}

			$cr = strpos($data, "\n", $off);
			rg_log('cr is at pos ' . $cr);

			if (substr_compare($data, '#', $off, 1) == 0) {
				$off = $cr + 1;
				continue;
			}
			$sc = strpos($data, ':', $off);
			rg_log('sc = ' . $sc);

			if (($sc === FALSE) || ($cr < $sc)) {
				$ret['errmsg'] = 'entry without \':\' at offset ' . $off;
				$error = TRUE;
				break;
			}

			if (!isset($ret['data'][$i]))
				$ret['data'][$i] = array();

			$k = substr($data, $off, $sc - $off);
			rg_log('k=' . $k . '.');
			$v = substr($data, $sc + 1, $cr - $sc - 1);
			if (strncmp($v, ':', 1) == 0) {
				$v = base64_decode(substr($v, 1));
				if ($v === FALSE) {
					$ret['errmsg'] = 'base64 decode error at offset ' . $off;
					$error = TRUE;
					break;
				}
			} else if (strncmp($v, ' ', 1) == 0) {
				$v = substr($v, 1);
			} else {
				$ret['errmsg'] = 'invalid character after \':\' at offset ' . $off;
				$error = TRUE;
				break;
			}

			if (!isset($ret['data'][$i][$k]))
				$ret['data'][$i][$k] = array();
			$ret['data'][$i][$k][] = $v;
			$off = $cr + 1;
		}
		if ($error)
			break;
	}

	return $ret;
}

Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master