yannstatic/static/2019/09/26/PHP-connexion-et-administration-annuaire-LDAP.html

2799 lines
264 KiB
HTML
Raw Normal View History

2024-10-31 20:18:37 +01:00
<!DOCTYPE html><html lang="fr">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>PHP connexion et administration annuaire LDAP - YannStatic</title>
<meta name="description" content="PHP - Connexion à un annuaire LDAP">
<link rel="canonical" href="https://static.rnmkcy.eu/2019/09/26/PHP-connexion-et-administration-annuaire-LDAP.html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
<!-- - include head/favicon.html - -->
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
<!-- end custom head snippets --><script>(function() {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length; i++) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb && (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining <= 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length; i++) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length; i++) {
for (flag = false, j = 0; j < mData.length; j++) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length; i++) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi && (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length; j++) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag && cbs && cbs.length > 0) {
for (j = 0; j < cbs.length; j++) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length; i++) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback && (qi.load || qi.callbacks.push(callback));
callback && (qi.load && callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length; i++) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) && (node = createNode('script', { src: url }));
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
</script><script>
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
jquery: '/assets/js/jquery.min.js',
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
gitalk: {
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
},
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
</script>
</head>
<body>
<div class="root" data-is-touch="false">
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
<div class="header__title">
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
<!-- Champ de recherche -->
<div id="searchbox" class="search search--dark" style="visibility: visible">
<div class="main">
<div class="search__header"></div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<!-- <div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div> -->
</div>
</div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date}&nbsp;{title}</a></li>'
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a></li>'
})
</script>
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
2024-11-28 11:42:23 +01:00
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/syntaxe-markdown.html">Aide</a></li></ul>
2024-10-31 20:18:37 +01:00
</nav></div>
</header>
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">PHP connexion et administration annuaire LDAP</h1></header></div><meta itemprop="headline" content="PHP connexion et administration annuaire LDAP"><div class="article__info clearfix"><ul class="left-col menu"><li>
2024-11-08 14:10:33 +01:00
<a class="button button--secondary button--pill button--sm" style="color:#00FFFF" href="/archive.html?tag=serveur">serveur</a>
2024-10-31 20:18:37 +01:00
</li></ul><ul class="right-col menu"><li>
<i class="far fa-calendar-alt"></i>&nbsp;<span title="Création" style="color:#FF00FF">26&nbsp;sept.&nbsp;2019</span></li></ul></div><meta itemprop="datePublished" content="2019-09-26T00:00:00+02:00">
<meta itemprop="keywords" content="serveur"><div class="js-article-content">
<div class="layout--article"><!-- start custom article top snippet -->
<style>
#myBtn {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 99;
font-size: 12px;
font-weight: bold;
border: none;
outline: none;
background-color: white;
color: black;
cursor: pointer;
padding: 5px;
border-radius: 4px;
}
#myBtn:hover {
background-color: #555;
}
</style>
<button onclick="topFunction()" id="myBtn" title="Haut de page">&#8679;</button>
<script>
//Get the button
var mybutton = document.getElementById("myBtn");
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
<!-- end custom article top snippet -->
<div class="article__content" itemprop="articleBody"><details>
<summary><b>Afficher/cacher Sommaire</b></summary>
<!-- affichage sommaire -->
<div class="toc-aside js-toc-root"></div>
</details><h2 id="php---connexion-à-un-annuaire-ldap">PHP - Connexion à un annuaire LDAP</h2>
<h3 id="introduction-à-ldap">Introduction à LDAP</h3>
<p>PHP permet la connexion et lenvoi de requêtes sur un annuaire LDAP, cest-à-dire un serveur permettant de stocker des informations de manière hiérarchique.</p>
<p>Un serveur LDAP est conçu pour être capable de gérer les opérations suivantes :</p>
<ul>
<li>établir la connexion avec lannuaire</li>
<li>rechercher des entrées</li>
<li>comparer des entrées</li>
<li>ajouter des entrées</li>
<li>modifier des entrées</li>
<li>supprimer des entrées</li>
<li>annuler ou abandonner une opération</li>
<li>fermer la connexion avec lannuaire</li>
</ul>
<p>Ainsi PHP fournit un ensemble de fonctions (pour peu que le module LDAP soit installé)
permettant de réaliser ces opérations. Ces fonctions seront explicitées au long de larticle.</p>
<p>Avant de commencer, il faut installer le module LDAP pour le langage PHP. Ce module ajoute un certain nombre de fonctions qui débutent par « ldap_ » et qui permettent dinterfacer le serveur.</p>
<h3 id="séquence-dinterrogation-avec-ldap">Séquence dinterrogation avec LDAP</h3>
<p>Linterrogation dun serveur LDAP avec PHP se fait selon une séquence simple,
nécessitant un nombre peu élevé de fonctions spécialisées. La séquence basique est la suivante :</p>
<ul>
<li>Etablissement de la connexion avec le serveur LDAP</li>
<li>Liaison et authentification sur le serveur (appelé bind en anglais)</li>
<li>Recherche dune entrée (ou bien une autre opération)</li>
<li>Exploitation des résultats (uniquement dans le cas dune recherche)</li>
<li>Fermeture de la connexion</li>
</ul>
<h3 id="connexion-au-serveur-ldap">Connexion au serveur LDAP</h3>
<p>Avant de pouvoir interroger le serveur LDAP, il est essentiel dinitier la connexion.
Pour cela linterpréteur PHP a besoin de connaître quelques renseignements
relatifs à lannuaire :</p>
<ul>
<li>Ladresse du serveur</li>
<li>Le port sur lequel le serveur fonctionne</li>
<li>La racine de lannuaire</li>
<li>Le login de lutilisateur (généralement root) ainsi que son mot de passe</li>
</ul>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// Fichier de configuration pour l'interface PHP</span>
<span class="c1">// de notre annuaire LDAP</span>
<span class="nv">$server</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">;</span>
<span class="nv">$port</span> <span class="o">=</span> <span class="s2">"389"</span><span class="p">;</span>
<span class="nv">$racine</span> <span class="o">=</span> <span class="s2">"o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$rootdn</span> <span class="o">=</span> <span class="s2">"cn=ldap_admin, o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$rootpw</span> <span class="o">=</span> <span class="s2">"secret"</span><span class="p">;</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<p>On définit donc cinq variables pour caractériser le serveur LDAP :
le nom du serveur, le port (389 par défaut), la racine supérieure de larborescence, la chaîne de connexion pour ladministrateur ainsi que son mot de passe.</p>
<p>La première fonction à utiliser est la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code> permettant détablir
une liaison avec le serveur. Sa syntaxe est la suivante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_connect ([string hostname [, int port]])
</code></pre></div></div>
<p>Cette fonction admet en paramètre le nom du serveur (éventuellement le port. Par défaut le port est 389). En cas déchec cette fonction retourne 0 sinon elle retourne un entier permettant didentifier le serveur et nécessaire dans les fonctions suivantes.</p>
<p>Voici un exemple de connexion au serveur :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="k">echo</span> <span class="s2">"Connexion...&lt;br&gt;"</span><span class="p">;</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<p>Toutefois cette opération nest pas suffisante pour pouvoir exécuter des opérations sur le serveur LDAP. En effet, il est nécessaire dinitier la liaison (en anglais <strong>to bind</strong>) avec le serveur LDAP à laide de la fonction <code class="language-plaintext highlighter-rouge">ldap_bind()</code> dont la syntaxe est la suivante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_bind (int identifiant [, string bind_rdn [, string bind_password]])
</code></pre></div></div>
<p>Cette fonction attend en paramètre lidentifiant du serveur retourné ainsi quéventuellement le Nom distingué relatif de lutilisateur (<em>RDN - Relative Distinguished Name</em>) et son mot de passe. Si lutilisateur et le mot de passe ne sont pas précisés, la connexion se fait de manière anonyme.</p>
<p>La déconnexion du serveur LDAP se fait tout naturellement par la fonction <code class="language-plaintext highlighter-rouge">ldap_close()</code> avec la syntaxe suivante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_close (int identifiant)
</code></pre></div></div>
<p>Cette fonction est similaire à la fonction <code class="language-plaintext highlighter-rouge">ldap_unbind()</code>.</p>
<p>Voici un exemple complet de connexion et de déconnexion à un serveur LDAP :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// Fichier de configuration pour l'interface PHP</span>
<span class="c1">// de notre annuaire LDAP</span>
<span class="nv">$server</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">;</span>
<span class="nv">$port</span> <span class="o">=</span> <span class="s2">"389"</span><span class="p">;</span>
<span class="nv">$racine</span> <span class="o">=</span> <span class="s2">"o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$rootdn</span> <span class="o">=</span> <span class="s2">"cn=ldap_admin, o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$rootpw</span> <span class="o">=</span> <span class="s2">"secret"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"Connexion...&lt;br&gt;"</span><span class="p">;</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// on s'authentifie en tant que super-utilisateur, ici, ldap_admin</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// Ici les opérations à effectuer</span>
<span class="k">echo</span> <span class="s2">"Déconnexion...&lt;br&gt;"</span><span class="p">;</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Impossible de se connecter au serveur LDAP"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="exécution-des-opérations">Exécution des opérations</h3>
<h4 id="ajouter-une-entrée-avec-ldap_add">Ajouter une entrée avec ldap_add()</h4>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_add()</code> permet dajouter des entrées à un annuaire LDAP
auquel on sest préalablement connecté (et lié). Voici sa syntaxe :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_add (int identifiant, string dn, array entry)
</code></pre></div></div>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_add()</code> admet en paramètre lidentifiant du serveur LDAP retourné par la fonction
<code class="language-plaintext highlighter-rouge">ldap_connect()</code> ainsi que le nom distingué de lentrée (cest-à-dire son emplacement dans lannuaire) et un tableau contenant lensemble des valeurs des attributs de lentrée.</p>
<p>Lorsquun attribut est multivalué (cest-à-dire lorsquun attribut est lui-même composé de plusieurs valeurs), celles-ci sont indexées dans une case du tableau (les indices du tableau commencent à 0). Dans lexemple ci-dessous par exemple, lattribut “mail” possède plusieurs valeurs :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span> <span class="c1">// On suppose que le serveur LDAP est sur cet hote</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// preparation des données</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"cn"</span><span class="p">]</span><span class="o">=</span><span class="s2">"Pillou"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"sn"</span><span class="p">]</span><span class="o">=</span><span class="s2">"Jean-Francois"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"mail"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="s2">"webmaster@commentcamarche.net"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"mail"</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="s2">"Jeff@commentcamarche.net"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"objectclass"</span><span class="p">]</span><span class="o">=</span><span class="s2">"person"</span><span class="p">;</span>
<span class="c1">// Ajout des données dans l'annuaire</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_add</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="s2">"cn=Jean-Francois Pillou, o=commentcamarche, c=fr"</span><span class="p">,</span> <span class="nv">$entry</span><span class="p">);</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h4 id="comparer-une-entrée-avec-ldap_compare">Comparer une entrée avec ldap_compare()</h4>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_compare()</code> permet de comparer la valeur dun attribut dune entrée de lannuaire LDAP, auquel on sest préalablement connecté (et lié), à une valeur passée en paramètre. Voici la syntaxe de la fonction ldap_compare() :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_compare (int identifiant, string dn, string attribut, string valeur)
</code></pre></div></div>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_compare()</code> admet en paramètre lidentifiant du serveur LDAP retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code>, le nom distingué de lentrée (cest-à-dire son emplacement dans lannuaire) ainsi que le nom de lattribut de lentrée et la valeur à laquelle on veut comparer sa valeur dans lannuaire.</p>
<p>En cas derreur, la fonction <code class="language-plaintext highlighter-rouge">ldap_compare()</code> renvoie la valeur -1, en cas de réussite elle renvoie TRUE, enfin dans le cas contraire elle renvoie FALSE.</p>
<p>Lexemple suivant (largement inspiré de celui de www.php.net) montre comment comparer un mot de passe avec celui stocké dans lannuaire pour un utilisateur donné :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// preparation des données</span>
<span class="nv">$dn</span><span class="o">=</span><span class="s2">"cn=Pillou Jean-Francois, o=commentcamarche,c=fr"</span><span class="p">;</span>
<span class="nv">$valeur</span><span class="o">=</span><span class="s2">"MonMot2Passe"</span><span class="p">;</span>
<span class="nv">$attribut</span><span class="o">=</span><span class="s2">"password"</span><span class="p">;</span>
<span class="c1">// Comparaison du mot de passe à celui dans l'annuaire</span>
<span class="nv">$resultat</span><span class="o">=</span><span class="nb">ldap_compare</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$dn</span><span class="p">,</span> <span class="nv">$attribut</span><span class="p">,</span> <span class="nv">$valeur</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$resultat</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Erreur:"</span><span class="mf">.</span><span class="nb">ldap_error</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">elseif</span> <span class="p">(</span><span class="nv">$resultat</span> <span class="o">==</span> <span class="kc">TRUE</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Le mot de passe est correct"</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">(</span><span class="nv">$resultat</span> <span class="o">==</span> <span class="kc">FALSE</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Le mot de passe est erronné..."</span><span class="p">;</span>
<span class="p">}</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<blockquote>
<p>Notez lutilisation de la fonction <code class="language-plaintext highlighter-rouge">ldap_error()</code> sur laquelle nous reviendrons ultérieurement pour afficher les détails de lerreur !</p>
</blockquote>
<h3 id="supprimer-une-entrée-avec-ldap_delete">Supprimer une entrée avec ldap_delete()</h3>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_delete()</code> permet de supprimer des entrées dun annuaire LDAP. Voici sa syntaxe :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_delete (int identifiant, string dn)
</code></pre></div></div>
<p>La fonction ldap_delete() admet uniquement deux paramètres :</p>
<ul>
<li>lidentifiant du serveur LDAP retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code></li>
<li>le nom distingué de lentrée à supprimer.</li>
</ul>
<p>Une fois de plus, cette fonction renvoie <em>TRUE</em> en cas de réussite, <code class="language-plaintext highlighter-rouge">FALSE</code> en cas déchec.</p>
<p>Lexemple suivant illustre la suppression dun élément de lannuaire :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span> <span class="c1">// On suppose que le serveur LDAP est sur cet hote</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// preparation des données</span>
<span class="nv">$dn</span><span class="o">=</span><span class="s2">"Pillou Jean-Francois,o=commentcamarche,c=fr"</span><span class="p">;</span>
<span class="c1">// Supression de l'entrée de l'annuaire</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_delete</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$dn</span><span class="p">);</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="modifier-une-entrée-avec-ldap_modify">Modifier une entrée avec ldap_modify()</h3>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_modify()</code> permet de modifier une entrée de lannuaire LDAP. Sa syntaxe est la même que celle de la fonction ldap_add() :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_modify (int identifiant, string dn, array entry)
</code></pre></div></div>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_modify()</code> admet en paramètre lidentifiant du serveur LDAP retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code> ainsi que le nom distingué de lentrée (cest-à-dire son emplacement dans lannuaire) et un tableau contenant lensemble des valeurs des attributs de lentrée à modifier.</p>
<p>Lorsquun attribut est multivalué (cest-à-dire lorsquun attribut est lui-même composé de plusieurs valeurs), celles-ci sont indexées dans une case du tableau (les indices du tableau commencent à 0). Dans lexemple ci-dessous par exemple, lattribut
“mail” possède plusieurs valeurs :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span> <span class="c1">// On suppose que le serveur LDAP est sur cet hote</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// preparation des données</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"cn"</span><span class="p">]</span><span class="o">=</span><span class="s2">"Pillou"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"sn"</span><span class="p">]</span><span class="o">=</span><span class="s2">"Jean-Francois"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"mail"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="s2">"webmaster@commentcamarche.net"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"mail"</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="s2">"Jeff@commentcamarche.net"</span><span class="p">;</span>
<span class="nv">$entry</span><span class="p">[</span><span class="s2">"objectclass"</span><span class="p">]</span><span class="o">=</span><span class="s2">"person"</span><span class="p">;</span>
<span class="c1">// Ajout des données dans l'annuaire</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_modify</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="s2">"cn=Jean-Francois Pillou, o=commentcamarche, c=fr"</span><span class="p">,</span> <span class="nv">$entry</span><span class="p">);</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="rechercher-une-entrée-avec-ldap_search">Rechercher une entrée avec ldap_search()</h3>
<p>La recherche dentrée dans lannuaire est sans aucun doute la fonction la plus utile
parmi les fonctions LDAP de PHP¨car un annuaire est prévu pour être plus souvent
sollicité en lecture (recherche) quen écriture (ajout/suppression/modification).</p>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code> permet de rechercher une ou plusieurs entrées de lannuaire LDAP à laide du DN de base, cest-à-dire le niveau de lannuaire à partir duquel la recherche est effectuée, ainsi quun filtre représentant le type de recherche que lon désire effectuer. Sa syntaxe est la suivante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_search (int identifiant, string base_dn,
string filter [, array attributs [, int attrsonly [,
int sizelimit [, int timelimit [, int deref]]]]])
</code></pre></div></div>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code> admet en paramètre lidentifiant du serveur LDAP retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code> ainsi que le nom distingué du dossier de base (cest-à-dire celui à partir duquel la recherche doit seffectuer) et le filtre de la recherche. La fonction ldap_search() est par défaut configurée avec loption de récursivité <strong><em>LDAP_SCOPE_SUBTREE</em></strong> ce qui signifie que la recherche se fait dans toutes les branches filles du dossier de base.</p>
<p>Le paramètre <strong><em>attributs</em></strong> permet de restreindre les attributs et les valeurs retournées, cest-à-dire quil sagit dun tableau contenant le nom des attributs (chaînes de caractères) des attributs que lon désire utiliser. Par défaut lintégralité des attributs des entrées est renvoyée par le serveur, ce qui peut donner un nombre de données très important.</p>
<p>Le paramètre <strong><em>attrsonly</em></strong> permet de demander à lannuaire de retourner uniquement les types dattributs et non leurs valeurs lorsquil vaut 1. Par défaut (ou lorsque ce paramètre vaut 0) les types des attributs ainsi que leurs valeurs sont retournés par le serveur.</p>
<p>Le sixième paramètre <strong><em>sizelimit</em></strong> comme son nom lindique permet de limiter le nombre maximum de résultat retourné par lannuaire afin de réduire le volume des données retournées. Il faut noter que si le serveur est configuré pour retourner moins de résultats, une valeur supérieure de lattribut ne permettra pas de dépasser la valeur inscrite dans la configuration du serveur. La valeur <strong><em>0</em></strong> indique quaucune limite autre que celle imposée par le serveur nest définie.</p>
<p>Le septième paramètre <strong><em>timelimit</em></strong> permet de limiter le temps maximal de la recherche pris par le serveur. Il faut noter que si le serveur est configuré pour retourner moins de résultats, une valeur supérieure de lattribut ne permettra pas de dépasser la valeur inscrite dans la configuration du serveur. La valeur 0 indique quaucune limite autre que celle imposée par le serveur nest définie.</p>
<p>Enfin le huitième paramètre <strong><em>deref</em></strong> permet dindiquer selon sa valeur la façon de procéder avec les alias lors de la recherche. Les valeurs possibles de ce paramètre sont les suivantes :</p>
<ul>
<li><strong><em>LDAP_DEREF_NEVER</em></strong> : les alias ne sont jamais déréférencés. Il sagit de la valeur par défaut.</li>
<li><strong><em>LDAP_DEREF_SEARCHING</em></strong> : les alias sont déréférencés uniquement pendant la recherche et non pendant leur localisation.</li>
<li><strong><em>LDAP_DEREF_FINDING</em></strong> : les alias sont déréférencés uniquement pendant leur localisation et non lors de la recherche.</li>
<li><strong><em>LDAP_DEREF_ALWAYS</em></strong> : les alias sont toujours déréférencés.</li>
</ul>
<p>Lexemple suivant permet de connaître le nombre de résultats retournés pour une recherche dune personne dont le nom ou le prenom commence par la chaîne $person passée en paramètre :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span> <span class="c1">// On suppose que le serveur LDAP est sur cet hote</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="nv">$dn</span> <span class="o">=</span> <span class="s2">"o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$filtre</span><span class="o">=</span><span class="s2">"(|(sn=</span><span class="nv">$person</span><span class="s2">*)(cn=</span><span class="nv">$person</span><span class="s2">*))"</span><span class="p">;</span>
<span class="nv">$restriction</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span> <span class="s2">"cn"</span><span class="p">,</span> <span class="s2">"sn"</span><span class="p">,</span> <span class="s2">"mail"</span><span class="p">);</span>
<span class="nv">$sr</span><span class="o">=</span><span class="nb">ldap_search</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$dn</span><span class="p">,</span> <span class="nv">$filtre</span><span class="p">,</span> <span class="nv">$restriction</span><span class="p">);</span>
<span class="nv">$info</span> <span class="o">=</span> <span class="nb">ldap_get_entries</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$sr</span><span class="p">);</span>
<span class="k">print</span> <span class="nv">$info</span><span class="p">[</span><span class="s2">"count"</span><span class="p">]</span><span class="mf">.</span><span class="s2">" enregistrements trouves
"</span><span class="p">;</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<p>Toutefois, une fois lopération de recherche effectuée, il sagit dexploiter les résultats obtenus. Ainsi, la majeure partie des fonctions LDAP ont pour but le traitement des résultats de la recherche.</p>
<p>Dans lexemple ci-dessus, la fonction <code class="language-plaintext highlighter-rouge">ldap_get_entries()</code> permet de récupérer des informations sur les entrées retournées par la fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code>.</p>
<h3 id="traitement-des-résultats">Traitement des résultats</h3>
<p>De nombreuses fonctions LDAP permettent dexploiter les résultats renvoyés
par la fonction ldap_search(). Ces fonctions ont un nom commençant généralement par</p>
<p><code class="language-plaintext highlighter-rouge">ldap_get_</code> suivi du nom de lélément à récupérer :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">ldap_get_dn()</code> permet de récupérer le DN de lentrée</li>
<li><code class="language-plaintext highlighter-rouge">ldap_get_entries()</code> permet de récupérer lensemble des entrées</li>
<li><code class="language-plaintext highlighter-rouge">ldap_get_option()</code> permet de récupérer la valeur dune option</li>
<li><code class="language-plaintext highlighter-rouge">ldap_get_values()</code> permet de récupérer toutes les valeurs dune entrée</li>
<li><code class="language-plaintext highlighter-rouge">ldap_get_values_len()</code> permet de récupérer les valeurs binaires dune entrée</li>
<li><code class="language-plaintext highlighter-rouge">ldap_count_entries()</code> permet de récupérer le nombre dentrées retournées par la fonction de recherche</li>
</ul>
<h3 id="récupérer-le-nombre-dentrées-retournées">Récupérer le nombre dentrées retournées</h3>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_count_entries()</code> permet de connaître le nombre dentrées retournées par la fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code>. Sa syntaxe est la suivante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int ldap_count_entries (int link_identifier, int result_identifier)
</code></pre></div></div>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_count_entries()</code> admet en paramètre lidentifiant du serveur LDAP retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code> ainsi que lidentifiant du résultat retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code> et retourne un entier représentant le nombre dentrées stockées dans le résultat de la recherche.</p>
<p>Voici un exemple dutilisation :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span> <span class="c1">// On suppose que le serveur LDAP est sur cet hote</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="nv">$dn</span> <span class="o">=</span> <span class="s2">"o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$filtre</span><span class="o">=</span><span class="s2">"(|(sn=</span><span class="nv">$person</span><span class="s2">*)(cn=</span><span class="nv">$person</span><span class="s2">*))"</span><span class="p">;</span>
<span class="nv">$restriction</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span> <span class="s2">"cn"</span><span class="p">,</span> <span class="s2">"sn"</span><span class="p">,</span> <span class="s2">"mail"</span><span class="p">);</span>
<span class="nv">$sr</span><span class="o">=</span><span class="nb">ldap_search</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$dn</span><span class="p">,</span> <span class="nv">$filtre</span><span class="p">,</span> <span class="nv">$restriction</span><span class="p">);</span>
<span class="nv">$nombre</span> <span class="o">=</span> <span class="nb">ldap_count_entries</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$sr</span><span class="p">);</span>
<span class="k">print</span> <span class="nv">$nombre</span><span class="mf">.</span><span class="s2">" enregistrements trouves
"</span><span class="p">;</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="récupérer-les-entrées-retournées">Récupérer les entrées retournées</h3>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_get_entries()</code> permet de récupérer lensemble des entrées retournées par la fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code> ainsi que de lire les attributs associés et leur(s) valeur(s).</p>
<p>Sa syntaxe est la suivante :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>array ldap_get_entries (int link_identifier, int result_identifier)
</code></pre></div></div>
<p>La fonction <code class="language-plaintext highlighter-rouge">ldap_get_entries()</code> admet en paramètre lidentifiant du serveur LDAP retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_connect()</code> ainsi que lidentifiant du résultat retourné par la fonction <code class="language-plaintext highlighter-rouge">ldap_search()</code> et retourne un tableau multidimensionnel contenant le résultat de la recherche, cest-à-dire le DN et le nom de lentrée ainsi que la ou les valeurs de chacune dentre-elles.</p>
<p>La structure du tableau retourné (on supposera quil se trouve dans la variable $entrees) est la suivante :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">$entrees["count"]</code> : nombre dentrées dans le résultat</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[0]</code> : détail de la première entrée</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[i]["dn"]</code> : DN de la ième entrée</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[i]["count"]</code> : nombre dattributs de la ième entrée</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[i][j]</code> : valeur du jème attribut de la ième entrée</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[i]["attribut"]</code> : valeur de lattribut nommé “attribut” de la ième entrée (pour un attribut multivalué)</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[i]["attribut"]["count"]</code> : Nombre de valeurs du jème attribut de la ième entrée (pour un attribut multivalué)</li>
<li><code class="language-plaintext highlighter-rouge">$entrees[i]["attribut"][j]</code> : Jème valeur de lattribut nommé “attribut” de la ième entrée (pour un attribut multivalué)</li>
</ul>
<blockquote>
<p>Les noms des attributs dans le tableau associatif sont en minuscules, ainsi lattribut givenName devra être écrit givenname (par exemple <code class="language-plaintext highlighter-rouge">$entrees[i]["givenname"]</code>)</p>
</blockquote>
<p>Voici un exemple dutilisation :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span> <span class="c1">// On suppose que le serveur LDAP est sur cet hote</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="nv">$dn</span> <span class="o">=</span> <span class="s2">"o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$filtre</span><span class="o">=</span><span class="s2">"(|(sn=</span><span class="nv">$person</span><span class="s2">*)(cn=</span><span class="nv">$person</span><span class="s2">*))"</span><span class="p">;</span>
<span class="nv">$restriction</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span> <span class="s2">"cn"</span><span class="p">,</span> <span class="s2">"sn"</span><span class="p">,</span> <span class="s2">"mail"</span><span class="p">);</span>
<span class="nv">$sr</span> <span class="o">=</span> <span class="nb">ldap_search</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$dn</span><span class="p">,</span> <span class="nv">$filter</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"Le nombre d'entrées retourné est de "</span><span class="mf">.</span><span class="nb">ldap_count_entries</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$sr</span><span class="p">)</span><span class="mf">.</span><span class="s2">"&lt;br&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"Récupération des entrées ..."</span><span class="p">;</span>
<span class="nv">$info</span> <span class="o">=</span> <span class="nb">ldap_get_entries</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$sr</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"Affichage des données des "</span><span class="mf">.</span><span class="nv">$info</span><span class="p">[</span><span class="s2">"count"</span><span class="p">]</span><span class="mf">.</span> <span class="s2">" entrées trouvées :"</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span><span class="o">&lt;</span><span class="nv">$info</span><span class="p">[</span><span class="s2">"count"</span><span class="p">];</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">echo</span> <span class="s2">"&lt;p align="</span><span class="n">justify</span><span class="s2">"&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"Le dn (Distinguished Name) est: "</span><span class="mf">.</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"dn"</span><span class="p">]</span> <span class="mf">.</span><span class="s2">"&lt;br&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"Nom (sn) : "</span><span class="mf">.</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"sn"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="mf">.</span> <span class="s2">"&lt;br&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"Prénom (cn) : "</span><span class="mf">.</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"cn"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="mf">.</span> <span class="s2">"&lt;br&gt;"</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="nv">$j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="nv">$j</span><span class="o">&lt;</span><span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"mail"</span><span class="p">][</span><span class="s2">"count"</span><span class="p">];</span><span class="nv">$j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Email numéro </span><span class="nv">$j</span><span class="s2">: "</span><span class="mf">.</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span> <span class="s2">"mail"</span><span class="p">][</span><span class="nv">$j</span><span class="p">]</span> <span class="mf">.</span><span class="s2">"&lt;br&gt;"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">echo</span> <span class="s2">"&lt;p&gt; ... Fermeture de la connexion"</span><span class="p">;</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Connexion au serveur LDAP impossible"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<blockquote>
<p>Notez que pour récupérer uniquement le nombre de résultats total, il est préférable dutiliser la fonction <code class="language-plaintext highlighter-rouge">ldap_count_entries()</code> que de passer par la fonction <code class="language-plaintext highlighter-rouge">ldap_get_entries()</code> puis <code class="language-plaintext highlighter-rouge">$entrees["count"]</code></p>
</blockquote>
<h2 id="php---administration-dun-annuaire-ldap">PHP - Administration dun annuaire LDAP</h2>
<h3 id="introduction-à-ldap-1">Introduction à LDAP</h3>
<p>PHP permet la connexion et lenvoi de requêtes sur un annuaire LDAP, cest-à-dire un serveur permettant de stocker des informations de manière hiérarchique.</p>
<p>Dans le cadre de cet article, on se propose décrire un <u>interface d'administration</u>
pour un annuaire. On va prévoir les actions de base, cest à dire :<br />
<strong>ajouter, modifier et supprimer des éléments de notre annuaire LDAP</strong>.<br />
Naturellement chacun à une action précise. Il y aura donc une page principale qui affichera les personnes contenues dans lannuaire et qui proposera les différentes actions associées aux objets.</p>
<p>Dans chaque module, on va avoir besoin dun certain nombre de variables qui caractérisent le serveur LDAP. On va donc créer un fichier de configuration externe qui sera chargé au démarrage de chaque module. De cette façon, lorsque vous voulez installer votre application sur une autre plate-forme, vous ne devez modifier que ce fichier de configuration.</p>
<p>De plus, on va prévoir la possibilité de modifier le modèle daffichage,
cest à dire lapparence de votre interface. On utilisera donc deux fichiers :</p>
<ul>
<li>header.php : qui définira le haut de page de notre interface</li>
<li>footer.php : qui définira le bas de page de notre interface</li>
</ul>
<h3 id="sécurisation-de-linterface">Sécurisation de linterface</h3>
<p>On supposera que lensemble des pages PHP créées dans ce tutorial se trouvent
sous le répertoires <strong>ldap_admin/</strong></p>
<p>Nous allons donc protéger le répertoire <strong>ldap_admin/</strong> qui contiendra les pages dadministration de notre annuaire. Chaque utilisateur qui voudra accéder à ces pages devra sauthentifier. Nous utilisons la méthode des fichiers <strong>.htaccess</strong></p>
<p>On va ainsi définir que seul lutilisateur <em>ldap_admin</em> peut accéder à linterface dadministration du forum. On va dans un premier temps créer le fichier des utilisateurs.</p>
<p>Placez-vous dans le répertoire ldap_admin et exécuter la commande suivante pour créer ce fichier (pour les utilisateurs de Linux) :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>htpasswd -c ldap_admin.passwd ldap_admin
</code></pre></div></div>
<blockquote>
<p>Remarque : le nom de ce fichier na aucune importance. Loption -c correspond à la création du fichier.</p>
</blockquote>
<p>On va alors avoir à rentrer un mot de passe pour lutilisateur: ldap_admin autorisé à accéder au répertoire protégé.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>New password:
</code></pre></div></div>
<p>On confirme.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Re-type new password:
</code></pre></div></div>
<p>Une fois que le fichier des utilisateurs est généré, on va créer le fichier <strong>.htaccess</strong> qui sera stocké dans le répertoire à protéger, ici <strong>ldap_admin/</strong></p>
<p>On protège aussi le fichier de configuration :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;Files config_LDAP.inc.php&gt;
Order Deny,Allow
Deny From All
&lt;/Files&gt;
AuthUserFile /home/httpd/html/services/ldap_admin/ldap_admin.passwd
AuthName "Acces Restreint"
AuthType Basic
&lt;Limit GET POST&gt;
require valid-user
&lt;/Limit&gt;
</code></pre></div></div>
<p>La sécurisation de notre interface est maintenant terminée.</p>
<h3 id="fichier-de-configuration">Fichier de configuration</h3>
<p>Commençons par commenter le fichier de configuration nommé <strong>config_LDAP.inc.php</strong> :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// Fichier de configuration pour l'interface PHP pour administrer</span>
<span class="c1">// notre annuaire LDAP</span>
<span class="nv">$server</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">;</span>
<span class="nv">$port</span> <span class="o">=</span> <span class="s2">"389"</span><span class="p">;</span>
<span class="nv">$racine</span> <span class="o">=</span> <span class="s2">"o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$rootdn</span> <span class="o">=</span> <span class="s2">"cn=ldap_admin, o=commentcamarche, c=fr"</span><span class="p">;</span>
<span class="nv">$rootpw</span> <span class="o">=</span> <span class="s2">"secret"</span><span class="p">;</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<p>On définit donc cinq variables pour caractériser le serveur LDAP :</p>
<ol>
<li>le nom du serveur</li>
<li>le port (389 par défaut)</li>
<li>la racine supérieure de larborescence</li>
<li>la chaîne de connexion pour ladministrateur</li>
<li>ainsi que son mot de passe.</li>
</ol>
<p>Le fichier de configuration sera automatiquement appelé par le fichier <strong>header.php</strong>
qui définit le haut de notre interface.</p>
<h3 id="linterface-phpldap">Linterface PHP/LDAP</h3>
<p>Détaillons maintenant le fichier <strong>admin.php</strong> qui est la page principale de notre interface.</p>
<p>Cette page liste les personnes saisies dans lannuaire et propose soit de les modifier soit de les supprimer. Elle propose aussi un lien en bas de page pour ajouter une nouvelle
personne.</p>
<p>Du point du vue du code source, elle ne comporte aucune grosse complexité.</p>
<ul>
<li>En début de programme, le fichier <strong>header.php</strong>, qui décrit le haut de page de linterface, est chargé. Ce même fichier charge automatiquement le fichier de configuration <strong>config_LDAP.inc.php</strong>.</li>
<li>Le fichier <strong>footer.php</strong>, utilisé pour le bas de page est chargé à la fin.</li>
</ul>
<p>La connexion au serveur LDAP est réalisée grâce à la fonction <code class="language-plaintext highlighter-rouge">ldap_connect</code>.</p>
<p>Ensuite, la fonction <code class="language-plaintext highlighter-rouge">ldap_search</code> permet de rechercher tous les objets de type <em>person</em> et de les afficher avec une boucle de type « for » sous la forme dun tableau en ajoutant deux liens qui correspondent respectivement à la modification et à la suppression.</p>
<p>Pour la modification, la page <strong>modifie.php</strong> est appelée. On lui passe en paramètre la valeur de <em>cn</em> contenue dans lannuaire, qui correspond au nom concaténé au prénom.</p>
<p>La même chose est réalisée pour le lien concernant la suppression sauf que la page <strong>supprime.php</strong> est appelée.</p>
<p>Le paramètre <em>cn</em> est encodé avec la fonction <code class="language-plaintext highlighter-rouge">urlencode()</code> de façon à transformer cette chaîne de caractère en une chaîne compatible avec le format des URL. Ainsi les espaces seront par exemple remplacés par des « + ».</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>admin.php
</code></pre></div></div>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// affichage du haut de la page contenu dans le fichier header.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"header.php"</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"Les personnes suivantes sont inscrites dans l'annuaire :&lt;p&gt;"</span><span class="p">;</span>
<span class="c1">// connexion au serveur LDAP : ds est égal à 1 si la connexion est OK</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// on recherche les objet de type person à partir de la racine</span>
<span class="c1">// de notre serveur LDAP, ici : o=commentcamarche, c=fr</span>
<span class="nv">$sr</span><span class="o">=</span><span class="nb">ldap_search</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$racine</span><span class="p">,</span> <span class="s2">"objectclass=person"</span><span class="p">);</span>
<span class="nv">$info</span> <span class="o">=</span> <span class="nb">ldap_get_entries</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$sr</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"&lt;table border=1&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;tr&gt;
&lt;th&gt;Nom et prénom&lt;/th&gt;
&lt;th&gt;Adresse e-Mail &lt;/th&gt;
&lt;th&gt;Téléphone&lt;/th&gt;
&lt;/tr&gt;"</span><span class="p">;</span>
<span class="c1">// on affiche sous forme d'un tableau les personnes enregistrées</span>
<span class="c1">// dans l'annuaire avec un lien pour modifier et un lien pour supprimer</span>
<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="nv">$i</span><span class="o">&lt;</span><span class="nv">$info</span><span class="p">[</span><span class="s2">"count"</span><span class="p">];</span><span class="nv">$i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$mynom</span> <span class="o">=</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"cn"</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$myemail</span> <span class="o">=</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"mail"</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$mytel</span> <span class="o">=</span> <span class="nv">$info</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s2">"telephonenumber"</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="k">echo</span><span class="s2">" &lt;tr&gt;&lt;th&gt;</span><span class="nv">$mynom</span><span class="s2">&lt;/th&gt;&lt;th&gt;
&lt;A HREF=mailto:</span><span class="nv">$myemail</span><span class="s2">&gt;</span><span class="nv">$myemail</span><span class="s2">&lt;/a&gt;&lt;/th&gt;&lt;th&gt;</span><span class="nv">$mytel</span><span class="s2">&lt;/th&gt;"</span><span class="p">;</span>
<span class="nv">$mynom</span><span class="o">=</span><span class="nb">urlencode</span><span class="p">(</span><span class="nv">$mynom</span><span class="p">);</span>
<span class="k">echo</span><span class="s2">" &lt;th&gt;&lt;a href=</span><span class="se">\"</span><span class="s2">modifie.php?cn=</span><span class="nv">$mynom</span><span class="se">\"</span><span class="s2">&gt;
Modifier&lt;/a&gt;&lt;/th&gt;"</span><span class="p">;</span>
<span class="k">echo</span><span class="s2">" &lt;th&gt;&lt;a href=</span><span class="se">\"</span><span class="s2">supprime.php?cn=</span><span class="nv">$mynom</span><span class="se">\"</span><span class="s2">&gt;
Supprimer&lt;/a&gt;&lt;/th&gt;&lt;/tr&gt;"</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">echo</span><span class="s2">"&lt;/table&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt; br&gt;&lt;a href=</span><span class="se">\"</span><span class="s2">ajoute.php</span><span class="se">\"</span><span class="s2">&gt;Ajouter une
nouvelle personne dans l'annuaire&lt;/a&gt;&lt;/center&gt;"</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// on ferme la connexion au serveur LDAP</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="c1">// on affiche le bas de page défini dans le fichier footer.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"footer.php"</span><span class="p">);</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="ajout-dune-entrée-à-ldap">Ajout dune entrée à LDAP</h3>
<p>Continuons avec la page <strong>ajoute.php</strong> qui est utilisée pour ajouter de nouvelles personnes dans notre annuaire : Sur la copie décran, vous pouvez constater sur le haut et bas de page est exactement le même que sur notre page principale (dû à lutilisation des fichiers header.php et footer.php). La page est constituée dun formulaire avec des champs obligatoires. Vous retrouvez les boutons standards pour valider ou annuler votre nouvelle saisie. Pour essayer de garder toute la fonction « ajouter » dans la même page
(formulaire et enregistrement), on introduit une variable go qui détermine si la page est appellée pour la première fois ou si elle est rappellée après la validation du formulaire.</p>
<p>Cette variable est en fait un champ caché du formulaire (<code class="language-plaintext highlighter-rouge">&lt;INPUT type="hidden" name="go" value="1"&gt;</code>).</p>
<p>Si la variable go est égale à 1 et que les champs <em>nom, prénom et mail</em> ne sont pas vides, on peut alors enregistrer la nouvelle personne dans lannuaire.</p>
<p>Pour ce faire, on se connecte au serveur et on sauthentifie avec le super-utilisateur,
ici ldap_admin (fonction <code class="language-plaintext highlighter-rouge">ldap_bind()</code>).</p>
<p>Ensuite on doit préparer nos informations avant de les inscrire dans lannuaire : on construit le champ cn en concaténant le nom et le prénom. On précise bien que cest un objet de type <em>person</em> que lon veut ajouter et on lance lenregistrement avec la fonction <code class="language-plaintext highlighter-rouge">ldap_add()</code>.</p>
<p>Sinon, on affiche le formulaire de saisie avec un message derreur si lon a validé le formulaire sans avoir rempli les champs obligatoires.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ajoute.php
</code></pre></div></div>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// on affiche le haut de la page contenu dans le fichier header.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"header.php"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="nv">$go</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span> <span class="k">and</span> <span class="p">(</span><span class="nv">$nom</span><span class="o">!=</span><span class="s2">""</span><span class="p">)</span> <span class="k">and</span> <span class="p">(</span><span class="nv">$prenom</span><span class="o">!=</span><span class="s2">""</span><span class="p">)</span> <span class="k">and</span> <span class="p">(</span><span class="nv">$mail</span><span class="o">!=</span><span class="s2">""</span><span class="p">))</span>
<span class="p">{</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// on s'authentifie en tant que super-utilisateur, ici, ldap_admin</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// préparation des données</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"cn"</span><span class="p">]</span><span class="o">=</span><span class="nv">$nom</span><span class="mf">.</span><span class="s2">" "</span><span class="mf">.</span><span class="nv">$prenom</span><span class="p">;</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"mail"</span><span class="p">]</span><span class="o">=</span><span class="nv">$mail</span><span class="p">;</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"telephonenumber"</span><span class="p">]</span><span class="o">=</span><span class="nv">$tel</span><span class="p">;</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"objectclass"</span><span class="p">]</span><span class="o">=</span><span class="s2">"person"</span><span class="p">;</span>
<span class="c1">// ajout dans l'annuaire</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_add</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="s2">"cn=</span><span class="nv">$nom</span><span class="s2"> </span><span class="nv">$prenom</span><span class="s2">,</span><span class="nv">$racine</span><span class="s2">"</span><span class="p">,</span><span class="nv">$info</span><span class="p">);</span>
<span class="c1">// fermeture de la connexion</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="nv">$go</span><span class="o">==</span><span class="mi">0</span><span class="p">;</span>
<span class="nv">$nom</span><span class="o">==</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">$prenom</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">$mail</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">$tel</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"L'enregistrement a réussi !!!</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;P&gt;&lt;A HREF=</span><span class="se">\"</span><span class="s2">ajoute.php</span><span class="se">\"</span><span class="s2">&gt;Ajouter
une nouvelle personne&lt;/A&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;P&gt;&lt;A HREF=</span><span class="se">\"</span><span class="s2">admin.php</span><span class="se">\"</span><span class="s2">&gt;Retourner
à la page d'administration&lt;/A&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$go</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$mes</span><span class="o">=</span><span class="s2">"ERREUR ! Vous devez obligatoirement remplir les champs en gras"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;FONT COLOR=FF0000&gt;</span><span class="nv">$mes</span><span class="s2">&lt;/FONT&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">echo</span> <span class="s2">"&lt;FORM ACTION=</span><span class="se">\"</span><span class="s2">ajoute.php</span><span class="se">\"</span><span class="s2"> METHOD=POST&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TABLE BORDER=0&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="n">quot</span><span class="p">;</span><span class="o">&lt;</span><span class="no">TR</span><span class="o">&gt;&lt;</span><span class="no">TD</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nc">B</span><span class="o">&gt;</span><span class="nc">Nom</span><span class="o">&lt;/</span><span class="nc">B</span><span class="o">&gt;&lt;/</span><span class="no">TD</span><span class="o">&gt;</span><span class="n">\n</span><span class="s2">";
echo "</span><span class="o">&lt;</span><span class="no">TD</span><span class="o">&gt;&lt;</span><span class="no">INPUT</span> <span class="no">TYPE</span><span class="o">=</span><span class="err">\</span><span class="s2">"text</span><span class="se">\"</span><span class="s2"> NAME=</span><span class="se">\"</span><span class="s2">nom</span><span class="se">\"</span><span class="s2">
value=</span><span class="se">\"</span><span class="nv">$nom</span><span class="se">\"</span><span class="s2"> SIZE=30 maxlength=80&gt;&lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TR&gt;&lt;TD&gt; &lt;B&gt;Prénom&lt;/B&gt;&lt;/TD&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TD&gt;&lt;INPUT TYPE=</span><span class="se">\"</span><span class="s2">text</span><span class="se">\"</span><span class="s2"> NAME=</span><span class="se">\"</span><span class="s2">prenom</span><span class="se">\"</span><span class="s2">
value=</span><span class="se">\"</span><span class="nv">$prenom</span><span class="se">\"</span><span class="s2"> SIZE=30 maxlength=80&gt;&lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TR&gt;&lt;TD&gt; &lt;B&gt;E-Mail&lt;/B&gt;&lt;/TD&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TD&gt;&lt;INPUT TYPE=</span><span class="se">\"</span><span class="s2">text</span><span class="se">\"</span><span class="s2"> NAME=</span><span class="se">\"</span><span class="s2">mail</span><span class="se">\"</span><span class="s2">
value=</span><span class="se">\"</span><span class="nv">$mail</span><span class="se">\"</span><span class="s2"> SIZE=40 maxlength=80&gt;&lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TR&gt;&lt;TD&gt; Téléphone&lt;/TD&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TD&gt;&lt;INPUT TYPE=</span><span class="se">\"</span><span class="s2">text</span><span class="se">\"</span><span class="s2"> NAME=</span><span class="se">\"</span><span class="s2">tel</span><span class="se">\"</span><span class="s2">
value=</span><span class="se">\"</span><span class="nv">$tel</span><span class="se">\"</span><span class="s2"> SIZE=40 maxlength=255&gt;&lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;/TABLE&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">hidden</span><span class="se">\"</span><span class="s2"> name=</span><span class="se">\"</span><span class="s2">go</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="s2">1</span><span class="se">\"</span><span class="s2">&gt;&lt;BR&gt;&lt;BR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">submit</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="s2">Valider</span><span class="se">\"</span><span class="s2">&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">reset</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="s2">Annuler</span><span class="se">\"</span><span class="s2">&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;/FORM&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;BR&gt;Les champs en &lt;B&gt;gras&lt;/B&gt; sont obligatoires.</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// on affiche le bas de la page contenu dans le fichier footer.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"footer.php"</span><span class="p">);</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="modification-dune-entrée-de-lannuaire-ldap">Modification dune entrée de lannuaire LDAP</h3>
<p>Regardons maintenant le source (plus long mais pas plus complexe !) de la page <strong>modifie.php</strong>.
Le nom et le prénom étant concaténé dans le champ cn de lannuaire, <u>il sera impossible de faire une modification sur le nom ou sur le prénom</u>.</p>
<p>Pour modifier une personne, il faut dabord la supprimer (avec <code class="language-plaintext highlighter-rouge">ldap_delete()</code>) puis la réenregistrer avec les nouvelles valeurs.</p>
<p>Le champ <em>mail</em> est bien sûr toujours <u>obligatoire</u>. On utilise le même principe pour centraliser sur la même page le formulaire de modification et le lenregistrement des modifications (variable <em>go</em>).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>modifie.php
</code></pre></div></div>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// on affiche le haut de la page contenu dans le fichier header.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"header.php"</span><span class="p">);</span>
<span class="nv">$cn</span><span class="o">=</span><span class="nb">urldecode</span><span class="p">(</span><span class="nv">$cn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="nv">$go</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span> <span class="k">and</span> <span class="p">(</span><span class="nv">$mail</span><span class="o">!=</span><span class="s2">""</span><span class="p">))</span>
<span class="p">{</span>
<span class="c1">// connexion au serveur</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// on s'authentifie en tant que super-utilisateur, ici, ldap_admin</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// Suppression de l'ancien enregistrement</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_delete</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="s2">"cn=</span><span class="nv">$cn</span><span class="s2">,</span><span class="nv">$racine</span><span class="s2">"</span><span class="p">);</span>
<span class="c1">// Préparation des données</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"cn"</span><span class="p">]</span><span class="o">=</span><span class="nv">$cn</span><span class="p">;</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"mail"</span><span class="p">]</span><span class="o">=</span><span class="nv">$mail</span><span class="p">;</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"telephonenumber"</span><span class="p">]</span><span class="o">=</span><span class="nv">$tel</span><span class="p">;</span>
<span class="nv">$info</span><span class="p">[</span><span class="s2">"objectclass"</span><span class="p">]</span><span class="o">=</span><span class="s2">"person"</span><span class="p">;</span>
<span class="c1">// Ajout dans l'annuaire</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_add</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="s2">"cn=</span><span class="nv">$cn</span><span class="s2">,</span><span class="nv">$racine</span><span class="s2">"</span><span class="p">,</span><span class="nv">$info</span><span class="p">);</span>
<span class="c1">// fermeture de la connexion à l'annuaire LDAP</span>
<span class="nb">ldap_close</span><span class="p">(</span><span class="nv">$ds</span><span class="p">);</span>
<span class="nv">$go</span><span class="o">==</span><span class="mi">0</span><span class="p">;</span>
<span class="nv">$nom</span><span class="o">==</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">$prenom</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">$mail</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">$tel</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"La modification a réussi !!!</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;P&gt;&lt;A HREF=</span><span class="se">\"</span><span class="s2">admin.php</span><span class="se">\"</span><span class="s2">&gt;Retourner
à la page d'administration&lt;/A&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$go</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$mes</span><span class="o">=</span><span class="s2">"ERREUR ! Vous devez obligatoirement remplir le champ mail"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;FONT COLOR=FF0000&gt;</span><span class="nv">$mes</span><span class="s2">&lt;/FONT&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// connexion au serveur</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$recherche</span><span class="o">=</span><span class="s2">"cn=</span><span class="nv">$cn</span><span class="s2">"</span><span class="p">;</span>
<span class="nv">$champs</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s2">"cn"</span><span class="p">,</span> <span class="s2">"telephonenumber"</span><span class="p">,</span> <span class="s2">"mail"</span><span class="p">);</span>
<span class="c1">// recherche les informations de la personne que l'on veut modifier</span>
<span class="nv">$sr</span><span class="o">=</span><span class="nb">ldap_search</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span> <span class="nv">$racine</span><span class="p">,</span> <span class="nv">$recherche</span><span class="p">,</span> <span class="nv">$champs</span><span class="p">);</span>
<span class="nv">$num</span><span class="o">=</span> <span class="nb">ldap_get_entries</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$sr</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$num</span><span class="p">[</span><span class="s2">"count"</span><span class="p">]</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$mynom</span> <span class="o">=</span> <span class="nv">$num</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">"cn"</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$myemail</span> <span class="o">=</span> <span class="nv">$num</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">"mail"</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$mytel</span> <span class="o">=</span> <span class="nv">$num</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">"telephonenumber"</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="k">echo</span> <span class="s2">"&lt;FORM ACTION=</span><span class="se">\"</span><span class="s2">modifie.php</span><span class="se">\"</span><span class="s2"> METHOD=POST&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TABLE BORDER=0&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TR&gt;&lt;TD&gt; &lt;B&gt;Modification de l'utilisateur : </span><span class="nv">$cn</span><span class="s2">&lt;/B&gt;&lt;/TD&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TR&gt;&lt;TD&gt; &lt;B&gt;E-Mail&lt;/B&gt;&lt;/TD&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TD&gt;&lt;INPUT TYPE=</span><span class="se">\"</span><span class="s2">text</span><span class="se">\"</span><span class="s2"> NAME=</span><span class="se">\"</span><span class="s2">mail</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="nv">$myemail</span><span class="se">\"</span><span class="s2">
SIZE=40 maxlength=80&gt;&lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TR&gt;&lt;TD&gt; Téléphone&lt;/TD&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;TD&gt;&lt;INPUT TYPE=</span><span class="se">\"</span><span class="s2">text</span><span class="se">\"</span><span class="s2"> NAME=</span><span class="se">\"</span><span class="s2">tel</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="nv">$mytel</span><span class="se">\"</span><span class="s2">
SIZE=40 maxlength=255&gt;&lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;/TABLE&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">hidden</span><span class="se">\"</span><span class="s2"> name=</span><span class="se">\"</span><span class="s2">cn</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="nv">$cn</span><span class="se">\"</span><span class="s2">&gt;&lt;BR&gt;&lt;BR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">hidden</span><span class="se">\"</span><span class="s2"> name=</span><span class="se">\"</span><span class="s2">go</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="s2">1</span><span class="se">\"</span><span class="s2">&gt;&lt;BR&gt;&lt;BR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">submit</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="s2">Modifier</span><span class="se">\"</span><span class="s2">&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;INPUT type=</span><span class="se">\"</span><span class="s2">reset</span><span class="se">\"</span><span class="s2"> value=</span><span class="se">\"</span><span class="s2">Annuler</span><span class="se">\"</span><span class="s2">&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;/FORM&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;BR&gt;Le champ &lt;B&gt;mail&lt;/B&gt; est obligatoire.</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Erreur ! La recherche n'a pas aboutie"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Erreur ! Problème à la connexion avec le serveur LDAP"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"footer.php"</span><span class="p">);</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="suppression-dune-entrée-de-lannuaire-ldap">Suppression dune entrée de lannuaire LDAP</h3>
<p>On termine enfin avec la page <strong>supprime.php</strong> qui, avant de supprimer, va demander
une confirmation.</p>
<p>Si on confirme, on rappelle la page <strong>supprime.php</strong> avec le paramètre <em>go=1</em></p>
<p>Ici, on est obligé de préciser <em>go=1</em> dans lURL car seules les variables contenues dans les formulaires sont automatiquement passées dune page à lautre.</p>
<p>La suppression ne peut seffectuer quavec le super-utilisateur <code class="language-plaintext highlighter-rouge">ldap_admin</code> (fonction <code class="language-plaintext highlighter-rouge">ldap_bind()</code>).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>supprime.php
</code></pre></div></div>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?</span>
<span class="c1">// on affiche le haut de la page contenu dans le fichier header.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"header.php"</span><span class="p">);</span>
<span class="nv">$cn</span><span class="o">=</span><span class="nb">urldecode</span><span class="p">(</span><span class="nv">$cn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$go</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"Etes-vous sur de vouloir supprimer l'utilisateur </span><span class="nv">$cn</span><span class="s2">&lt;br&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="nv">$cn</span><span class="o">=</span><span class="nb">urlencode</span><span class="p">(</span><span class="nv">$cn</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"&lt;A HREF=</span><span class="se">\"</span><span class="s2">supprime.php?go=1&amp;cn=</span><span class="nv">$cn</span><span class="se">\"</span><span class="s2">&gt;oui&lt;/A&gt;&lt;BR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;A HREF=</span><span class="se">\"</span><span class="s2">admin.php</span><span class="se">\"</span><span class="s2">&gt;non&lt;/A&gt;&lt;BR&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="nv">$cn</span><span class="o">=</span><span class="nb">urldecode</span><span class="p">(</span><span class="nv">$cn</span><span class="p">);</span>
<span class="c1">// connexion au serveur LDAP</span>
<span class="nv">$ds</span><span class="o">=</span><span class="nb">ldap_connect</span><span class="p">(</span><span class="nv">$server</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$ds</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// on s'authentifie en tant que super-utilisateur, ici, ldap_admin</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_bind</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="nv">$rootdn</span><span class="p">,</span><span class="nv">$rootpw</span><span class="p">);</span>
<span class="c1">// Suppression de l'ancien enregistrement</span>
<span class="nv">$r</span><span class="o">=</span><span class="nb">ldap_delete</span><span class="p">(</span><span class="nv">$ds</span><span class="p">,</span><span class="s2">"cn=</span><span class="nv">$cn</span><span class="s2">,</span><span class="nv">$racine</span><span class="s2">"</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"La suppression a réussi !!!</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;P&gt;&lt;A HREF=</span><span class="se">\"</span><span class="s2">admin.php</span><span class="se">\"</span><span class="s2">&gt;Retourner
à la page d'administration&lt;/A&gt;</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// on affiche le bas de la page contenu dans le fichier footer.php</span>
<span class="k">require</span><span class="p">(</span><span class="s2">"footer.php"</span><span class="p">);</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<h3 id="modification-dune-entrée-de-lannuaire-ldap-1">Modification dune entrée de lannuaire LDAP</h3>
<p>Vous voilà prêt à administrer votre annuaire… ou à construire votre propre interface dadministration. Pour un souci de simplicité, seules les fonctionnalités de base ont été implémentées.</p>
<p>Une page pour rechercher une personne pourrait aussi être écrite.</p>
<p>La présentation de linterface est sommaire mais assez pratique : toutefois, pour la page <strong>admin.php</strong>, il serait envisageable dajouter un alphabet qui lorsque lon clique sur une lettre, déclenche laffichage des personnes dont le nom commence par la lettre sélectionnée.</p>
<p>De même, vous pouvez modifier aussi la structure de lannuaire.
Par exemple, vous pouvez ajouter des propriétés à votre objet <em>person</em> : un champ <em>photo</em> qui pourrait contenir le chemin daccès complet à une photo didentité stockée sur votre serveur…</p>
<p>Les sources sont commentés de façon à vous aider à concevoir de nouveaux programmes en PHP.</p>
</div>
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2019-09-26T00:00:00+02:00"><!-- start custom article footer snippet -->
<!-- end custom article footer snippet -->
<!--
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
&emsp;</div>
-->
</footer>
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2019/09/26/Airsonic-divergence(fork)-Subsonic.html">Airsonic music stream</a></div><div class="next"><span>SUIVANT</span><a href="/2019/10/05/OpenLDAP-installation-configuration-annuaire.html">OpenLDAP installation et configuration annuaire</a></div></div></div>
</div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
$scroll = $(scroll);
$articleContent.find('.highlight').each(function() {
$this = $(this);
$this.attr('data-lang', $this.find('code').attr('data-lang'));
});
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
$this = $(this);
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
});
$articleContent.on('click', '.anchor', function() {
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
});
});
});
})();
</script>
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
<!-- end custom main bottom snippet -->
</div>
</div></div></div></div>
</div><script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $body = $('body'), $window = $(window);
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
var activeCount = 0;
function modal(options) {
var $root = this, visible, onChange, hideWhenWindowScroll = false;
var scrollTop;
function setOptions(options) {
var _options = options || {};
visible = _options.initialVisible === undefined ? false : show;
onChange = _options.onChange;
hideWhenWindowScroll = _options.hideWhenWindowScroll;
}
function init() {
setState(visible);
}
function setState(isShow) {
if (isShow === visible) {
return;
}
visible = isShow;
if (visible) {
activeCount++;
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
$root.addClass('modal--show');
$pageMain.scrollTop(scrollTop);
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
$window.on('keyup', handleKeyup);
} else {
activeCount > 0 && activeCount--;
$root.removeClass('modal--show');
$window.scrollTop(scrollTop);
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
$window.off('keyup', handleKeyup);
}
onChange && onChange(visible);
}
function show() {
setState(true);
}
function hide() {
setState(false);
}
function handleKeyup(e) {
// Char Code: 27 ESC
if (e.which === 27) {
hide();
}
}
setOptions(options);
init();
return {
show: show,
hide: hide,
$el: $root
};
}
$.fn.modal = modal;
});
})();
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
(function () {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
// search panel
var search = (window.search || (window.search = {}));
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
true : window.useDefaultSearchBox ;
var $searchModal = $('.js-page-search-modal');
var $searchToggle = $('.js-search-toggle');
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
var modalVisible = false;
search.searchModal = searchModal;
var $searchBox = null;
var $searchInput = null;
var $searchClear = null;
function getModalVisible() {
return modalVisible;
}
search.getModalVisible = getModalVisible;
function handleModalChange(visible) {
modalVisible = visible;
if (visible) {
search.onShow && search.onShow();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
} else {
search.onShow && search.onHide();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
setTimeout(function() {
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
search.clear && search.clear();
window.pageAsideAffix && window.pageAsideAffix.refresh();
}, 400);
}
}
$searchToggle.on('click', function() {
modalVisible ? searchModal.hide() : searchModal.show();
});
// Char Code: 83 S, 191 /
$(window).on('keyup', function(e) {
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
modalVisible || searchModal.show();
}
});
if (useDefaultSearchBox) {
$searchBox = $('.js-search-box');
$searchInput = $searchBox.children('input');
$searchClear = $searchBox.children('.js-icon-clear');
search.getSearchInput = function() {
return $searchInput.get(0);
};
search.getVal = function() {
return $searchInput.val();
};
search.setVal = function(val) {
$searchInput.val(val);
};
$searchInput.on('focus', function() {
$(this).addClass('focus');
});
$searchInput.on('blur', function() {
$(this).removeClass('focus');
});
$searchInput.on('input', window.throttle(function() {
var val = $(this).val();
if (val === '' || typeof val !== 'string') {
search.clear && search.clear();
} else {
$searchBox.addClass('not-empty');
search.onInputNotEmpty && search.onInputNotEmpty(val);
}
}, 400));
$searchClear.on('click', function() {
$searchInput.val(''); $searchBox.removeClass('not-empty');
search.clear && search.clear();
});
}
});
})();
</script><div class="search search--dark">
<div class="main">
<div class="search__header">Recherche</div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div>
</div>
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
Annuler</button>
</div>
<div id="results-container" class="search-result js-search-result"></div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
noResultsText: '<p>Aucun résultat!</p>',
json: '/search.json',
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a>&nbsp;(Création {create})</li>'
})
</script>
</div></div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function scrollToAnchor(anchor, duration, callback) {
var $root = this;
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
callback && callback();
});
}
$.fn.scrollToAnchor = scrollToAnchor;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function affix(options) {
var $root = this, $window = $(window), $scrollTarget, $scroll,
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
hasInit = false, curState;
function setOptions(options) {
var _options = options || {};
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroll && (scroll = _options.scroll);
_options.disabled !== undefined && (disabled = _options.disabled);
$scrollTarget = $(scrollTarget);
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
$scroll = $(scroll);
}
function preCalc() {
top();
rootHeight = $root.outerHeight();
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
rootLeft = $root.offset().left;
}
function calc(needPreCalc) {
needPreCalc && preCalc();
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
rootBottomTop = scrollBottom - rootTop;
}
function top() {
if (curState !== 'top') {
$root.removeClass('fixed').css({
left: 0,
top: 0
});
curState = 'top';
}
}
function fixed() {
if (curState !== 'fixed') {
$root.addClass('fixed').css({
left: rootLeft + 'px',
top: 0
});
curState = 'fixed';
}
}
function bottom() {
if (curState !== 'bottom') {
$root.removeClass('fixed').css({
left: 0,
top: rootBottomTop + 'px'
});
curState = 'bottom';
}
}
function setState() {
var scrollTop = $scrollTarget.scrollTop();
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
fixed();
} else if (scrollTop < rootTop) {
top();
} else {
bottom();
}
}
function init() {
if(!hasInit) {
var interval, timeout;
calc(true); setState();
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState();
});
$window.on('resize', function() {
disabled || (calc(true), setState());
});
hasInit = true;
}
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions,
refresh: function() {
calc(true, { animation: false }); setState();
}
};
}
$.fn.affix = affix;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function toc(options) {
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
function setOptions(options) {
var _options = options || {};
_options.selectors && (selectors = _options.selectors);
_options.container && (container = _options.container);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroller && (scroller = _options.scroller);
_options.disabled !== undefined && (disabled = _options.disabled);
$headings = $(container).find(selectors).filter('[id]');
$scrollTarget = $(scrollTarget);
$scroller = $(scroller);
}
function calc() {
headingsPos = [];
$headings.each(function() {
headingsPos.push(Math.floor($(this).position().top));
});
}
function setState(element, disabled) {
var scrollTop = $scrollTarget.scrollTop(), i;
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
if (element) {
$activeCur = element;
} else {
for (i = 0; i < headingsPos.length; i++) {
if (scrollTop >= headingsPos[i]) {
$activeCur = $tocLi.eq(i);
} else {
$activeCur || ($activeCur = $tocLi.eq(i));
break;
}
}
}
$activeLast && $activeLast.removeClass('active');
($activeLast = $activeCur).addClass('active');
}
function render() {
if(!hasRendered) {
$root.append($tocUl);
$headings.each(function() {
var $this = $(this);
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
});
$tocLi = $tocUl.children('li');
$tocUl.on('click', 'a', function(e) {
e.preventDefault();
var $this = $(this);
scrolling = true;
setState($this.parent());
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
scrolling = false;
});
});
}
hasRendered = true;
}
function init() {
var interval, timeout;
if(!hasInit) {
render(); calc(); setState(null, scrolling);
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState(null, scrolling);
});
$window.on('resize', window.throttle(function() {
if (!disabled) {
render(); calc(); setState(null, scrolling);
}
}, 100));
}
hasInit = true;
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions
};
}
$.fn.toc = toc;
});
})();
/*(function () {
})();*/
</script><script>
/* toc must before affix, since affix need to konw toc' height. */(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window);
var $articleContent = $('.js-article-content');
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
var toc;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
function disabled() {
return $col2.css('display') === 'none' || !hasToc;
}
tocDisabled = disabled();
toc = $tocRoot.toc({
selectors: TOC_SELECTOR,
container: $articleContent,
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
tocDisabled = disabled();
toc && toc.setOptions({
disabled: tocDisabled
});
}, 100));
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window), $pageFooter = $('.js-page-footer');
var $pageAside = $('.js-page-aside');
var affix;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
affix = $pageAside.affix({
offsetBottom: $pageFooter.outerHeight(),
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
scroll: hasSidebar ? $('.js-page-main').children() : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
affix && affix.setOptions({
disabled: tocDisabled
});
}, 100));
window.pageAsideAffix = affix;
});
})();
</script><!---->
</div>
<script>(function () {
var $root = document.getElementsByClassName('root')[0];
if (window.hasEvent('touchstart')) {
$root.dataset.isTouch = true;
document.addEventListener('touchstart', function(){}, false);
}
})();
</script>
</body>
</html>