Skip to content

Commit 78630b0

Browse files
committed
Added functionality for Active Directory groups to be able to have virtual folders created for them along with associated configuration options.
1 parent 605e1b5 commit 78630b0

File tree

2 files changed

+120
-3
lines changed

2 files changed

+120
-3
lines changed

configuration.example.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,42 @@
173173
'public_keys' => [],
174174
];
175175

176+
// If automatic groups mode is disabled, then you have to manually add the allowed groups into $allowed_groups down below:
177+
// If enabled, then any groups you are a memberof will automatically be added in using the template below.
178+
$auto_groups_mode = false;
179+
180+
$auto_groups_mode_virtual_folder_template = [
181+
[
182+
//"id" => 0,
183+
"name" => "groups-#GROUP#",
184+
"mapped_path" => 'C:\groups\#GROUP#',
185+
//"used_quota_size" => 0,
186+
//"used_quota_files" => 0,
187+
//"last_quota_update" => 0,
188+
"virtual_path" => "/groups/#GROUP#",
189+
"quota_size" => -1,
190+
"quota_files" => -1
191+
]
192+
];
193+
194+
// List of groups where a virtual folder will be created and associated with any group members:
195+
$allowed_groups = [];
196+
197+
// Note: that for each group you need to provide a nested array (this allows for more than one virtual folder per group to be defined):
198+
$allowed_groups['example'] = [
199+
[
200+
//"id" => 0,
201+
"name" => "groups-#GROUP#",
202+
"mapped_path" => 'C:\groups\#GROUP#',
203+
//"used_quota_size" => 0,
204+
//"used_quota_files" => 0,
205+
//"last_quota_update" => 0,
206+
"virtual_path" => "/groups/#GROUP#",
207+
"quota_size" => -1,
208+
"quota_files" => -1
209+
]
210+
];
211+
176212
// Add a minimum length for usernames (set to 0 to ignore length):
177213
$username_minimum_length = 4;
178214

functions.php

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,11 @@ function authenticateUser($data) {
8989

9090
logMessage('Before authentication attempt for: ' . $data['username']);
9191
if ($connection->auth()->attempt($userDistinguishedName, $data['password'])) {
92+
$groups = getUserGroups($user);
93+
9294
// User has been successfully authenticated.
9395
logMessage('After authentication attempt for: ' . $data['username'] . ' (success!)');
94-
$output = createResponseObject($connectionName, $data['username']);
96+
$output = createResponseObject($connectionName, $data['username'], $groups);
9597

9698
logMessage('Disconnecting from ' . $connectionName);
9799
$connection->disconnect();
@@ -125,8 +127,15 @@ function authenticateUser($data) {
125127
return denyRequest();
126128
}
127129

128-
function createResponseObject($connectionName, $username) {
129-
global $home_directories, $virtual_folders, $default_output_object, $connection_output_objects, $user_output_objects;
130+
function createResponseObject($connectionName, $username, $groups = []) {
131+
global $home_directories,
132+
$virtual_folders,
133+
$default_output_object,
134+
$connection_output_objects,
135+
$user_output_objects,
136+
$allowed_groups,
137+
$auto_groups_mode,
138+
$auto_groups_mode_virtual_folder_template;
130139

131140
$userHomeDirectory = str_replace('#USERNAME#', $username, $home_directories[$connectionName]);
132141

@@ -156,6 +165,45 @@ function createResponseObject($connectionName, $username) {
156165
}
157166
}
158167

168+
// Support for automatically creating virtual folders for allowed groups the user may be a member of:
169+
if (!empty($groups)) {
170+
if ($auto_groups_mode) {
171+
foreach($groups as $group) {
172+
if (isset($auto_groups_mode_virtual_folder_template)) {
173+
foreach($auto_groups_mode_virtual_folder_template as $virtual_group_folder) {
174+
175+
$virtual_group_folder['name'] = str_replace('#GROUP#', $group, $virtual_group_folder['name']);
176+
$virtual_group_folder['mapped_path'] = str_replace('#GROUP#', $group, $virtual_group_folder['mapped_path']);
177+
$virtual_group_folder['virtual_path'] = str_replace('#GROUP#', $group, $virtual_group_folder['virtual_path']);
178+
179+
$output['virtual_folders'][] = $virtual_group_folder;
180+
181+
// Defaulting to open permissions on the virtual group folder:
182+
$output['permissions'][$virtual_group_folder['virtual_path']] = ["*"];
183+
}
184+
}
185+
}
186+
} else {
187+
if (!empty($allowed_groups)) {
188+
foreach($groups as $group) {
189+
if (isset($allowed_groups[$group])) {
190+
foreach($allowed_groups[$group] as $virtual_group_folder) {
191+
192+
$virtual_group_folder['name'] = str_replace('#GROUP#', $group, $virtual_group_folder['name']);
193+
$virtual_group_folder['mapped_path'] = str_replace('#GROUP#', $group, $virtual_group_folder['mapped_path']);
194+
$virtual_group_folder['virtual_path'] = str_replace('#GROUP#', $group, $virtual_group_folder['virtual_path']);
195+
196+
$output['virtual_folders'][] = $virtual_group_folder;
197+
198+
// Defaulting to open permissions on the virtual group folder:
199+
$output['permissions'][$virtual_group_folder['virtual_path']] = ["*"];
200+
}
201+
}
202+
}
203+
}
204+
}
205+
}
206+
159207
return $output;
160208
}
161209

@@ -222,6 +270,39 @@ function homeDirectoryEntriesExist() {
222270
}
223271
}
224272

273+
function getUserGroups($user) {
274+
$groups = array();
275+
276+
if (isset($user['memberof'])) {
277+
if (isset($user['memberof']['count'])) {
278+
unset($user['memberof']['count']);
279+
}
280+
281+
foreach($user['memberof'] as $group) {
282+
$group = str_replace('CN=', '', $group);
283+
284+
$endGroupName = strpos($group, ',OU');
285+
286+
$group = substr($group, 0, $endGroupName);
287+
288+
// Perform uniformity transformations:
289+
$group = strtolower($group);
290+
$group = str_replace('#', '', $group);
291+
$group = str_replace('(', '', $group);
292+
$group = str_replace(')', '', $group);
293+
$group = str_replace(' ', '-', $group);
294+
$group = str_replace('&', 'and', $group);
295+
$group = preg_replace('/[^a-zA-Z0-9\-\._]/','', $group);
296+
297+
if (!empty($group)) {
298+
$groups[] = $group;
299+
}
300+
}
301+
}
302+
303+
return $groups;
304+
}
305+
225306
function logMessage($message, $extra = []) {
226307
if (defined('_SFTPGO_LOG') && _SFTPGO_LOG === true) {
227308
global $log;

0 commit comments

Comments
 (0)