Skip to content

Commit 4e272a4

Browse files
author
David Coutadeur
committed
add createAccount and updateAccount hooks and split hook() function (#219)
1 parent 0b9c647 commit 4e272a4

File tree

4 files changed

+188
-90
lines changed

4 files changed

+188
-90
lines changed

conf/config.inc.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@
341341
# "accountEnable" => array(),
342342
# "accountDisable" => array(),
343343
# "updateValidityDates" => array(),
344+
# "createAccount" => array(),
345+
# "updateAccount" => array(),
344346
# "deleteAccount" => array()
345347
#);
346348
# passwordReset, passwordLock,...: entrypoints triggering hooks
@@ -350,12 +352,15 @@
350352
# * accountEnable: input: login
351353
# * accountDisable: input: login
352354
# * updateValidityDates: input: login, start date, end date
355+
# * createAccount: input: dn, ldap entry
356+
# * updateAccount: input: dn, ldap entry
353357
# * deleteAccount: input: login
354-
# externalScript: path of the script that is called. Script should return 0, else action after prehook will be aborted, unless error is ignored
358+
# externalScript: path of the script that is called. Prehook script or function should return 0, else action will be aborted, unless error is ignored
355359
# function: the hook can also be a function. Write your own file.php in hooks/ directory
356360
# displayError: display an error if the script or function returns an error
357361
# ignoreError: prehook only, ignore error returned by the script or function
358362
# encodebase64: passwordReset entrypoint only, encode the password in base64 before sending it
363+
# For createAccount and updateAccount, for prehook external script, the expected output is: first line: error message, all other lines: ldap entry in json format. For prehook function, the expected returned values are: return code, error message, ldap entry
359364
$prehook = array();
360365
$posthook = array();
361366

htdocs/create.php

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
require_once("../conf/config.inc.php");
1919
require __DIR__ . '/../vendor/autoload.php';
2020
require_once("../lib/date.inc.php");
21+
require_once("../lib/hook.inc.php");
2122

2223
# Connect to LDAP
2324
$ldap_connection = $ldapInstance->connect();
@@ -74,23 +75,37 @@ function ($matches) use ($item, $create_attributes, $attributes_map) {
7475

7576
$dn .= "," . $create_base;
7677

77-
# Create entry
78-
if (!ldap_add($ldap, $dn, $create_attributes)) {
79-
error_log("LDAP - modify failed for $dn");
80-
$result = "createfailed";
81-
$action = "displayform";
78+
79+
list($prehook_return, $prehook_message, $create_attributes) =
80+
hook($prehook, 'createAccount', "", array("dn" => $dn, "entry" => $create_attributes));
81+
82+
if ( $prehook_return > 0 and !$prehook['createAccount']['ignoreError']) {
83+
$result = "hookerror";
8284
} else {
83-
$errno = ldap_errno($ldap);
84-
if ( $errno ) {
85-
error_log("LDAP - create error $errno (".ldap_error($ldap).") for $dn");
85+
# Create entry
86+
if (!ldap_add($ldap, $dn, $create_attributes)) {
87+
error_log("LDAP - modify failed for $dn");
8688
$result = "createfailed";
8789
$action = "displayform";
8890
} else {
89-
$result = "createok";
90-
$action = "displayentry";
91+
$errno = ldap_errno($ldap);
92+
if ( $errno ) {
93+
error_log("LDAP - create error $errno (".ldap_error($ldap).") for $dn");
94+
$result = "createfailed";
95+
$action = "displayform";
96+
} else {
97+
$result = "createok";
98+
$action = "displayentry";
99+
}
91100
}
92101
}
93102

103+
if ( $result === "createok" ) {
104+
list($posthook_return, $posthook_message) =
105+
hook($posthook, 'createAccount', "", array("dn" => $dn, "entry" => $create_attributes));
106+
}
107+
108+
94109
if ($audit_log_file) {
95110
auditlog($audit_log_file, $dn, $audit_admin, "createentry", $result, $comment);
96111
}
@@ -118,6 +133,12 @@ function ($matches) use ($item, $create_attributes, $attributes_map) {
118133

119134
if ( $action == "displayentry" ) {
120135
$location = 'index.php?page=display&dn='.urlencode($dn).'&createresult='.$result;
136+
if ( isset($prehook_return) and $prehook['createAccount']['displayError'] and $prehook_return > 0 ) {
137+
$location .= '&prehookresult='.$prehook_message;
138+
}
139+
if ( isset($posthook_return) and $posthook['createAccount']['displayError'] and $posthook_return > 0 ) {
140+
$location .= '&posthookresult='.$posthook_message;
141+
}
121142
header('Location: '.$location);
122143
}
123144

htdocs/update.php

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
require_once("../conf/config.inc.php");
2626
require __DIR__ . '/../vendor/autoload.php';
2727
require_once("../lib/date.inc.php");
28+
require_once("../lib/hook.inc.php");
2829

2930
# Connect to LDAP
3031
$ldap_connection = $ldapInstance->connect();
@@ -72,23 +73,36 @@ function ($matches) use ($item, $update_attributes, $attributes_map) {
7273
$update_attributes[ $attributes_map[$item]['attribute'] ] = $value;
7374
}
7475

75-
# Update entry
76-
if (!ldap_mod_replace($ldap, $dn, $update_attributes)) {
77-
error_log("LDAP - modify failed for $dn");
78-
$result = "updatefailed";
79-
$action = "displayform";
76+
77+
list($prehook_return, $prehook_message, $update_attributes) =
78+
hook($prehook, 'updateAccount', "", array("dn" => $dn, "entry" => $update_attributes));
79+
80+
if ( $prehook_return > 0 and !$prehook['updateAccount']['ignoreError']) {
81+
$result = "hookerror";
8082
} else {
81-
$errno = ldap_errno($ldap);
82-
if ( $errno ) {
83-
error_log("LDAP - modify error $errno (".ldap_error($ldap).") for $dn");
83+
# Update entry
84+
if (!ldap_mod_replace($ldap, $dn, $update_attributes)) {
85+
error_log("LDAP - modify failed for $dn");
8486
$result = "updatefailed";
8587
$action = "displayform";
8688
} else {
87-
$result = "updateok";
88-
$action = "displayentry";
89+
$errno = ldap_errno($ldap);
90+
if ( $errno ) {
91+
error_log("LDAP - modify error $errno (".ldap_error($ldap).") for $dn");
92+
$result = "updatefailed";
93+
$action = "displayform";
94+
} else {
95+
$result = "updateok";
96+
$action = "displayentry";
97+
}
8998
}
9099
}
91100

101+
if ( $result === "updateok" ) {
102+
list($posthook_return, $posthook_message) =
103+
hook($posthook, 'updateAccount', "", array("dn" => $dn, "entry" => $update_attributes));
104+
}
105+
92106
if ($audit_log_file) {
93107
auditlog($audit_log_file, $dn, $audit_admin, "updateentry", $result, $comment);
94108
}
@@ -137,6 +151,12 @@ function ($matches) use ($item, $update_attributes, $attributes_map) {
137151

138152
if ( $action == "displayentry" ) {
139153
$location = 'index.php?page=display&dn='.urlencode($dn).'&updateresult='.$result;
154+
if ( isset($prehook_return) and $prehook['updateAccount']['displayError'] and $prehook_return > 0 ) {
155+
$location .= '&prehookresult='.$prehook_message;
156+
}
157+
if ( isset($posthook_return) and $posthook['updateAccount']['displayError'] and $posthook_return > 0 ) {
158+
$location .= '&posthookresult='.$posthook_message;
159+
}
140160
header('Location: '.$location);
141161
}
142162

lib/hook.inc.php

Lines changed: 121 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@ function password_hook_command($hook, $login, $newpassword, $oldpassword = null,
3131
return $command;
3232
}
3333

34-
/* @function string hook_command(string $hook, string $login)
35-
Creates hook command line passing login as parameter
34+
/* @function string hook_command(string $hook, string arg1, string arg2,...)
35+
Creates hook command line passing multiple arguments
3636
@param $hook string script/command to execute for procesing hook data
37-
@param $login string username
37+
@param $argN string Nth argument
3838
*/
39-
function hook_command($hook, $login) {
40-
$command = escapeshellcmd($hook).' '.escapeshellarg($login);
39+
function hook_command($hook, ...$args) {
40+
$command = escapeshellcmd($hook);
41+
foreach ($args as $arg) {
42+
$command .= ' '.escapeshellarg($arg);
43+
}
4144
return $command;
4245
}
4346

@@ -65,84 +68,133 @@ function get_hook_login($dn, $ldapInstance, $login_attribute)
6568
return $login_value;
6669
}
6770

71+
function call_external_command($hookConfig, $entrypoint, $login_value, $params)
72+
{
73+
$returnCode = 0;
74+
$returnMessage = "";
75+
$returnedEntry = isset($params['entry']) ? $params['entry'] : null;
76+
77+
switch ($entrypoint) {
78+
79+
case "passwordReset":
80+
$password = $params['password'];
81+
$command = password_hook_command($hookConfig[$entrypoint]['externalScript'],
82+
$login_value,
83+
$password,
84+
null,
85+
$hookConfig[$entrypoint]['encodebase64']);
86+
exec($command, $output, $returnCode);
87+
$returnMessage = $output[0];
88+
break;
89+
90+
case "updateValidityDates":
91+
$start_date = $params['start_date'];
92+
$end_date = $params['end_date'];
93+
$command = validity_hook_command($hookConfig[$entrypoint]['externalScript'],
94+
$login_value,
95+
$start_date,
96+
$end_date);
97+
exec($command, $output, $returnCode);
98+
$returnMessage = $output[0];
99+
break;
100+
101+
case "passwordLock":
102+
case "passwordUnlock":
103+
case "accountEnable":
104+
case "accountDisable":
105+
case "deleteAccount":
106+
$command = hook_command($hookConfig[$entrypoint]['externalScript'], $login_value);
107+
exec($command, $output, $returnCode);
108+
$returnMessage = $output[0];
109+
break;
110+
111+
case "createAccount":
112+
case "updateAccount":
113+
$dn = $params['dn'];
114+
$command = hook_command($hookConfig[$entrypoint]['externalScript'], $dn, json_encode($returnedEntry));
115+
exec($command, $output, $returnCode);
116+
$returnMessage = $output[0];
117+
if(count($output) > 1) {
118+
$returnedEntry = json_decode(implode('', array_slice($output, 1)), true);
119+
}
120+
break;
121+
122+
}
123+
return array($returnCode, $returnMessage, $returnedEntry);
124+
}
125+
126+
function call_external_function($hookConfig, $entrypoint, $login_value, $params)
127+
{
128+
$returnCode = 0;
129+
$returnMessage = "";
130+
$returnedEntry = isset($params['entry']) ? $params['entry'] : null;
131+
132+
switch ($entrypoint) {
133+
134+
case "passwordReset":
135+
$password = $params['password'];
136+
if( isset($hookConfig[$entrypoint]['encodebase64']) &&
137+
$hookConfig[$entrypoint]['encodebase64'] )
138+
{
139+
$password = base64_encode($params['password']);
140+
}
141+
$params = [$login_value, $password];
142+
list($returnCode, $returnMessage) =
143+
$hookConfig[$entrypoint]['function'](...$params);
144+
break;
145+
146+
case "updateValidityDates":
147+
$start_date = $params['start_date'];
148+
$end_date = $params['end_date'];
149+
$params = [$login_value, $start_date, $end_date];
150+
list($returnCode, $returnMessage) =
151+
$hookConfig[$entrypoint]['function'](...$params);
152+
break;
153+
154+
case "passwordLock":
155+
case "passwordUnlock":
156+
case "accountEnable":
157+
case "accountDisable":
158+
case "deleteAccount":
159+
$params = [$login_value];
160+
list($returnCode, $returnMessage) =
161+
$hookConfig[$entrypoint]['function'](...$params);
162+
break;
163+
164+
case "createAccount":
165+
case "updateAccount":
166+
$dn = $params['dn'];
167+
$params = [$dn, $returnedEntry];
168+
list($returnCode, $returnMessage, $returnedEntry) =
169+
$hookConfig[$entrypoint]['function'](...$params);
170+
break;
171+
172+
}
173+
return array($returnCode, $returnMessage, $returnedEntry);
174+
}
175+
68176
function hook($hookConfig, $entrypoint, $login_value, $params) {
69177

70178
$returnCode = 0; # success return code by default
71179
$returnMessage = "";
180+
$returnedEntry = isset($params['entry']) ? $params['entry'] : null;
72181

73182
if ( isset($hookConfig[$entrypoint]['externalScript']) ||
74183
isset($hookConfig[$entrypoint]['function']) ) {
75184
if ( isset($login_value) ) {
76185

77-
# Compute external command
78-
if(isset($hookConfig[$entrypoint]['externalScript']))
79-
{
80-
switch ($entrypoint) {
81-
case "passwordReset":
82-
$password = $params['password'];
83-
$command = password_hook_command($hookConfig[$entrypoint]['externalScript'],
84-
$login_value,
85-
$password,
86-
null,
87-
$hookConfig[$entrypoint]['encodebase64']);
88-
break;
89-
case "updateValidityDates":
90-
$start_date = $params['start_date'];
91-
$end_date = $params['end_date'];
92-
$command = validity_hook_command($hookConfig[$entrypoint]['externalScript'],
93-
$login_value,
94-
$start_date,
95-
$end_date);
96-
break;
97-
case "passwordLock":
98-
case "passwordUnlock":
99-
case "accountEnable":
100-
case "accountDisable":
101-
case "deleteAccount":
102-
$command = hook_command($hookConfig[$entrypoint]['externalScript'], $login_value);
103-
break;
104-
}
105-
}
106-
107-
# Run external command
186+
# Compute and run external command
108187
if(isset($hookConfig[$entrypoint]['externalScript']))
109188
{
110-
exec($command, $output, $returnCode);
111-
$returnMessage = $output[0];
189+
list($returnCode, $returnMessage, $returnedEntry) =
190+
call_external_command($hookConfig, $entrypoint, $login_value, $params);
112191
}
113192

114-
# Prepare arguments and run function
193+
# Compute arguments and run external function
115194
if(isset($hookConfig[$entrypoint]['function']))
116195
{
117-
switch ($entrypoint) {
118-
case "passwordReset":
119-
$password = $params['password'];
120-
if( isset($hookConfig[$entrypoint]['encodebase64']) &&
121-
$hookConfig[$entrypoint]['encodebase64'] )
122-
{
123-
$password = base64_encode($params['password']);
124-
}
125-
$params = [$login_value, $password];
126-
list($returnCode, $returnMessage) =
127-
$hookConfig[$entrypoint]['function'](...$params);
128-
break;
129-
case "updateValidityDates":
130-
$start_date = $params['start_date'];
131-
$end_date = $params['end_date'];
132-
$params = [$login_value, $start_date, $end_date];
133-
list($returnCode, $returnMessage) =
134-
$hookConfig[$entrypoint]['function'](...$params);
135-
break;
136-
case "passwordLock":
137-
case "passwordUnlock":
138-
case "accountEnable":
139-
case "accountDisable":
140-
case "deleteAccount":
141-
$params = [$login_value];
142-
list($returnCode, $returnMessage) =
143-
$hookConfig[$entrypoint]['function'](...$params);
144-
break;
145-
}
196+
list($returnCode, $returnMessage, $returnedEntry) =
197+
call_external_function($hookConfig, $entrypoint, $login_value, $params);
146198
}
147199

148200
}
@@ -153,7 +205,7 @@ function hook($hookConfig, $entrypoint, $login_value, $params) {
153205
}
154206
}
155207

156-
return array($returnCode, $returnMessage);
208+
return array($returnCode, $returnMessage, $returnedEntry);
157209
}
158210

159211
?>

0 commit comments

Comments
 (0)