ldap-rest 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/bin/index.js +1 -1
  2. package/dist/config/args.js +1 -1
  3. package/dist/lib/authz/base.js +1 -1
  4. package/dist/lib/errors.js +1 -1
  5. package/dist/lib/expressFormatedResponses.js +1 -1
  6. package/dist/lib/utils.js +1 -1
  7. package/dist/plugins/auth/authzScope.js +1 -1
  8. package/dist/plugins/ldap/bulkImport.js +1 -1
  9. package/dist/plugins/ldap/enterpriseRules.js +1 -1
  10. package/dist/plugins/ldap/groups.js +1 -1
  11. package/dist/plugins/ldap/passwordPolicy.js +1 -1
  12. package/dist/src/config/args.d.ts +6 -0
  13. package/dist/src/config/schema.d.ts +5 -3
  14. package/dist/src/lib/authz/base.d.ts +39 -0
  15. package/dist/src/lib/errors.d.ts +35 -2
  16. package/dist/src/lib/utils.d.ts +12 -0
  17. package/dist/src/plugins/auth/authzScope.d.ts +19 -0
  18. package/dist/src/plugins/ldap/bulkImport.d.ts +10 -0
  19. package/dist/src/plugins/ldap/enterpriseRules.d.ts +25 -7
  20. package/dist/src/plugins/ldap/groups.d.ts +29 -5
  21. package/dist/src/plugins/ldap/passwordPolicy.d.ts +13 -1
  22. package/docs/client-development/api/rest-api.md +52 -0
  23. package/docs/usage/configuration.md +7 -6
  24. package/docs/usage/plugins/auth/authz-linid1.md +36 -1
  25. package/docs/usage/plugins/ldap/bulk-import.md +15 -0
  26. package/docs/usage/plugins/ldap/enterprise-rules.md +41 -11
  27. package/docs/usage/plugins/ldap/password-policy.md +13 -1
  28. package/docs/usage/plugins/ldap/trash.md +9 -0
  29. package/docs/usage/upgrading.md +37 -0
  30. package/package.json +1 -1
  31. package/static/schemas/example/groups.json +2 -1
  32. package/static/schemas/example/organizations.json +2 -0
  33. package/static/schemas/standard/devices.json +4 -2
  34. package/static/schemas/twake/groups.json +2 -1
  35. package/static/schemas/twake/organizations.json +2 -0
  36. package/static/schemas/twake/teamMailboxes.json +2 -1
  37. package/static/schemas/twake/users.json +1 -0
@@ -3,7 +3,7 @@
3
3
  The business rules an enterprise directory needs on top of per-attribute
4
4
  validation: uniqueness across a shared namespace, mail addresses confined to
5
5
  the domains an organization owns, computed organization paths, normalised
6
- quotas, and referential-integrity guards on deletion.
6
+ quotas, and referential integrity on deletion.
7
7
 
8
8
  Every rule is driven by the loaded entity schemas. The plugin contains no
9
9
  attribute name, no domain and no nomenclature value, so the same code serves a
@@ -134,24 +134,47 @@ An `accountExpiry` attribute must not carry a date already past. The comparison
134
134
  is against the start of the current day, so scheduling something for today is
135
135
  allowed.
136
136
 
137
- ### Deletion guards
137
+ ### Deletion and references
138
138
 
139
139
  ```json
140
140
  {
141
141
  "title": { "type": "pointer", "referentialIntegrity": "restrict" },
142
+ "twakeLocalAdminLink": {
143
+ "type": "array",
144
+ "items": { "type": "pointer", "branch": ["ou=users,dc=example,dc=com"] },
145
+ "referentialIntegrity": "remove"
146
+ },
142
147
  "member": { "type": "array", "role": "members", "deleteGuard": "nonEmpty" }
143
148
  }
144
149
  ```
145
150
 
