Source

Target

Commits (56)
Showing with 743 additions and 667 deletions
+743 -667
......@@ -245,3 +245,9 @@ documentation and additional help.
* Matthew Newton <matthew.newton@networkradius.com>
EpochDays attributes as human readable
* Cass Rebbelin <Rebbelin@hisolutions.com>
PNG traversal path vulnerability
* Milan Stute <mstute@seemoo.tu-darmstadt.de>
Contributed Social Handlers for google scholar, Github, Matrix
## %"FusionDirectory 1.5" - 2025-02-24
### Added
#### fusiondirectory
- fd#6270 [Snapshot] - Enhancement in order to provide a first concept of revision and source reference
- fd#6301 [CORE] - Tasks Mail must take into account dynGroups
- fd#6302 [CORE][TASKS] - Tasks must be set as repeatable and updatable
- fd#6303 [CORE][MAIL] – Attachments for emails must be created as sub nodes
- fd#6305 [CORE][Task] - type mail should include a BCC field
- fd#6306 [CORE] - Issues of services not triggered by account deactivation via lock icon on user list
- fd#6307 [CORE] - Supann life cycle - automation via Orchestrator
- fd#6309 Support SSHA512 password if overlay pw-sha2 is installed
- fd#6314 [CORE] - Snapshots - review of the current automatic creation logic
- fd#6320 [Tasks] - Mail class can have one method static to be reused outside object call by others
- fd#6323 [Tasks] - LastExec is performed on localTime and should be set in UTC - always
- fd#6340 Add callerMAIL as macro in simplePlugin
- fd#6343 [CORE] - New directory structure numbering
- fd#6350 [Audit] - Account locked is not logged within audit upon clicking on the lock icon
- fd#6346 [Recovery] - Usage of supannMailPrivee within password recovery
- fd#6351 [core] - audit logging - allowing to see attributes => values within audit record. With hiding of values if required.
- fd#6352 [Core] - SimplePlugin - audit section (logging-modify) - must have a way to detect specific changes within a multi evaluated attributes
- fd#6354 [CORE] - Tasks - Allow subtasks to received helper information as form of references
- fd#6357 [core] - new token branch with new objectClass allowing management of specific tokens
- fd#6359 [Core] - Task - main menu allows periodicity of a cyclic setting - one element is empty
- fd#6361 Creat a column for showing a supanEtatDate
- fd#6365 [Core] - Reviewing how the locking mechanism logic work - general lock - supann lock.
#### fusiondirectory-plugins
- fd-plugins#6055 Add a basic kerberos plugin
- fd-plugins#6203 [Supann-Ex] - Verification of uniqueness, generation of hash based on login ID and time.
- fd-plugins#6241 Private form must not be related to the plugin invitations
- fd-plugins#6258 [NewPlugin] - Notifications, based on automatic snapshots, send email to required personal about attributes changes
- fd-plugins#6259 Proper way to manage supannCivilite
- fd-plugins#6260 Update yaml with the new screenshot and tags
- fd-plugins#6267 [webservice] - Force the usage of the timezone configured within FusionDirectory in order to avoid the default GMT
- fd-plugins#6277 [Mail] - Render mail unique all the time, not only if allowed to be used as authentication
- fd-plugins#6278 [LifeCycle] - Move lifeCycle from Core to Plugins
- fd-plugins#6285 [Audit] - A new task allowing a specific retention date of audit logs with automatic deletion
- fd-plugins#6290 [Notifications] - Allowing awareness on different supann states values
- fd-plugins#6298 [Audit] - Migration - obsolete attribute in backend config must be set - fdAuditRotationDelay
- fd-plugins#6299 [Supann] - supannMailPrivee should contains the following tag : {secours}
- fd-plugins#6300 [UserReminder] - New task allowing to send notification email when supannStatus "sursis" is at 30 and 15 days of ending the account
- fd-plugins#6301 [audit] - New backend allowing to hide certain attributes value recorded in audit logs
- fd-plugins#6305 [Plugins] - fdRPCwebserive - posix force_ids is not taken into consideration correctly
- fd-plugins#6306 [Notifications] - The Attributes list should not be mandatory - only supann resource.
- fd-plugins#6307 [Reminder] - Remove manager boolean as forward-to renders this redundant
- fd-plugins#6318 [Plugins] - supann - Reviewing how the locking mechanism logic work - general lock - supann lock.
- fd-plugins#6319 [Plugins] - Reviewing how the locking mechanism logic work - mail resource lock - zimbraAccountStatus update
### Changed
#### fusiondirectory
- fd#6300 [CORE] - UsersGroupsRolesAttribute attribute must include dyngroup as well
- fd#6321 [Tasks] - Make the generic tasks even more generic, allowing the object type string to be custom in case of added plugins
- fd#6324 [Tasks] - Main tasks create slave objects related to a DN - current definition of attributeAccess is string with lifeCycle description
- fd#6326 [Core] - Add orcid test method
- fd#6330 [new section] - Workflow to integrate sub menu such as mail template and tasks
- fd#6334 [CORE] - New behavior for template, automatic saving if no errors
- fd#6335 [Core] - A new branding and therefore new logo is now available for FusionDirectory
- fd#6364 [Core] - When lock mechanism is trigger - the user should not be editable if not unlock"
#### fusiondirectory-plugins
- fd-plugins#6249 Import eduPerson schema for orcid
- fd-plugins#6272 rename the certificate icon
- fd-plugins#6280 [Plugins] - update plugins to take into consideration the new directory of CORE structure
- fd-plugins#6302 [Plugins] - Sinaps - deactivate sinaps in backend when installed - allowing remaining system unblocked
- fd-plugins#6311 put the version 1.5 in all yaml for FusionDirectory 1.5 and change php version to 7.4
- fd-plugins#6321 [Plugins] - Unix - trust all report a dn unknown when * is set
### Removed
#### fusiondirectory
- fd#6333 [Core] - PhpSetup removal of the error collector mail to - considered not useful anymore
- fd#6337 [Core] - remove the legacy theme
- fd#6339 [Core] - remove leftover of dashboard in the core
- fd#6341 [LifeCycle] - Removal of lifeCycle within CORE
#### fusiondirectory-plugins
- fd-plugins#6271 remove the legacy theme
- fd-plugins#6275 remove leftover of dashboard in the core
- fd-plugins#6281 remove ldif from ppolicy plugin
### Fixed
#### fusiondirectory
- fd#6313 [CORE] - Snapshots - review of the current automatic creation logic
- fd#6331 Use replacement icons for the one now in the plugins
- fd#6332 Add an error log when the session is destroyed
- fd#6360 [Mail] - When supann is available - the supannMailPrivee and potentially other are detected with label
#### fusiondirectory-plugins
- fd-plugins#6081 Do not record empty memberUid within mixedgroups
- fd-plugins#6178 [Posix] - Template - TrustMode %askme% set as a service disables the entire table.
- fd-plugins#6205 [Zimbra] - Lifecycle of Zimbra account - Errors of re-activation and auto-activation not working.
- fd-plugins#6274 there is error in the variables_webauthn.inc are not correct for our packaged version
- fd-plugins#6246 Plugin dyngroups missing icons
- fd-plugins#6255 [Samba] - Samba tab cannot be removed when samba ID mapping is activated
- fd-plugins#6270 [Kerberos] - Issue declaring class invisible without attrs
- fd-plugins#6276 [GID - posix group] - issue with template not allowing to set GID.
- fd-plugins#6322 [Template] - Issue when creating a template with empty password, error message should not be seen
- fd-plugins#6309 there is a oid used twice in user-reminder
- fd-plugins#6312 [Plugins] - Reminder attributes fdTasksReminderRecipientsMembers should not be mandatory within ldap
- fd-plugins#6313 [fd-plugins] - User-reminder issue when supann is subStatus is set to none.
- fd-plugins#6314 [Plugins] - user-reminder force the nextSubState to be checked
- fd-plugins#6316 posix group not apply from user template
- fd-plugins#6323 [Supann] - Supann Civilites is marked as "values" and therefore is badly translated.
### Security
#### fusiondirectory
- fd#6363 [Security] - path traversal vulnerability - limited to png files
## %"FusionDirectory 1.4" - 2023-06-13
### Added
......@@ -25,7 +138,7 @@
- fd#5966 Management configuration system
- fd#5970 Allow plugins to easily take part in the user locking process
- fd#5976 icons missing in filter selections in core
- fd#5979 Samba and FD
- fd#5979 Samba and Fusiondirectory
- fd#5980 Management should be a bit more flexible
- fd#5986 Add a reinitialisation button for the management configuration
- fd#5999 Allow ObjectsAttribute instances to specify filter elements
......
......@@ -64,33 +64,20 @@ Be aware that if your naming policy of user cn's differs from the way FusionDire
### Community support
There are a couple ways you can try [to get help][get help].You can also join the `#fusiondirectory` IRC channel at libera.chat.
There are a couple of ways you can try [to get help][get help].
### Professional support
Professional support is provided through of subscription.
We have two type of subscription :
* [FusionDirectory Subscription][subscription-fusiondirectory] : Global subscription for FusionDirectory
* [FusionDirectory][subscription-fusiondirectory] : Global subscription for FusionDirectory and all the plugins
* [FusionDirectory Plus][subscription-fusiondirectory-plus] : Expert Support on Education, Deployement and Infrastructure plugins
The subscription provides access to FusionDirectory's stable enterprise repository, providing reliable software updates and security enhancements,
as well as technical help and support.
The subscription provides access to FusionDirectory's enterprise repository, tested and pre-packaged versions with patches between versions,
providing reliable software updates and security enhancements, as well as technical help and support.
Choose the plan that's right for you. Our subscriptions are flexible and scalable according to your needs
The subscription period is one year from the date of purchase and gives you access to the extensive infrastructure of enterprise-class software and services.
## IRC Etiquette
* If we don't answer right away then just hang out in the channel. Someone will
eventually write back to you as it just means we are away from keyboard,
working on something else, or in a different timezone than you.
* You should treat IRC as what it is: asynchronous chat. Sure the messages can
be instant but in most channels people are in different time zones. At times
chat replies can be in excess of 24hrs.
The subscription period is one year from the date of purchase and provides you with access to the extensive infrastructure of enterprise-class software and services.
### Best practice badge
......@@ -98,15 +85,13 @@ The subscription period is one year from the date of purchase and gives you acce
## Crowfunding
If you like us and want to send us a small contribution you can use the following crowfunding services
If you like us and want to send us a small contribution, you can use the following crowdfunding services
* [donate-liberapay]
* [donate-kofi]
* [donate-opencollective]
* [donate-communitybridge]
* [donate-github]
## License
......@@ -114,13 +99,11 @@ If you like us and want to send us a small contribution you can use the followin
[FusionDirectory]: https://www.fusiondirectory.org/
[fusiondirectory-install]: https://fusiondirectory-user-manual.readthedocs.io/en/1.4/fusiondirectory/install/index.html
[get help]: https://www.fusiondirectory.org/en/communaute/
[fusiondirectory-install]: https://fusiondirectory-user-manual.readthedocs.io/en/latest/fusiondirectory/install/index.html
[subscription-fusiondirectory]: https://www.fusiondirectory.org/en/subscription-fusiondirectory/
[get help]: https://fusiondirectory-user-manual.readthedocs.io/en/latest/support/index.html
[subscription-fusiondirectory-plus]: https://www.fusiondirectory.org/en/subscriptions-fusiondirectory-plus/
[subscription-fusiondirectory]: https://www.fusiondirectory.org/en/iam-tool-service-subscriptions/
[register]: https://register.fusiondirectory.org
......@@ -128,6 +111,5 @@ If you like us and want to send us a small contribution you can use the followin
[donate-kofi]: https://ko-fi.com/fusiondirectory
[donate-opencollective]: https://opencollective.com/fusiondirectory
[donate-github]: https://github.com/fusiondirectory
[donate-communitybridge]: https://funding.communitybridge.org/projects/fusiondirectory
......@@ -3465,6 +3465,144 @@ interfaces for this, run the **fusiondirectory-migration-manager
fusiondirectory-migration-manager --migrate-interfaces
```
Migrate FusionDirectory from 1.4 to 1.5
=======================================
Upgrade FusionDirectory first
-----------------------------
Upgrade FusionDirectory core package before other ones to avoid
dependencies errors:
``` {.shell}
apt-get install fusiondirectory
```
Upgrade FusionDirectory schema package too.
``` {.shell}
apt-get install fusiondirectory-schema
```
Upgrade of LDAP directory
-------------------------
Then update the core-fd-conf schema.
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/core-fd-conf.schema
```
Then update the core-fd schema.
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/core-fd.schema
```
if you are using the audit plugin plugin you have to update is schema
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/audit-fd-conf.schema
```
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/audit-fd.schema
```
if you are using the public-forms plugin you have to update is schema
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/public-forms-fd-conf.schema
```
if you are using the supann plugin you have to update is schema and
install a new one
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/internet2.schema
```
``` {.shell}
fusiondirectory-schema-manager --insert-schema /etc/ldap/schema/fusiondirectory/eduperson.schema
```
``` {.shell}
fusiondirectory-schema-manager --replace-schema /etc/ldap/schema/fusiondirectory/supann-fd-conf.schema
```
Check for deprecated attributes and objectClasses in your LDAP
--------------------------------------------------------------
- **fusiondirectory-migration-manager \-\--list-deprecated** to list
deprecated attributes and objectclasses
Deprecated attributes:
``` {.shell}
fusiondirectory-migration-manager --list-deprecated List deprecated attributes and objectclasses Deprecated attributes:
Deprecated attributes:
gotoLogonScript (GOto - specifies a LogonScript) - 1.3.6.1.4.1.10098.1.1.11.10
gosaDefaultPrinter (Defines a default printer a user owns) - 1.3.6.1.4.1.10098.1.1.12.13
gotoHotplugDevice (GOto - keeps hotplug devices) - 1.3.6.1.4.1.10098.1.1.11.14
gotoHotplugDeviceDN (GOto - points to hotplug devices) - 1.3.6.1.4.1.10098.1.1.11.18
gotoLogoffScript (GOto - specifies a LogoffScript) - 1.3.6.1.4.1.10098.1.1.11.19
gotoSyslogServer (GOto - Gonicus Terminal Concept, value syslogServer.) - 1.3.6.1.4.1.10098.1.1.1.1
gotoMode (GOto - Gonicus Terminal Concept, Terminal is active.) - 1.3.6.1.4.1.10098.1.1.1.24
gotoLdapServer (LDAP server to use) - 1.3.6.1.4.1.10098.1.1.1.38
gosaMailMaxSize (Block mails bigger than this value) - 1.3.6.1.4.1.10098.1.1.12.8
gosaSpamSortLevel (Spamassassins hits) - 1.3.6.1.4.1.10098.1.1.12.9
gosaSpamMailbox (Where to put spam) - 1.3.6.1.4.1.10098.1.1.12.10
argonautLdap2zoneAllowNotify (Fusion Directory - Argonaut, allow notify.) - 1.3.6.1.4.1.38414.2.13.2
fdPpolicyDefaultCn (FusionDirectory - cn of the default ppolicy) - 1.3.6.1.4.1.38414.45.1.2
fdHttpAuthActivated (FusionDirectory - HTTP Basic Auth activation) - 1.3.6.1.4.1.38414.8.15.6
fdHttpHeaderAuthActivated (FusionDirectory - HTTP Header Auth activation) - 1.3.6.1.4.1.38414.8.15.7
fdCasActivated (FusionDirectory - CAS activation) - 1.3.6.1.4.1.38414.8.21.1
fdAuditRotationDelay (FusionDirectory - Actions to be stored by audit plugin) - 1.3.6.1.4.1.38414.61.1.3
```
Deprecated objectClasses:
``` {.shell}
Deprecated objectClasses:
gotoTerminal (GOto - Gonicus Terminal Concept, objectclass) - 1.3.6.1.4.1.10098.1.2.1.1
gotoWorkstation (GOto - Gonicus Terminal Concept, objectclass) - 1.3.6.1.4.1.10098.1.2.1.30
gotoPrinter (GOto - Gonicus Terminal Concept, objectclass) - 1.3.6.1.4.1.10098.1.2.1.31
gotoEnvironment (GOto - contains environment settings) - 1.3.6.1.4.1.10098.1.2.1.32
gotoWorkstationTemplate (GOto - Gonicus Terminal Concept, objectclass) - 1.3.6.1.4.1.10098.1.2.1.34
gotoTerminalTemplate (GOto - Gonicus Terminal Concept, objectclass) - 1.3.6.1.4.1.10098.1.2.1.35
gotoDevice (GOto - contains environment settings) - 1.3.6.1.4.1.10098.1.2.1.42
GOhard (Gonicus Hardware definitions, objectclass) - 1.3.6.1.4.1.10098.1.2.1.3
goServer (Server description) - 1.3.6.1.4.1.10098.1.2.1.27
fdAsteriskPluginConf (FusionDirectory asterisk plugin configuration) - 1.3.6.1.4.1.38414.19.2.1
```
- **fusiondirectory-migration-manager \-\--check-deprecated** will
output a list of dn using old attributes and objectClasses
``` {.shell}
fusiondirectory-migration-manager --check-deprecated
cn=config,ou=fusiondirectory,dc=formation-fusiondirectory,dc=org contains an obsolete attribute
There are no entries in the LDAP using obsolete classes
```
- **fusiondirectory-migration-manager \-\--ldif-deprecated** will
output an ldif file on the console that you can use with ldapmodify
to clean you ldap server from old attributes.
``` {.shell}
fusiondirectory-migration-manager --ldif-deprecated
dn:cn=config,ou=fusiondirectory,dc=formation-fusiondirectory,dc=org
changetype:modify
delete:fdAuditRotationDelay
-
# There are no entries in the LDAP using obsolete classes
```
If they are old objectClasses it will warn you and you will have to remove it by hand,
they have been specified at the **fusiondirectory-migration-manager ---check-deprecated** step.
[php-cas]: http://packages.ubuntu.com/trusty/all/php-cas/download
......@@ -3476,14 +3614,11 @@ fusiondirectory-migration-manager --migrate-interfaces
To improve this piece of software, please report all kind of errors using the bug tracker
on https://gitlab.fusiondirectory.org
Documentation: https://fusiondirectory-user-manual.readthedocs.io/en/1.4/index.html
Documentation: https://fusiondirectory-user-manual.readthedocs.io/en/latest/index.html
Mailinglist: https://lists.fusiondirectory.org/
Irc: #fusiondirectory on libera.chat
---
The FusionDirectory project https://www.fusiondirectory.org/
Enjoy :)
......@@ -478,6 +478,12 @@ attributetype ( 1.3.6.1.4.1.38414.8.19.2 NAME 'fdForceSaslPasswordAsk'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.38414.8.19.3 NAME 'fdOGroupDefaultUser'
DESC 'FusionDirectory - Create a default user in ou=restricted for object groups'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )
# SSL
attributetype ( 1.3.6.1.4.1.38414.8.20.1 NAME 'fdSslCaCertPath'
......@@ -556,6 +562,29 @@ attributetype ( 1.3.6.1.4.1.38414.8.21.8 NAME 'fdCasClientServiceName'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
# FusionDirectory Tokens
attributetype ( 1.3.6.1.4.1.38414.8.22.1 NAME 'fdTokenRDN'
DESC 'FusionDirectory - Branch where FusionDirectory Tokens are stored'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.38414.8.22.2 NAME 'fdOrchestratorTokenRDN'
DESC 'FusionDirectory - Branch where FusionDirectory Orchestrator Tokens are stored'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.38414.8.22.3 NAME 'fdrecoveryTokenRDN'
DESC 'FusionDirectory - Branch where FusionDirectory Recovery Tokens are stored'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
# merged from dashboard-fd.schema - Needed by Fusion Directory for dashboard options
attributetype ( 1.3.6.1.4.1.38414.27.1.1 NAME 'fdDashboardPrefix'
......@@ -670,14 +699,15 @@ objectclass ( 1.3.6.1.4.1.38414.8.2.1 NAME 'fusionDirectoryConf'
fdIncrementalModifierStates $
fdSslCaCertPath $ fdSslKeyPath $ fdSslCertPath $ fdSnapshotRetentionDays $ fdSnapshotSourceData $
fdCasActivated $ fdCasServerCaCertPath $ fdCasHost $ fdCasPort $ fdCasContext $ fdCasVerbose $
fdLoginMethod $ fdCasLibraryBool $ fdCasClientServiceName $ fdEnableAutomaticSnapshots $ fdSnapshotMinRetention
fdLoginMethod $ fdCasLibraryBool $ fdCasClientServiceName $ fdEnableAutomaticSnapshots $ fdSnapshotMinRetention $
fdTokenRDN $ fdOrchestratorTokenRDN $ fdrecoveryTokenRDN
) )
objectclass ( 1.3.6.1.4.1.38414.8.2.2 NAME 'fusionDirectoryPluginsConf'
DESC 'FusionDirectory plugins configuration'
SUP top AUXILIARY
MUST ( cn )
MAY ( fdOGroupRDN $ fdForceSaslPasswordAsk ) )
MAY ( fdOGroupRDN $ fdForceSaslPasswordAsk $ fdOGroupDefaultUser ) )
objectclass ( 1.3.6.1.4.1.38414.8.2.3 NAME 'fdPasswordRecoveryConf'
DESC 'FusionDirectory password recovery configuration'
......
......@@ -552,6 +552,6 @@ objectclass (1.3.6.1.4.1.38414.62.2.9 NAME 'fdTasksConf'
### token objectclass ###
objectclass ( 1.3.6.1.4.1.38414.62.2.11 NAME 'fdTokenEntry'
SUP top AUXILIARY
SUP top STRUCTURAL
DESC 'FusionDirectory - Class for token storage'
MUST ( fdTokenUserDN $ fdTokenType $ fdToken $ fdTokenTimestamp ))
\ No newline at end of file
MUST ( cn $ fdTokenUserDN $ fdTokenType $ fdToken $ fdTokenTimestamp ))
\ No newline at end of file
......@@ -25,6 +25,7 @@ class ThemeFileParsingException extends Exception
/*!
* \brief Icon theme directory
*/
class IconThemeDir
{
/* Nominal (unscaled) size of the icons in this directory.
......@@ -43,7 +44,7 @@ class IconThemeDir
* Valid types are Fixed, Scalable and Threshold.
* The type decides what other keys in the section are used.
* If not specified, the default is Threshold. */
private $Type = 'Threshold';
private $Type = 'Threshold';
/* The icons in this directory can be used if the size differ at most this much from the desired (unscaled) size.
* Defaults to 2 if not present. */
......@@ -51,9 +52,9 @@ class IconThemeDir
function __construct ($infos)
{
$this->Size = $infos['Size'];
$this->MinSize = $infos['Size'];
$this->MaxSize = $infos['Size'];
$this->Size = $infos['Size'];
$this->MinSize = $infos['Size'];
$this->MaxSize = $infos['Size'];
foreach (['Type', 'MaxSize', 'MinSize', 'Threshold'] as $key) {
if (isset($infos[$key])) {
$this->$key = $infos[$key];
......@@ -100,6 +101,7 @@ class IconThemeDir
/*!
* \brief Icon theme
*/
class IconTheme
{
private $subdirs = [];
......@@ -109,12 +111,12 @@ class IconTheme
function __construct ($folder, $default_parent)
{
$this->path = $folder;
$datas = @parse_ini_file($folder.'/index.theme', TRUE, INI_SCANNER_RAW);
$datas = @parse_ini_file($folder . '/index.theme', TRUE, INI_SCANNER_RAW);
if ($datas === FALSE) {
throw new ThemeFileParsingException('Error while parsing theme file');
}
if (isset($datas['Icon Theme']['Directories']) && !empty($datas['Icon Theme']['Directories'])) {
$dirs = preg_split('/,/', $datas['Icon Theme']['Directories']);
$dirs = preg_split('/,/', $datas['Icon Theme']['Directories']);
foreach ($dirs as $name) {
if (isset($datas[$name])) {
$this->subdirs[strtolower($datas[$name]['Context'])][$name] = new IconThemeDir($datas[$name]);
......@@ -141,8 +143,8 @@ class IconTheme
if ($filename != NULL) {
return $filename;
}
if (isset(static::$fallbacks[$context.'/'.$icon])) {
foreach (static::$fallbacks[$context.'/'.$icon] as $fallback) {
if (isset(static::$fallbacks[$context . '/' . $icon])) {
foreach (static::$fallbacks[$context . '/' . $icon] as $fallback) {
$filename = $this->LookupIcon($fallback[0], $fallback[1], $size);
if ($filename != NULL) {
return $filename;
......@@ -169,7 +171,7 @@ class IconTheme
foreach ($this->subdirs[$context] as $path => &$subdir) {
if ($subdir->MatchesSize($size)) {
foreach (static::$extensions as $extension) {
$filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension;
$filename = $this->path . '/' . $path . '/' . $iconname . '.' . $extension;
if (file_exists($filename)) {
return $filename;
}
......@@ -182,7 +184,7 @@ class IconTheme
foreach ($this->subdirs[$context] as $path => &$subdir) {
if (($sizedistance = $subdir->SizeDistance($size)) < $minimal_size) {
foreach (static::$extensions as $extension) {
$filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension;
$filename = $this->path . '/' . $path . '/' . $iconname . '.' . $extension;
if (file_exists($filename)) {
$closest_filename = $filename;
$minimal_size = $sizedistance;
......@@ -198,12 +200,12 @@ class IconTheme
return NULL;
}
static public $default_theme = 'breezy';
static public $extensions = ['png', 'xpm', 'svg'];
static public $find_closest = FALSE;
static public $default_theme = 'breezy';
static public $extensions = ['png', 'xpm', 'svg'];
static public $find_closest = FALSE;
/* We store themes in the session. To do otherwise, override these methods. */
static public $session_var = 'IconThemes';
static public $session_var = 'IconThemes';
static public function loadThemes ($path)
{
......@@ -228,6 +230,11 @@ class IconTheme
static public function findThemeIcon ($theme, $context, $icon, $size)
{
// We have to sanitize the $icon received from $_GET['icon']. Fixing vulnerability : CWE-35
if (!preg_match('/^[a-zA-Z0-9_\-]+$/', $icon)) {
trigger_error('Error: Wrong icon name received');
die('Error: wrong icon name received');
}
if (!isset($_SESSION[static::$session_var])) {
trigger_error('Error: no theme found in session');
die('Error: no theme found in session');
......@@ -248,162 +255,162 @@ class IconTheme
/* Fallback system */
static public $fallbacks = [
'types/user-group' => [
['applications','system-users']
'types/user-group' => [
['applications', 'system-users']
],
'types/resource-group' => [
['actions','resource-group']
'types/resource-group' => [
['actions', 'resource-group']
],
'types/user' => [
['places','user-identity'],
['status','avatar-default'],
'types/user' => [
['places', 'user-identity'],
['status', 'avatar-default'],
],
'types/contact' => [
['mimetypes','x-office-contact'],
'types/contact' => [
['mimetypes', 'x-office-contact'],
],
'types/certificate' => [
['mimetypes','stock_certificate'],
['mimetypes','application-certificate'],
['actions','view-certificate'],
'types/certificate' => [
['mimetypes', 'stock_certificate'],
['mimetypes', 'application-certificate'],
['actions', 'view-certificate'],
],
'applications/user-info' => [
['actions','user-properties'],
['types','contact'],
['mimetypes','x-office-contact'],
['types','user'],
['places','user-identity'],
['status','avatar-default'],
'applications/user-info' => [
['actions', 'user-properties'],
['types', 'contact'],
['mimetypes', 'x-office-contact'],
['types', 'user'],
['places', 'user-identity'],
['status', 'avatar-default'],
],
'applications/office-calendar' => [
['mimetypes','x-office-calendar'],
'applications/office-calendar' => [
['mimetypes', 'x-office-calendar'],
],
'applications/os-linux' => [
['applications','linux'],
'applications/os-linux' => [
['applications', 'linux'],
],
'applications/os-windows' => [
['applications','windows'],
'applications/os-windows' => [
['applications', 'windows'],
],
'applications/samba' => [
['applications','os-windows'],
['applications','windows'],
'applications/samba' => [
['applications', 'os-windows'],
['applications', 'windows'],
],
'applications/config-language' => [
['applications','locale'],
['applications','preferences-desktop-locale'],
'applications/config-language' => [
['applications', 'locale'],
['applications', 'preferences-desktop-locale'],
],
'mimetypes/text-csv' => [
['mimetypes','x-office-spreadsheet'],
['mimetypes','text-x-generic'],
'mimetypes/text-csv' => [
['mimetypes', 'x-office-spreadsheet'],
['mimetypes', 'text-x-generic'],
],
'mimetypes/application-pdf' => [
['mimetypes','x-office-document'],
'mimetypes/application-pdf' => [
['mimetypes', 'x-office-document'],
],
'actions/application-exit' => [
['actions','system-log-out'],
'actions/application-exit' => [
['actions', 'system-log-out'],
],
'actions/archive' => [
['mimetypes','application-x-archive'],
'actions/archive' => [
['mimetypes', 'application-x-archive'],
],
'actions/document-export' => [
['actions','document-send'],
'actions/document-export' => [
['actions', 'document-send'],
],
'actions/download' => [
['actions','document-save'],
'actions/download' => [
['actions', 'document-save'],
],
'actions/document-restore' => [
['actions','document-import'],
['actions','document-open'],
'actions/document-restore' => [
['actions', 'document-import'],
['actions', 'document-open'],
],
'actions/document-edit' => [
['actions','edit'],
['applications','text-editor'],
['applications','accessories-text-editor'],
['actions','document-open'],
'actions/document-edit' => [
['actions', 'edit'],
['applications', 'text-editor'],
['applications', 'accessories-text-editor'],
['actions', 'document-open'],
],
'actions/snapshot' => [
['actions','document-save'],
'actions/snapshot' => [
['actions', 'document-save'],
],
'actions/system-reboot' => [
['actions','view-refresh'],
'actions/system-reboot' => [
['actions', 'view-refresh'],
],
'actions/system-update' => [
['applications','system-software-update'],
'actions/system-update' => [
['applications', 'system-software-update'],
],
'actions/system-reinstall' => [
['applications','system-installer'],
'actions/system-reinstall' => [
['applications', 'system-installer'],
],
'actions/task-start' => [
['actions','media-playback-start'],
'actions/task-start' => [
['actions', 'media-playback-start'],
],
'actions/task-stop' => [
['actions','media-playback-stop'],
'actions/task-stop' => [
['actions', 'media-playback-stop'],
],
'actions/task-schedule' => [
['actions','chronometer'],
['actions','smallclock'],
'actions/task-schedule' => [
['actions', 'chronometer'],
['actions', 'smallclock'],
],
'actions/up' => [
['actions','go-up'],
['actions','arrow-up'],
'actions/up' => [
['actions', 'go-up'],
['actions', 'arrow-up'],
],
'actions/upload' => [
['actions','document-import'],
['actions','up'],
'actions/upload' => [
['actions', 'document-import'],
['actions', 'up'],
],
'actions/down' => [
['actions','go-down'],
['actions','arrow-down'],
'actions/down' => [
['actions', 'go-down'],
['actions', 'arrow-down'],
],
'actions/previous' => [
['actions','go-previous'],
['actions','arrow-left'],
'actions/previous' => [
['actions', 'go-previous'],
['actions', 'arrow-left'],
],
'actions/next' => [
['actions','go-next'],
['actions','arrow-right'],
'actions/next' => [
['actions', 'go-next'],
['actions', 'arrow-right'],
],
'actions/submit' => [
['actions','go-jump'],
'actions/submit' => [
['actions', 'go-jump'],
],
'categories/settings' => [
['categories','gnome-settings'],
['categories','preferences-other'],
['categories','preferences-system'],
'categories/settings' => [
['categories', 'gnome-settings'],
['categories', 'preferences-other'],
['categories', 'preferences-system'],
],
'categories/checks' => [
['actions','view-task'],
['actions','view-calendar-tasks'],
['actions','checkbox'],
['status','task-complete'],
'categories/checks' => [
['actions', 'view-task'],
['actions', 'view-calendar-tasks'],
['actions', 'checkbox'],
['status', 'task-complete'],
],
'devices/server' => [
['places','server'],
['places','network-server'],
'devices/server' => [
['places', 'server'],
['places', 'network-server'],
],
'devices/media-cdrom' => [
['devices','media-optical'],
'devices/media-cdrom' => [
['devices', 'media-optical'],
],
'devices/terminal' => [
['applications','utilities-terminal'],
'devices/terminal' => [
['applications', 'utilities-terminal'],
],
'devices/computer-windows' => [
['applications','os-windows'],
['applications','windows'],
'devices/computer-windows' => [
['applications', 'os-windows'],
['applications', 'windows'],
],
'devices/template' => [
['actions','document-new'],
'devices/template' => [
['actions', 'document-new'],
],
'status/object-locked' => [
['status','changes-prevent'],
'status/object-locked' => [
['status', 'changes-prevent'],
],
'status/object-unlocked' => [
['status','changes-allow'],
'status/object-unlocked' => [
['status', 'changes-allow'],
],
'status/task-waiting' => [
['actions','task-schedule'],
'status/task-waiting' => [
['actions', 'task-schedule'],
],
'places/folder-network' => [
['places','folder-remote'],
'places/folder-network' => [
['places', 'folder-remote'],
],
];
}
......@@ -37,7 +37,7 @@ class Lock
/*!
* \brief Add a lock for object(s)
*
* Adds a lock by the specified user for one ore multiple objects.
* Adds a lock by the specified user for one or multiple objects.
* If a lock for that object already exists from another user, an error is triggered.
*
* \param array $object The object or array of objects to lock
......
......@@ -166,7 +166,7 @@ class passwordRecovery extends standAlonePage
$ldap = $config->get_ldap_link();
// Check if token branch is here
$token = get_ou('recoveryTokenRDN') . get_ou('fusiondirectoryRDN') . $config->current['BASE'];
$token = get_ou('recoveryTokenRDN') . get_ou('tokenRDN') . $config->current['BASE'];
$ldap->cat($token, ['dn']);
if (!$ldap->count()) {
/* It's not, let's create it */
......@@ -219,7 +219,7 @@ class passwordRecovery extends standAlonePage
/* Retrieve hash from the ldap */
$ldap = $config->get_ldap_link();
$token = get_ou('recoveryTokenRDN') . get_ou('fusiondirectoryRDN') . $config->current['BASE'];
$token = get_ou('recoveryTokenRDN') . get_ou('tokenRDN') . $config->current['BASE'];
$dn = 'ou=' . $this->login . ',' . $token;
$ldap->cat($dn);
$attrs = $ldap->fetch();
......
......@@ -370,7 +370,7 @@ class tests
public static function is_orcid ($orcid)
{
/* Remove hyphens, remove last digit, convert to array */
$baseDigits = str_split(str_replace('-', '', substr($orcid, 0, -1)));
$baseDigits = str_split(str_replace('-', '', $orcid));
$sum = 0;
foreach ($baseDigits as $baseDigit) {
$sum = ($sum + (int)$baseDigit) * 2;
......
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2003-2010 Cajus Pollmeier
Copyright (C) 2011-2018 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*!
* \file class_csvExporter.inc
* Source code for class csvExporter
*/
/*!
* \brief This class contains all the functions needed for csv export
*/
class csvExporter
{
var $result;
/*!
* \brief Create a csvExporter
*
* \param array $headline
*
* \param array $header
*
* \param array $entries
*
* \param array $columns
*/
function __construct ($headline, $header, $entries, $columns = [])
{
// If no preset, render all columns
if (!count($columns)) {
foreach ($header as $index => $dummy) {
$columns[] = $index;
}
}
// Generate header
$this->result = '#';
foreach ($columns as $index) {
if (isset($header[$index])) {
$this->result .= trim(html_entity_decode($header[$index], ENT_QUOTES, 'UTF-8').";");
} else {
$this->result .= ";";
}
}
$this->result = preg_replace('/;$/', '', $this->result)."\n";
// Append entries
foreach ($entries as $row) {
foreach ($columns as $index) {
if (isset($row["_sort$index"])) {
$this->result .= trim(html_entity_decode($row["_sort$index"], ENT_QUOTES, 'UTF-8')).";";
} else {
$this->result .= ";";
}
}
$this->result = preg_replace('/;$/', '', $this->result)."\n";
}
}
/*!
* \brief Get the result
*/
function query ()
{
return $this->result;
}
static function export (managementListing $listing)
{
$columns = $listing->getColumns();
$iterator = $listing->getIterator();
// Generate header
$result = '#';
foreach ($columns as $column) {
if ($column->isExportable()) {
$result .= $column->getLabel().';';
}
}
$result = preg_replace('/;$/', '', $result)."\n";
// Append entries
foreach ($iterator as $entry) {
foreach ($columns as $column) {
if ($column->isExportable()) {
$result .= implode(',', $column->getRawExportValues($entry)).';';
}
}
$result = preg_replace('/;$/', '', $result)."\n";
}
return $result;
}
/*!
* \brief Get Informations
*/
static function getInfo ()
{
return ["exportCSV" => [ "label" => _("CSV"), "image" => "geticon.php?context=mimetypes&icon=text-csv&size=16", "class" => "csvExporter", "mime" => "text/x-csv", "filename" => "export.csv" ]];
}
}
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2003-2010 Cajus Pollmeier
Copyright (C) 2011-2016 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*!
* \file class_pdfExporter.inc
* Source code for class pdfExporter
*/
// Try to load PDF library
@include_once(FPDF);
// Load supporter class only if FPDF is loaded
$classes = get_declared_classes();
if (in_array('FPDF', $classes)) {
include('class_PDF.php');
}
/*!
* \brief This class contains all the functions needed for pdf export
*/
class pdfExporter
{
var $result;
/*!
* \brief Export PDF
*
* \param array $headline
*
* \param array $header
*
* \param array $entries
*
* \param array $columns
*/
function __construct ($headline, $header, $entries, $columns = [])
{
// Bail out if no FPDF available
if (!class_exists('FPDF')) {
die(_("No PDF export possible: there is no FPDF library installed."));
}
// If no preset, render all columns
if (!count($columns)) {
$columns = array_keys($header);
}
// Create new PDF
$this->result = new PDF('L', 'mm', 'A4');
$this->result->AliasNbPages();
$this->result->SetFont('Helvetica', '', 10);
$this->result->setHeadline(utf8_decode($headline));
$this->result->AddPage();
// Analyze for width
$width = $this->calcWidth($header, $entries, $columns);
// Render head
$this->result->SetFont('', 'B');
$this->result->SetTextColor(0);
$this->result->SetDrawColor(0, 0, 0);
$this->result->SetLineWidth(.3);
// Height calculator
$height = 0;
$fill = FALSE;
foreach ($entries as $row) {
// Render header
if ($height == 0) {
// Generate header
$this->result->SetFillColor(230, 230, 230);
$this->result->SetFont('', 'B');
foreach ($columns as $order => $index) {
if (isset($header[$index])) {
$this->result->Cell($width[$order], 7, utf8_decode($header[$index]), 1, 0, 'C', 1);
} else {
$this->result->Cell($width[$order], 7, '', 1, 0, 'C', 1);
}
}
$this->result->Ln();
$height = 7;
// Set entry collors
$this->result->SetFillColor(240, 240, 240);
$this->result->SetFont('');
}
foreach ($columns as $order => $index) {
if (isset($row["_sort$index"])) {
$this->result->Cell($width[$order], 6, utf8_decode($row["_sort$index"]), 'LR', 0, 'L', $fill);
} else {
$this->result->Cell($width[$order], 6, '', 'LR', 0, 'L', $fill);
}
}
$this->result->Ln();
// Increase height to eventually create new page
$height += 8;
if ($height > 220) {
$height = 0;
$this->result->Cell(array_sum($width), 0, '', 'T');
$this->result->AddPage();
$fill = FALSE;
} else {
$fill = !$fill;
}
}
$this->result->Cell(array_sum($width), 0, '', 'T');
}
/*!
* \brief Calculate the width page
*
* \param array $header
*
* \param array $entries
*
* \param array $columns
*/
function calcWidth ($header, $entries, $columns)
{
$width = [];
// Locate longest value for each column
foreach ($columns as $index) {
$max = 0;
if (isset($header[$index])) {
$len = $this->result->GetStringWidth($header[$index]);
if ($len > $max) {
$max = $len;
}
}
foreach ($entries as $row) {
if (isset($row["_sort$index"])) {
$len = $this->result->GetStringWidth($row["_sort$index"]);
if ($len > $max) {
$max = $len;
}
}
}
$width[] = $max;
}
// Scale to page width
$printWidth = 280;
$scale = $printWidth / array_sum($width);
foreach ($width as &$w) {
$w *= $scale;
}
unset($w);
return $width;
}
/*!
* \brief Calculate the width page
*/
static function calcColumnsWidth ($result, $columns, $iterator)
{
$width = [];
// Locate longest value for each column
foreach ($columns as $index => $column) {
if (!$column->isExportable()) {
continue;
}
$max = 0;
$len = $result->GetStringWidth($column->getLabel());
if ($len > $max) {
$max = $len;
}
foreach ($iterator as $entry) {
$len = $result->GetStringWidth(implode(',', $column->getRawExportValues($entry)));
if ($len > $max) {
$max = $len;
}
}
$width[$index] = $max;
}
// Scale to page width
$printWidth = 280;
$scale = $printWidth / array_sum($width);
foreach ($width as &$w) {
$w *= $scale;
}
unset($w);
return $width;
}
/*!
* \brief Get the result
*/
function query ()
{
return $this->result->Output("", "S");
}
static function export (managementListing $listing)
{
global $ui;
// Bail out if no FPDF available
if (!class_exists('FPDF')) {
die(_('No PDF export possible: there is no FPDF library installed.'));
}
$columns = $listing->getColumns();
$iterator = $listing->getIterator();
// Create new PDF
$result = new PDF('L', 'mm', 'A4');
$result->AliasNbPages();
$result->SetFont('Helvetica', '', 10);
$headline = $listing->parent->headline;
$headline .= ', '._('created by').' '.$ui->cn.' - '.strftime('%A, %d. %B %Y, %H:%M:%S');
$result->setHeadline(utf8_decode($headline));
$result->AddPage();
// Analyze for width
$width = static::calcColumnsWidth($result, $columns, $iterator);
// Render head
$result->SetTextColor(0);
$result->SetDrawColor(0, 0, 0);
$result->SetLineWidth(.3);
// Render header
$result->SetFillColor(230, 230, 230);
$result->SetFont('', 'B');
foreach ($columns as $index => $column) {
if ($column->isExportable()) {
$result->Cell($width[$index], 7, utf8_decode($column->getLabel()), 1, 0, 'C', 1);
}
}
$result->Ln();
$height = 7;
// Set entry colors
$result->SetFillColor(240, 240, 240);
$result->SetFont('');
$fill = TRUE;
foreach ($iterator as $entry) {
if ($height > 220) {
$height = 0;
$result->Cell(array_sum($width), 0, '', 'T');
$result->AddPage();
$fill = FALSE;
} else {
$fill = !$fill;
}
foreach ($columns as $index => $column) {
if ($column->isExportable()) {
$result->Cell(
$width[$index],
6,
implode(
',',
array_map(
'utf8_decode',
$column->getRawExportValues($entry)
)
),
'LR',
0,
'L',
$fill
);
}
}
$result->Ln();
// Increase height to eventually create new page
$height += 8;
}
$result->Cell(array_sum($width), 0, '', 'T');
return $result->Output('', 'S');
}
/*!
* \brief Get informations
*/
static function getInfo ()
{
// Check if class defined
$classes = get_declared_classes();
if (in_array('FPDF', $classes)) {
return ["exportPDF" => [ "label" => _("PDF"), "image" => "geticon.php?context=mimetypes&icon=application-pdf&size=16", "class" => "pdfExporter", "mime" => "application/pdf", "filename" => "export.pdf" ]];
} else {
return NULL;
}
}
}
......@@ -395,6 +395,8 @@ function get_ou ($name)
$map = [
'fusiondirectoryRDN' => 'ou=fusiondirectory,',
'lockRDN' => 'ou=locks,',
'tokenRDN' => 'ou=tokens,',
'orchestratorTokenRDN' => 'ou=orchestrator,',
'recoveryTokenRDN' => 'ou=recovery,',
'reminderTokenRDN' => 'ou=reminder,',
'roleRDN' => 'ou=roles,',
......
......@@ -70,8 +70,6 @@ class management implements FusionDirectoryDialog
protected $actions = [];
protected $actionHandlers = [];
protected $exporters = [];
public $neededAttrs = [];
public static $skipTemplates = TRUE;
......@@ -131,16 +129,6 @@ class management implements FusionDirectoryDialog
$this->snapHandler = new SnapshotHandler();
}
// Load exporters
foreach (array_keys($class_mapping) as $class) {
if (preg_match('/Exporter$/', $class)) {
$info = call_user_func([$class, 'getInfo']);
if ($info != NULL) {
$this->exporters = array_merge($this->exporters, $info);
}
}
}
$this->configureActions();
}
......@@ -224,21 +212,6 @@ class management implements FusionDirectoryDialog
)
);
// Add export actions
$exportMenu = [];
foreach ($this->exporters as $action => $exporter) {
$exportMenu[] = new Action(
$action, $exporter['label'], $exporter['image'],
'0', 'export'
);
}
$this->registerAction(
new SubMenuAction(
'export', _('Export list'), 'geticon.php?context=actions&icon=document-export&size=16',
$exportMenu
)
);
$this->registerAction(
new Action(
'edit', _('Edit'), 'geticon.php?context=actions&icon=document-edit&size=16',
......@@ -1255,18 +1228,6 @@ class management implements FusionDirectoryDialog
}
}
function export (array $action)
{
if (!isset($this->exporters[$action['action']])) {
trigger_error('Unknown exporter ' . $action['action']);
return;
}
$exporter = $this->exporters[$action['action']];
$file = $exporter['class']::export($this->listing);
send_binary_content($file, $exporter['filename'], $exporter['mime']);
}
/* End of action handlers */
/* Methods related to Snapshots */
......
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2025 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* Note : Class used to parse supannRessourceEtatDate in a readable human format.
*/
class SupannEtatDateColumn extends LinkColumn
{
/**
* @param ListingEntry $entry
* @param string $value
* @return string
* Note : Allows to receive an attribute value and return it to readable format.
*/
protected function renderSingleValue (ListingEntry $entry, string $value): string
{
if (!empty($value)) {
$parts = explode(':', $value);
$startDateStr = $parts[2] ?? '';
$endDateStr = $parts[3] ?? '';
$startDate = $this->parseDate($startDateStr);
$endDate = $this->parseDate($endDateStr);
$text = $parts[0] . ' : ' . $this->buildDateText($startDate, $endDate);
return $this->renderLink($entry, $text);
}
return '&nbsp;';
}
/**
* @param string $dateStr
* @return DateTimeImmutable|null
* Note :
*/
private function parseDate (string $dateStr): ?DateTimeImmutable
{
// Veirfy if the date received is of proper stored format.
if (strlen($dateStr) === 8) {
$year = (int)substr($dateStr, 0, 4);
$month = (int)substr($dateStr, 4, 2);
$day = (int)substr($dateStr, 6, 2);
try {
return (new DateTimeImmutable())->setDate($year, $month, $day);
} catch (\Exception $e) {
}
}
return NULL;
}
/**
* @param DateTimeImmutable|null $startDate
* @param DateTimeImmutable|null $endDate
* @return string
* Note : Once date have been formated, we simply add small 'from' and to 'text' string before returning.
*/
private function buildDateText (?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): string
{
if ($startDate !== NULL && $endDate !== NULL) {
return 'From ' . $startDate->format('d/m/Y') . ' to ' . $endDate->format('d/m/Y');
}
if ($startDate !== NULL) {
return 'From ' . $startDate->format('d/m/Y');
}
if ($endDate !== NULL) {
return 'Until ' . $endDate->format('d/m/Y');
}
return 'No start or end dates set';
}
}
\ No newline at end of file
......@@ -123,9 +123,9 @@ abstract class passwordMethod
*
* \param string $dn
*/
function lock_account ($dn = '')
function lock_account ($dn = '', bool $lockEverything = TRUE)
{
return $this->generic_modify_account($dn, 'LOCK');
return $this->generic_modify_account($dn, 'LOCK', $lockEverything);
}
/*!
......@@ -141,7 +141,7 @@ abstract class passwordMethod
* \brief Unlocks an account which was locked by 'lock_account()'.
* For details about the locking mechanism see 'lock_account()'.
*/
private function generic_modify_account ($dn, string $mode)
private function generic_modify_account ($dn, string $mode, bool $lockEverything = TRUE)
{
global $config;
if (!$this->lockable) {
......@@ -163,15 +163,21 @@ abstract class passwordMethod
} elseif ($mode == 'UNLOCK') {
return TRUE;
}
/* Fill modification array */
$modify = [];
foreach ($userObject->by_object as $tab) {
if ($tab instanceof UserTabLockingAction) {
$tab->fillLockingLDAPAttrs($mode, $modify);
// Only trigger if general lock is set
if ($lockEverything) {
foreach ($userObject->by_object as $tab) {
if ($tab instanceof UserTabLockingAction) {
// Execute below function if available in each plugin tab to lock what is required to be locked. (webservice etc).
$tab->fillLockingLDAPAttrs($mode, $modify);
}
}
}
// Call pre hooks
$errors = $userMainTab->callHook('PRE'.$mode, [], $ret);
if (!empty($errors)) {
......
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2003-2010 Cajus Pollmeier
Copyright (C) 2011-2016 FusionDirectory
Copyright (C) 2011-2025 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,45 +21,95 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*!
* \file class_PDF.php
* Source code for class PDF
*/
/*!
* \brief This class contains all the functions to manage pdf
*/
class PDF extends FPDF
class passwordMethodArgon2 extends passwordMethod
{
var $headline = "";
public $hash = 'argon2';
/*!
* \brief passwordMethodArgon2 Constructor
*/
function __construct ()
{
}
/*!
* \brief Set the headline
* \brief Is available
*
* \param string $headline
* \return TRUE if is available, otherwise return false
*/
function setHeadline ($headline)
public function is_available (): bool
{
$this->headline = $headline;
return defined('PASSWORD_ARGON2ID') && function_exists('password_hash') && function_exists('password_verify');
}
/*!
* \brief Set font and cell for the header page
* \brief Generate template hash
*
* \param string $pwd Password
* \param bool $locked Should the password be locked
*
* \return string the password hash
*/
function Header ()
public function generate_hash (string $pwd, bool $locked = FALSE): string
{
$this->SetFont('Helvetica', 'B', 10);
$this->Cell(0, 0, $this->headline, 0, 0, 'L');
$this->Ln(5);
$hash = password_hash($pwd, PASSWORD_ARGON2ID);
return '{ARGON2}'.($locked ? '!' : '').$hash;
}
/*!
* \brief Set position from the bottom and the number of the page
* \brief Check if a password matches a hash
*
* \param string $pwd The password to check
* \param string $hash The hash to check against
*
* \return bool True if the password matches the hash
*/
function Footer ()
function checkPassword ($pwd, $hash): bool
{
$this->SetY(-15);
$this->SetFont('Helvetica', 'I', 8);
$this->Cell(0, 10, _("Page")." ".$this->PageNo().'/{nb}', 0, 0, 'C');
// Remove the {ARGON2} prefix and any lock indicator
$hash = preg_replace('/^\{ARGON2\}!?/', '', $hash);
if (strlen($hash) === 0) {
return FALSE;
}
return password_verify($pwd, $hash);
}
/*!
* \brief Check if the hash needs to be rehashed
*
* \param string $hash The hash to check
*
* \return bool True if the hash needs to be rehashed
*/
public function needsRehash (string $hash): bool
{
// Remove the {ARGON2} prefix and any lock indicator
$hash = preg_replace('/^\{ARGON2\}!?/', '', $hash);
return password_needs_rehash($hash, PASSWORD_ARGON2ID);
}
/*!
* \brief Get the hash name
*/
static function get_hash_name ()
{
return 'argon2';
}
/*!
* \brief Extract a method
*
* \param string $password_hash
*/
static function _extract_method ($password_hash): string
{
if (preg_match('/^\{ARGON2\}/i', $password_hash)) {
return static::get_hash_name();
}
return '';
}
}
?>
\ No newline at end of file
......@@ -91,6 +91,14 @@ class ObjectsAttribute extends GenericDialogAttribute
protected function fillDisplayValue ($i)
{
$value = $this->value[$i];
// Fixing potentially visual for wildcard string
if ($value === '*') {
$this->displays[$i] = 'Any';
$this->types[$i] = FALSE;
return;
}
try {
if ($this->store_attr == 'dn') {
$objects = objects::ls($this->selectManagementParameters[0], $this->selectManagementParameters[2], $value, '', FALSE, 'base');
......@@ -109,8 +117,12 @@ class ObjectsAttribute extends GenericDialogAttribute
protected function fillDisplayValueFrom ($i, $attrs)
{
global $config;
$defaultDn = 'uid=default,ou=nonexistent,' . $config->current['BASE'];
$objectType = NULL; // <-- Add this line
if ($attrs) {
$objectType = NULL;
if (is_array($attrs)) {
foreach ($this->selectManagementParameters[0] as $type) {
try {
......@@ -143,8 +155,16 @@ class ObjectsAttribute extends GenericDialogAttribute
$this->displays[$i] = $this->value[$i];
$this->types[$i] = FALSE;
} else {
$this->displays[$i] = sprintf(_('Non existing dn: %s'), $this->value[$i]);
$this->types[$i] = FALSE;
// Special handling for the default user DN
if ($this->value[$i] === $defaultDn) {
$this->displays[$i] = '<span class="default-user-dn">' . _('Default user placeholder') . '</span>';
$this->types[$i] = FALSE; // Mark type as FALSE for placeholder
} else {
// Handle other non-existing DNs by setting display and type to FALSE
// This prevents errors in later code expecting these keys to be set.
$this->displays[$i] = sprintf(_('[Non-existent DN: %s]'), $this->value[$i]); // Indicate non-existence clearly
$this->types[$i] = FALSE; // Mark type as FALSE
}
}
}
......@@ -181,13 +201,54 @@ class ObjectsAttribute extends GenericDialogAttribute
function setValue ($value)
{
global $config; // Needed for defaultDn comparison
// Reset types and let parent handle initial population and display filling
$this->types = [];
parent::setValue($value);
// Now, filter out entries that are marked as non-existent (type === FALSE)
// unless it's the special default user placeholder.
$defaultDn = 'uid=default,ou=nonexistent,' . $config->current['BASE'];
$filteredValue = [];
$filteredDisplays = [];
$filteredTypes = [];
foreach ($this->value as $key => $dn) {
if (isset($this->types[$key])) {
if ($this->types[$key] !== FALSE) {
// Valid object
$filteredValue[$key] = $this->value[$key];
$filteredDisplays[$key] = $this->displays[$key];
$filteredTypes[$key] = $this->types[$key];
} elseif ($dn === $defaultDn) {
// Special case: default DN, keep even if type is FALSE
$filteredValue[$key] = $this->value[$key];
$filteredDisplays[$key] = $this->displays[$key];
$filteredTypes[$key] = $this->types[$key];
}
}
}
// Replace the internal arrays with the filtered versions
$this->value = $filteredValue;
$this->displays = $filteredDisplays;
$this->types = $filteredTypes;
// Re-index arrays to ensure sequential keys if necessary for rendering or other logic
// Although using keys directly might be fine depending on renderOnlyFormInput logic
$this->value = array_values($this->value);
$this->displays = array_values($this->displays);
$this->types = array_values($this->types);
}
protected function removeValue ($row)
{
// Ensure keys are sequential after removal if using array_values in setValue
parent::removeValue($row);
unset($this->types[$row]);
// Re-index after removal
$this->value = array_values($this->value);
$this->displays = array_values($this->displays);
$this->types = array_values($this->types);
}
}
......@@ -38,6 +38,8 @@ class simplePlugin implements SimpleTab
* associative array that stores attributeLdapName => reference on object
*/
public $attributesAccess = [];
// Thisb bolean allows children class to get readOnly automatically via static state or class-level state.
private static $user_locked = FALSE;
/*!
\brief Mark plugin as account
......@@ -158,6 +160,11 @@ class simplePlugin implements SimpleTab
$this->parent = $parent;
$this->mainTab = $mainTab;
// This class-level state allows children to get readOnly automatically.
if (self::$user_locked) {
$this->read_only = TRUE;
}
try {
$plInfo = pluglist::pluginInfos(get_class($this));
} catch (UnknownClassException $e) {
......@@ -299,6 +306,12 @@ class simplePlugin implements SimpleTab
}
}
public static function setUserLocked (bool $locked): void
{
self::$user_locked = $locked;
}
protected function loadAttributes ()
{
// We load attributes values
......
......@@ -63,7 +63,7 @@ define("FPDF_FONTPATH", "/usr/share/php/fpdf/font/"); /*! Define fpdf font path
/*!
* \brief FusionDirectory Version
*/
define("FD_VERSION", "1.4"); /*! Define FusionDirectory version */
define("FD_VERSION", "1.5"); /*! Define FusionDirectory version */
/*!
* \brief FusionDirectory config object RDN
......