146
- - `referentialIntegrity: "restrict"` refuses to delete an entry while another
147
- entry still points at it — a position somebody still holds, a nomenclature
148
- value still in use. Declared on the **referencing** attribute, and the
149
- pointer's `branch` tells the plugin which deletions to check.
150
- - `deleteGuard: "nonEmpty"` refuses to delete a group that still has members.
151
- The placeholder member some directories keep to satisfy `groupOfNames`
152
- (`--group-dummy-user`) does not count.
153
-
154
- Both default to off: a deployment turns them on where it wants them.
151
+ `referentialIntegrity` is declared on the **referencing** attribute, and the
152
+ pointer's `branch` tells the plugin which deletions concern it:
153
+
154
+ - `restrict` refuses to delete an entry while another entry still points at
155
+ it — a position somebody still holds, a nomenclature value still in use.
156
+ - `remove` takes the deleted entry's DN out of the attribute once the
157
+ deletion has landed: an account leaves the organizations it administered,
158
+ the mailboxes delegated to it, the groups it owned. It also applies to an
159
+ attribute carrying the `owners` role, which is not a pointer. A move into
160
+ the trash (`--trash-base`, see [trash](trash.md)) counts as a deletion,
161
+ [what a restore brings back](trash.md#limitations).
162
+ This runs with the server's rights, whoever deleted the entry, since a
163
+ link left behind would hand its rights to the next entry created with the
164
+ same DN; the writes are attributed to the deletion's author. Use it on
165
+ optional attributes only. Each deletion searches every attribute marked
166
+ `remove`: give them an equality index.
167
+ - `ignore`, the default, leaves the reference dangling.
168
+
169
+ `deleteGuard: "nonEmpty"` refuses to delete a group that still has members.
170
+ The placeholder member some directories keep to satisfy `groupOfNames`
171
+ (`--group-dummy-user`) does not count.
172
+
173
+ Both default to off: a deployment turns them on where it wants them. The
174
+ shipped Twake schemas mark `remove` on the links to accounts: the managers
175
+ and local administrators of an organization, the delegates of a mailbox,
176
+ the owners of a group or a shared mailbox, the owner and manager of a
177
+ device. Members leave their groups through the groups plugin.
155
178
 
156
179
  ## Errors
157
180
 
@@ -160,6 +183,13 @@ Both default to off: a deployment turns them on where it wants them.
160
183
  | `400` | A size that is not a size, a date already past |
161
184
  | `409` | A duplicate value, a mail domain outside the authorised set, a guarded delete |
162
185
 
186
+ A duplicate value answers `code: "unique"` with the `attribute` and the
187
+ `value` refused, and a mail domain outside the authorised set answers
188
+ `code: "mailDomain"` with them and the authorised `domains`, each listed once:
189
+ a client explains them in its own words, under the field at fault. The
190
+ holder of a duplicate value is never named.
191
+ See [the error format](../../../client-development/api/rest-api.md#error-response-format).
192
+
163
193
  ## See also
164
194
 
165
195
  - [flat-generic](flat-generic.md) — the schema format these markers extend
@@ -342,7 +342,12 @@ curl -X PATCH "http://localhost:8081/api/v1/password-policies/default" \
342
342
  `pwdUseCheckModule`, gives the entry the `pwdPolicyChecker` class. Both
343
343
  need OpenLDAP 2.6; an older directory refuses them with a `400`.
344
344
  - An attribute the directory's schema does not know is refused with a `400`
345
- naming it.
345
+ naming it. The list answers, next to `policies`, the `attributes` a policy
346
+ can be given: those of the above that the directory's schema defines.
347
+ OpenLDAP 2.4 lacks `pwdMaxLength`, `pwdMaxIdle`, `pwdMinDelay` and
348
+ `pwdMaxDelay`. The schema is read once per `--ldap-raw-schema-cache-ttl`:
349
+ after an upgrade of the directory, the list follows within that delay, or
350
+ at the next restart.
346
351
 
347
352
  **Creating a policy:** `POST` takes `cn` and the attributes to set. The entry
348
353
  is created under `--ppolicy-base` as a `person` holding `pwdPolicy`, as in
@@ -357,6 +362,13 @@ every administrator reads there: name `--ppolicy-base` in
357
362
  directory read and change the policies
358
363
  ([global branches](../auth/authz-linid1.md#global-branches)).
359
364
 
365
+ `GET /authz/scope` answers `passwordPolicies: true` to a caller who may list
366
+ the policies, and `false` to the others, so that a client offers them
367
+ without asking for them and being refused. It is the judgement the
368
+ authorization plugin describing the scope makes of a search of
369
+ `--ppolicy-base`, which is the search the listing makes; the field is
370
+ absent when this plugin is not loaded.
371
+
360
372
  **Deleting a policy** is refused (`409`) while it is the default one or an
361
373
  entry's `pwdPolicySubentry` names it. The default one is only known through
362
374
  `--ppolicy-default-dn` when there are several: without it, nothing stops
@@ -200,6 +200,15 @@ This plugin uses the `ldapdeleterequest` hook to intercept delete operations bef
200
200
  - Entries with the same RDN will overwrite previous trash entries
201
201
  - Tree structures (entries with children) must be deleted leaf-first
202
202
  - Does not track history (only keeps the latest deleted version)
203
+ - An entry moved to the trash leaves the links declared
204
+ `referentialIntegrity: "remove"`
205
+ ([details](enterprise-rules.md#deletion-and-references)) and, with
206
+ `core/ldap/groups`, its groups. A restore does not bring those links back:
207
+ a restored account has to be made a manager, an administrator or a
208
+ delegate again. Attributes the directory's `refint` overlay follows
209
+ (`member`, `owner`, `manager` in its stock configuration) are the
210
+ exception: `refint` may move the value to the trashed DN before it is
211
+ removed, and a restore then brings it back.
203
212
 
204
213
  ## Troubleshooting
205
214
 
@@ -4,6 +4,43 @@ What to check before deploying, newest first. Only releases that need a
4
4
  decision or a configuration change appear here; see the
5
5
  [CHANGELOG](../../CHANGELOG.md) for everything else.
6
6
 
7
+ ## To 0.24.0
8
+
9
+ ### Links to deleted accounts
10
+
11
+ **Who is affected:** a deployment using the Twake schemas, or any schema
12
+ whose links to accounts now carry `referentialIntegrity: "remove"`
13
+ ([details](plugins/ldap/enterprise-rules.md#deletion-and-references)).
14
+
15
+ Accounts deleted from now on leave the links naming them. Those deleted
16
+ before still appear as managers, local administrators, delegates or owners,
17
+ and an account created again at the same address gets their rights. List
18
+ the dangling ones and remove them:
19
+
20
+ ```sh
21
+ # Connection to the directory, as for any ldapsearch
22
+ OPTS="-H ldap://localhost -D cn=admin,dc=example,dc=com -w secret"
23
+ BASE="dc=example,dc=com"
24
+ for attr in twakeLocalAdminLink twakeManagerLink twakeDelegatedUsers \
25
+ owner manager; do
26
+ ldapsearch $OPTS -LLL -o ldif-wrap=no -b "$BASE" "($attr=*)" "$attr" |
27
+ sed -n -e 's/^dn: //p' -e "s/^$attr: />/p" |
28
+ while IFS= read -r line; do
29
+ case "$line" in
30
+ ">"*) target="${line#>}"
31
+ ldapsearch $OPTS -LLL -s base -b "$target" dn >/dev/null 2>&1 ||
32
+ echo "$dn: $attr $target" ;;
33
+ *) dn="$line" ;;
34
+ esac
35
+ done
36
+ done
37
+ ```
38
+
39
+ Then, for each line, delete that value
40
+ (`ldapmodify`, `delete: <attribute>` with the DN shown). `owner` and
41
+ `manager` may also be listed for entries no schema marks `remove`, an
42
+ account's `manager` say: check before deleting those.
43
+
7
44
  ## To 0.22.0
8
45
 
9
46
  ### James follows the mail domains
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ldap-rest",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "Light directory manager",
5
5
  "keywords": [
6
6
  "Identity-Manager"
@@ -74,7 +74,8 @@
74
74
  "hint": "Expected the DN of an entry of this directory"
75
75
  },
76
76
  "required": false,
77
- "role": "owners"
77
+ "role": "owners",
78
+ "referentialIntegrity": "remove"
78
79
  },
79
80
  "twakeDepartmentLink": {
80
81
  "type": "pointer",
@@ -79,6 +79,7 @@
79
79
  "branch": ["ou=users,__LDAP_BASE__"]
80
80
  },
81
81
  "required": false,
82
+ "referentialIntegrity": "remove",
82
83
  "role": "managers",
83
84
  "label": "Managers"
84
85
  },
@@ -99,6 +100,7 @@
99
100
  "branch": ["ou=users,__LDAP_BASE__"]
100
101
  },
101
102
  "required": false,
103
+ "referentialIntegrity": "remove",
102
104
  "role": "localAdmins",
103
105
  "label": "Local administrators"
104
106
  }
@@ -57,7 +57,8 @@
57
57
  "owner": {
58
58
  "type": "pointer",
59
59
  "branch": ["ou=users,__LDAP_BASE__"],
60
- "required": false
60
+ "required": false,
61
+ "referentialIntegrity": "remove"
61
62
  },
62
63
  "ou": {
63
64
  "type": "string",
@@ -66,7 +67,8 @@
66
67
  "manager": {
67
68
  "type": "pointer",
68
69
  "branch": ["ou=users,__LDAP_BASE__"],
69
- "required": false
70
+ "required": false,
71
+ "referentialIntegrity": "remove"
70
72
  }
71
73
  }
72
74
  }
@@ -147,7 +147,8 @@
147
147
  "en": "Owners",
148
148
  "fr": "Propriétaires",
149
149
  "mn": "Эзэмшигчид"
150
- }
150
+ },
151
+ "referentialIntegrity": "remove"
151
152
  },
152
153
  "twakeDepartmentLink": {
153
154
  "type": "pointer",
@@ -109,6 +109,7 @@
109
109
  "branch": ["ou=users,__LDAP_BASE__"]
110
110
  },
111
111
  "required": false,
112
+ "referentialIntegrity": "remove",
112
113
  "role": "managers",
113
114
  "label": {
114
115
  "en": "Managers",
@@ -137,6 +138,7 @@
137
138
  "branch": ["ou=users,__LDAP_BASE__"]
138
139
  },
139
140
  "required": false,
141
+ "referentialIntegrity": "remove",
140
142
  "role": "localAdmins",
141
143
  "label": {
142
144
  "en": "Local administrators",
@@ -127,7 +127,8 @@
127
127
  "en": "Owners",
128
128
  "fr": "Propriétaires",
129
129
  "mn": "Эзэмшигчид"
130
- }
130
+ },
131
+ "referentialIntegrity": "remove"
131
132
  },
132
133
  "twakeDepartmentLink": {
133
134
  "type": "pointer",
@@ -384,6 +384,7 @@
384
384
  "branch": ["ou=users,__LDAP_BASE__"]
385
385
  },
386
386
  "required": false,
387
+ "referentialIntegrity": "remove",
387
388
  "group": {
388
389
  "en": "Mailbox Settings",
389
390
  "fr": "Paramètres de messagerie",