LDAP-Monitor 2.0.0__tar.gz → 2.0.1__tar.gz

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.
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: LDAP-Monitor
3
- Version: 2.0.0
3
+ Version: 2.0.1
4
4
  Summary: Monitor LDAP directory changes in real-time
5
5
  Home-page: https://github.com/MegaManSec/LDAP-Monitoring-Watchdog
6
6
  Author: Joshua Rogers
7
7
  Author-email: ldap-watchdog@joshua.hu
8
- License: GPL-3.0
8
+ License-Expression: GPL-3.0-or-later
9
9
  Project-URL: Blog Post, https://joshua.hu/ldap-watchdog-openldap-python-monitoring-tool-realtime-directory-slack-notifications
10
10
  Project-URL: Author, https://joshua.hu/
11
11
  Classifier: Programming Language :: Python :: 3
@@ -13,7 +13,6 @@ Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
16
  Classifier: Operating System :: OS Independent
18
17
  Classifier: Topic :: System :: Monitoring
19
18
  Classifier: Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP
@@ -30,8 +29,8 @@ Dynamic: classifier
30
29
  Dynamic: description
31
30
  Dynamic: description-content-type
32
31
  Dynamic: home-page
33
- Dynamic: license
34
32
  Dynamic: license-file
33
+ Dynamic: license-expression
35
34
  Dynamic: project-url
36
35
  Dynamic: provides-extra
37
36
  Dynamic: requires-dist
@@ -43,12 +42,12 @@ Dynamic: summary
43
42
  ## Overview
44
43
  LDAP Watchdog is a tool designed to monitor record changes in an LDAP directory in real-time.
45
44
  It provides a mechanism to track and visualize modifications, additions, and removals to user and group entries, allowing users to correlate expected changes with actual changes and identify potential security incidents.
46
- It was created with OpenLDAP and Linux in mind, however it may work in other implementations of LDAP.
47
- It is written in Python and only requires the ldap3 library.
45
+ It was created with OpenLDAP and Linux in mind, and needs a server that gives every entry an `entryUUID` (RFC 4530), so Active Directory, which uses `objectGUID` instead, is not supported.
46
+ It is written in Python and requires the ldap3 library, plus requests for Slack notifications.
48
47
 
49
48
  This software was written by [Joshua Rogers](https://joshua.hu/).
50
49
 
51
- If you're interesting in any of the following, then LDAP Watchdog is for you:
50
+ If you're interested in any of the following, then LDAP Watchdog is for you:
52
51
  - Know what's going on in your LDAP directory on-demand with Slack webhook integration.
53
52
  - See new hires, leavers, and promotions as they appear in LDAP.
54
53
  - Monitor _when_ and what HR is doing.
@@ -58,7 +57,7 @@ If you're interesting in any of the following, then LDAP Watchdog is for you:
58
57
 
59
58
  In addition to monitoring for modifications, additions, and removals in an LDAP directory, it can be configured to ignore specific attributes, or even fine-tuned to ignore fine-grained attributes depending on their old/new values.
60
59
 
61
- The changes that are monitored can either be forwarded to a slack webhook or output to the terminal (or both). Optional colored output is also supported.
60
+ Changes are always printed to the terminal, and are also forwarded to a Slack webhook if one is configured. Colored output can be turned off.
62
61
 
63
62
  Previously named LDAP-Stalker (because monitoring changes of an LDAP directory is an excellent way to stalk changes in a company: learn about promotions before they're announced, new hires, leavers, etc.), a blog post about the details and history of this project [can be found here](https://joshua.hu/ldap-watchdog-openldap-python-monitoring-tool-realtime-directory-slack-notifications).
64
63
 
@@ -90,7 +89,7 @@ Note: in the below examples, changes to entryCSN and modifyTimestamp on existing
90
89
 
91
90
  7. **Ignored Entries and Attributes:** Users can specify UUIDs and attributes to ignore when comparing changes to existing entries.
92
91
 
93
- 8. **Conditional Ignored Attributes:** Conditional filtering allows users to ignore specific attributes based on change type (additions, modifications, deletions).
92
+ 8. **Conditional Ignored Attributes:** Users can ignore changes to an attribute only when they involve specific values, such as one group in `memberOf`.
94
93
 
95
94
 
96
95
  ## Requirements
@@ -108,7 +107,7 @@ pip install LDAP-Monitor
108
107
  To include Slack webhook support:
109
108
 
110
109
  ```bash
111
- pip install LDAP-Monitor[slack]
110
+ pip install "LDAP-Monitor[slack]"
112
111
  ```
113
112
 
114
113
  ### Docker
@@ -131,6 +130,12 @@ cd LDAP-Monitoring-Watchdog
131
130
  pip install ".[slack]"
132
131
  ```
133
132
 
133
+ ### Upgrading
134
+
135
+ **From 1.x:** Since 2.0.0, LDAPS connections verify the server certificate and that it matches the host name or IP address in `LDAP_WATCHDOG_SERVER`; 1.0.0 checked neither. Before upgrading, set `LDAP_WATCHDOG_CA_CERTS_FILE` if the certificate is self-signed or from a private CA, and if it does not match that name, use a matching certificate or set `LDAP_WATCHDOG_TLS_VERIFY=false` (see the TLS notes under [Configuration](#configuration)). The [release notes](https://github.com/MegaManSec/LDAP-Monitoring-Watchdog/releases/tag/v2.0.0) list the other changes.
136
+
137
+ **From 1.x or 2.0.0:** Since 2.0.1, boolean settings only accept the values listed under [Configuration](#configuration). Earlier versions read anything other than `true`, `1` or `yes` as false. Now an unrecognized value stops the process at startup, an empty value means the default, and `on` or a quoted `"true"` means true. For example, an empty `LDAP_WATCHDOG_USE_SSL` with a bare host name now connects with LDAPS on port 636 instead of plain LDAP on port 389.
138
+
134
139
  ## Usage
135
140
 
136
141
  ### Running with pip install
@@ -138,7 +143,7 @@ pip install ".[slack]"
138
143
  ```bash
139
144
  export LDAP_WATCHDOG_SERVER='ldaps://ldaps.intra.lan'
140
145
  export LDAP_WATCHDOG_BASE_DN='dc=mouse,dc=com'
141
- export LDAP_WATCHDOG_USERNAME='Emily'
146
+ export LDAP_WATCHDOG_USERNAME='cn=Emily,ou=People,dc=mouse,dc=com'
142
147
  export LDAP_WATCHDOG_PASSWORD='qwerty123'
143
148
  ldap-watchdog
144
149
  ```
@@ -152,34 +157,37 @@ python -m ldap_watchdog
152
157
  ### Running with Docker
153
158
 
154
159
  ```bash
155
- docker run -d \
160
+ docker run -d --restart unless-stopped \
156
161
  -e LDAP_WATCHDOG_SERVER='ldaps://ldaps.intra.lan' \
157
162
  -e LDAP_WATCHDOG_BASE_DN='dc=mouse,dc=com' \
158
- -e LDAP_WATCHDOG_USERNAME='Emily' \
163
+ -e LDAP_WATCHDOG_USERNAME='cn=Emily,ou=People,dc=mouse,dc=com' \
159
164
  -e LDAP_WATCHDOG_PASSWORD='qwerty123' \
160
165
  -e SLACK_WEBHOOK_URL='https://hooks.slack.com/services/[...]' \
161
- -e LDAP_WATCHDOG_IGNORED_ATTRIBUTES='modifyTimestamp,phoneNumber,officeLocation,gecos' \
166
+ -e LDAP_WATCHDOG_IGNORED_ATTRIBUTES='entryCSN,modifyTimestamp,telephoneNumber,roomNumber,gecos' \
167
+ -e LDAP_WATCHDOG_DISABLE_COLOR_OUTPUT='true' \
162
168
  megamansec/ldap-monitor
163
169
  ```
164
170
 
165
171
  ### Systemd Installation (Debian-based)
166
172
 
167
- A Debian-based installation script, [install.sh](https://github.com/MegaManSec/LDAP-Monitoring-Watchdog/blob/main/install.sh), is provided. When run as root from a clone of this repository, this script:
173
+ A Debian-based installation script, [install.sh](https://github.com/MegaManSec/LDAP-Monitoring-Watchdog/blob/main/install.sh), is provided. It needs Python 3.10 or later and the `python3-venv` package. When run as root from a clone of this repository, this script:
168
174
 
169
175
  1. Creates (if necessary) a Python virtual environment in `/opt/ldap-watchdog`.
170
176
  2. Installs LDAP Watchdog from the clone into that virtual environment, with the dependency versions pinned in `requirements.txt`.
171
- 3. Creates an environment file at `/etc/ldap-watchdog.env` for configuration.
172
- 4. Installs and enables a systemd service (`/etc/systemd/system/ldap-watchdog.service`) that runs **ldap-watchdog** in the background.
177
+ 3. Creates an environment file at `/etc/ldap-watchdog.env` for configuration, unless one already exists.
178
+ 4. Installs, enables and starts a systemd service (`/etc/systemd/system/ldap-watchdog.service`) that runs **ldap-watchdog** in the background as an unprivileged dynamic user, so a CA bundle must be world-readable.
173
179
  5. Configures logging to `/var/log/ldap-watchdog.log` and `/var/log/ldap-watchdog-error.log`.
174
180
  6. Sets up log rotation in `/etc/logrotate.d/ldap-watchdog`.
175
181
 
176
- You may optionally pass a single argument to `install.sh` to set the `SLACK_WEBHOOK_URL`:
182
+ Rerunning the script from an updated clone upgrades the installation.
183
+
184
+ You may optionally pass a single argument to `install.sh` to set the `SLACK_WEBHOOK_URL` when the environment file is first created:
177
185
 
178
186
  ```bash
179
187
  sudo ./install.sh "https://hooks.slack.com/services/[...]"
180
188
  ```
181
189
 
182
- After installation, edit `/etc/ldap-watchdog.env` to configure the LDAP connection settings, then restart the service:
190
+ After installation, edit `/etc/ldap-watchdog.env` to configure the LDAP connection settings (the service fails until then), then restart the service:
183
191
 
184
192
  ```bash
185
193
  sudo systemctl restart ldap-watchdog
@@ -187,24 +195,26 @@ sudo systemctl restart ldap-watchdog
187
195
 
188
196
  ## Configuration
189
197
 
190
- All configuration is done via environment variables. The following variables are supported:
198
+ All configuration is done via environment variables; an empty value is the same as an unset one, except for `LDAP_WATCHDOG_SLACK_BULLETPOINT`. The following variables are supported:
191
199
 
192
200
  ### General Settings
193
201
 
194
202
  | Environment Variable | Description | Default |
195
203
  |---|---|---|
196
- | `LDAP_WATCHDOG_SERVER` | LDAP server URL (e.g. `ldaps://ldaps.intra.lan`) | `""` |
204
+ | `LDAP_WATCHDOG_SERVER` | LDAP server URL or host name (e.g. `ldaps://ldaps.intra.lan`). Required. | `""` |
197
205
  | `LDAP_WATCHDOG_BASE_DN` | Base Distinguished Name for LDAP searches | `""` |
198
- | `LDAP_WATCHDOG_USERNAME` | LDAP username for authentication. Leave empty for anonymous bind. | `""` |
199
- | `LDAP_WATCHDOG_PASSWORD` | LDAP password for authentication. Leave empty for anonymous bind. | `""` |
200
- | `LDAP_WATCHDOG_USE_SSL` | Set to `true` to use SSL, `false` otherwise | `true` |
206
+ | `LDAP_WATCHDOG_USERNAME` | Bind DN for authentication (e.g. `cn=Emily,ou=People,dc=mouse,dc=com`). If this or the password is empty, the bind is anonymous. | `""` |
207
+ | `LDAP_WATCHDOG_PASSWORD` | Password for `LDAP_WATCHDOG_USERNAME` | `""` |
208
+ | `LDAP_WATCHDOG_USE_SSL` | Set to `true` to use SSL (LDAPS, default port 636 instead of 389), `false` otherwise. An `ldaps://` or `ldap://` scheme in `LDAP_WATCHDOG_SERVER` overrides this. | `true` |
201
209
  | `LDAP_WATCHDOG_CA_CERTS_FILE` | Optional PEM CA bundle for verifying the LDAP server certificate. If unset, system trust roots are used. | Unset |
202
210
  | `LDAP_WATCHDOG_TLS_VERIFY` | Set to `false` to skip verifying the LDAP server certificate and host name. The connection is still encrypted but not authenticated. | `true` |
203
- | `LDAP_WATCHDOG_SEARCH_FILTER` | LDAP filter for user and group entries | `(&(|(objectClass=inetOrgPerson)(objectClass=groupOfNames)))` |
211
+ | `LDAP_WATCHDOG_SEARCH_FILTER` | LDAP filter for user and group entries | `(&(\|(objectClass=inetOrgPerson)(objectClass=groupOfNames)))` |
204
212
  | `LDAP_WATCHDOG_SEARCH_ATTRIBUTE` | Comma-separated list of attributes to retrieve. [`*,+`](https://joshua.hu/tracking-secret-ldap-login-times-with-modifytimestamp-heuristics) is used by default to include operational attributes. `entryUUID` is always requested and must be readable for every entry. | `*,+` |
205
- | `LDAP_WATCHDOG_REFRESH_RATE` | Time interval in seconds between consecutive LDAP searches | `60` |
213
+ | `LDAP_WATCHDOG_REFRESH_RATE` | Whole number of seconds to wait after each LDAP search before the next one | `60` |
206
214
  | `LDAP_WATCHDOG_NETWORK_TIMEOUT` | Positive integer timeout in seconds for LDAP and Slack connection/read operations. This limits individual waits, not the total duration of a poll. | `30` |
207
- | `LDAP_WATCHDOG_DISABLE_COLOR_OUTPUT` | Set to `true` to disable colored terminal output | `false` |
215
+ | `LDAP_WATCHDOG_DISABLE_COLOR_OUTPUT` | Set to `true` to disable colored output, which is used even when output goes to a file or `docker logs` | `false` |
216
+
217
+ Boolean settings accept `true`, `yes`, `on` or `1` and `false`, `no`, `off` or `0`, in any case and optionally quoted; any other value stops the process at startup.
208
218
 
209
219
  LDAPS connections verify the server certificate and check that it is valid for the host name or IP address in `LDAP_WATCHDOG_SERVER`. For a private CA, set `LDAP_WATCHDOG_CA_CERTS_FILE` to a readable PEM CA bundle; in Docker, mount the bundle into the container and use its container path. A self-signed server certificate can be used as the bundle itself. If the certificate can't be provided or doesn't match the server's name, `LDAP_WATCHDOG_TLS_VERIFY=false` turns verification off; anyone on the network path can then impersonate the server and capture the bind password. For a server without TLS, use an `ldap://` URL or set `LDAP_WATCHDOG_USE_SSL=false`.
210
220
 
@@ -212,7 +222,7 @@ LDAPS connections verify the server certificate and check that it is valid for t
212
222
 
213
223
  | Environment Variable | Description | Default |
214
224
  |---|---|---|
215
- | `LDAP_WATCHDOG_CONTROL_UUID` | UUID of a control user whose changes trigger an error if not found. If set, this user should always have some type of change when the LDAP directory is retrieved. | `""` |
225
+ | `LDAP_WATCHDOG_CONTROL_UUID` | `entryUUID` of a control user that is changed (e.g. by a cron job) before every poll. Unless one of its attributes present in both snapshots has a new value, the comparison is rejected with an error. The user must match the base DN and search filter, and its changes are announced unless the ignore filters hide them, e.g. by listing it in `LDAP_WATCHDOG_IGNORED_UUIDS`. | `""` |
216
226
  | `LDAP_WATCHDOG_CONTROL_USER_ATTRIBUTE` | Specific attribute to check in the control user. If set, it must exist in both snapshots and its value must differ. | `""` |
217
227
 
218
228
  A failed control check logs an error and skips that comparison. The next poll compares against the most recent successfully retrieved snapshot; changes from a rejected comparison are not replayed. A failed LDAP retrieval instead preserves the previous snapshot and is retried on the next poll. Failure to retrieve the initial snapshot stops the process.
@@ -221,14 +231,14 @@ A failed control check logs an error and skips that comparison. The next poll co
221
231
 
222
232
  | Environment Variable | Description | Default |
223
233
  |---|---|---|
224
- | `SLACK_WEBHOOK_URL` | Slack Webhook URL for notifications. Requires the `slack` extra (`pip install LDAP-Monitor[slack]`). | `None` |
225
- | `LDAP_WATCHDOG_SLACK_BULLETPOINT` | Bullet point character used in Slack and console output | ` \u2022 ` |
234
+ | `SLACK_WEBHOOK_URL` | Slack Webhook URL for notifications. Requires the `slack` extra (`pip install "LDAP-Monitor[slack]"`). | Unset |
235
+ | `LDAP_WATCHDOG_SLACK_BULLETPOINT` | Text that starts each line of changes in Slack and console output | • with one space before and three after |
226
236
 
227
- Slack delivery is best effort: HTTP and network failures are logged to stderr, and monitoring and console output continue. Failed notifications are not queued or retried.
237
+ Slack delivery is best effort: HTTP and network failures are logged to stderr, and monitoring and console output continue. Failed notifications are not queued or retried. Messages longer than 4,000 characters are shortened by replacing their longest words with `[...truncated...]`; if that is not enough, they are cut at 4,000 characters, dropping their last lines (additions are listed first, then removals, then modifications). Console output is never shortened.
228
238
 
229
239
  ### Ignored Entries and Attributes
230
240
 
231
- These filters apply to attribute changes on entries present in both snapshots. Entry additions and deletions are always announced with all retrieved attributes, including for ignored UUIDs.
241
+ These filters apply to attribute changes on entries present in both snapshots. Entry additions and deletions are always announced with all retrieved attributes, including for ignored UUIDs. UUIDs are `entryUUID` values, shown in parentheses after the DN in each message, and names and values must match exactly, including case (`modifyTimestamp`, not `modifytimestamp`). Changes hidden by `LDAP_WATCHDOG_IGNORED_ATTRIBUTES` or `LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES` are still written to stderr with their values; those of ignored UUIDs are skipped silently.
232
242
 
233
243
  | Environment Variable | Description | Default |
234
244
  |---|---|---|
@@ -238,7 +248,7 @@ These filters apply to attribute changes on entries present in both snapshots. E
238
248
 
239
249
  ### Conditional Ignored Attributes
240
250
 
241
- The `LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES` variable accepts a JSON string where keys are attribute names and values are lists of values to ignore:
251
+ The `LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES` variable accepts a JSON object where keys are attribute names and values are arrays of values to ignore (an array even for one value):
242
252
 
243
253
  ```bash
244
254
  export LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES='{
@@ -248,21 +258,23 @@ export LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES='{
248
258
  }'
249
259
  ```
250
260
 
261
+ If an attribute has exactly one value before and after, the whole change is hidden when either value is listed (see Limitations). Otherwise only the listed values are dropped from the added or removed values. Invalid JSON stops the process at startup.
262
+
251
263
  ## Example Configuration
252
264
 
253
265
  ```bash
254
266
  export LDAP_WATCHDOG_CONTROL_UUID='a71c6e4c-8881-4a03-95bf-4fc25d5e6359'
255
267
  export LDAP_WATCHDOG_SERVER='ldaps://ldaps.intra.lan'
256
268
  export LDAP_WATCHDOG_BASE_DN='dc=mouse,dc=com'
257
- export LDAP_WATCHDOG_USERNAME='Emily'
269
+ export LDAP_WATCHDOG_USERNAME='cn=Emily,ou=People,dc=mouse,dc=com'
258
270
  export LDAP_WATCHDOG_PASSWORD='qwerty123'
259
271
  export LDAP_WATCHDOG_USE_SSL='true'
260
272
  export LDAP_WATCHDOG_TLS_VERIFY='true'
261
273
  export LDAP_WATCHDOG_REFRESH_RATE='60'
262
274
  export LDAP_WATCHDOG_NETWORK_TIMEOUT='30'
263
275
  export LDAP_WATCHDOG_DISABLE_COLOR_OUTPUT='false'
264
- export LDAP_WATCHDOG_IGNORED_UUIDS='e191c564-6e6d-42c1-ae51-bda0509fe846,8655e0d9-ecdc-46ce-ba42-1fa3dfbf5faa'
265
- export LDAP_WATCHDOG_IGNORED_ATTRIBUTES='modifyTimestamp,phoneNumber,officeLocation,gecos'
276
+ export LDAP_WATCHDOG_IGNORED_UUIDS='a71c6e4c-8881-4a03-95bf-4fc25d5e6359,e191c564-6e6d-42c1-ae51-bda0509fe846,8655e0d9-ecdc-46ce-ba42-1fa3dfbf5faa'
277
+ export LDAP_WATCHDOG_IGNORED_ATTRIBUTES='entryCSN,modifyTimestamp,telephoneNumber,roomNumber,gecos'
266
278
  export LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES='{"objectClass":["posixAccount"],"memberOf":["cn=mailing-list-user,ou=Accessgroups,dc=mouse,dc=com","cn=interns,ou=Accessgroups,dc=mouse,dc=com"],"organizationalStatus":["researcher"]}'
267
279
  export SLACK_WEBHOOK_URL='https://hooks.slack.com/services/[...]'
268
280
 
@@ -270,8 +282,9 @@ ldap-watchdog
270
282
  ```
271
283
 
272
284
  ## Limitations
273
- 1. The _LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES_ configuration may unfortunately hide important changes that are not intended to be hidden. This may happen if an attribute has a single value which is changed. This is because conditional ignored attributes will hide changes to the attribute both when the value is changed __to__ _as well as_ __from__ the ignored value; for example, if a user is a memberOf _cn=mailing-list-user,ou=Accessgroups,dc=mouse,dc=com_ which gets __changed__ to _cn=super-administrator,ou=Accessgroups,dc=mouse,dc=com_, it will be missed.
274
- 2. Similar to #1, there is no real way to determine whether a change is really a change in some cases, or a removal and then addition in the same time. In theory, it doesn't really matter, however it's important to note.
285
+ 1. The `LDAP_WATCHDOG_CONDITIONAL_IGNORED_ATTRIBUTES` configuration may unfortunately hide important changes that are not intended to be hidden. This may happen if an attribute has a single value which is changed. This is because conditional ignored attributes will hide changes to the attribute both when the value is changed __to__ _as well as_ __from__ the ignored value; for example, if a user is a memberOf _cn=mailing-list-user,ou=Accessgroups,dc=mouse,dc=com_ which gets __changed__ to _cn=super-administrator,ou=Accessgroups,dc=mouse,dc=com_, it will be missed.
286
+ 2. Similar to #1, there is no real way to determine whether a change is really a change in some cases, or a removal and then addition at the same time. In theory, it doesn't really matter, however it's important to note.
287
+ 3. LDAP Watchdog polls rather than receiving changes as they happen: after each search it waits `LDAP_WATCHDOG_REFRESH_RATE` seconds, then retrieves all matching entries again and compares them with the previous snapshot. A change made and undone between two polls is never reported, and the timestamp on each message is when the change was detected, not when it was made (which `modifyTimestamp` records).
275
288
 
276
289
 
277
290
  ## Development
@@ -286,4 +299,4 @@ python -m unittest discover -s tests
286
299
  `requirements.txt` pins every dependency for the Docker image and `install.sh`. After changing the dependencies in `setup.py`, regenerate it with `pip-compile --extra=slack --output-file=requirements.txt setup.py`.
287
300
 
288
301
  ## License
289
- This project is licensed under [GPL3.0](https://github.com/MegaManSec/LDAP-Monitoring-Watchdog/blob/main/LICENSE).
302
+ This project is licensed under [GPL-3.0-or-later](https://github.com/MegaManSec/LDAP-Monitoring-Watchdog/blob/main/LICENSE).
@@ -1,6 +1,7 @@
1
1
  LICENSE
2
2
  MANIFEST.in
3
3
  README.md
4
+ pyproject.toml
4
5
  setup.py
5
6
  LDAP_Monitor.egg-info/PKG-INFO
6
7
  LDAP_Monitor.egg-info/SOURCES.txt
@@ -12,4 +13,6 @@ ldap_watchdog/__init__.py
12
13
  ldap_watchdog/__main__.py
13
14
  ldap_watchdog/config.py
14
15
  ldap_watchdog/watchdog.py
15
- tests/test_watchdog.py
16
+ tests/test_watchdog.py
17
+ tests/certs/ldap.example.com.pem
18
+ tests/certs/localhost.pem
@@ -1,5 +1,5 @@
1
- GNU AFFERO GENERAL PUBLIC LICENSE
2
- Version 3, 19 November 2007
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
3
 
4
4
  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5
5
  Everyone is permitted to copy and distribute verbatim copies
@@ -7,15 +7,17 @@
7
7
 
8
8
  Preamble
9
9
 
10
- The GNU Affero General Public License is a free, copyleft license for
11
- software and other kinds of works, specifically designed to ensure
12
- cooperation with the community in the case of network server software.
10
+ The GNU General Public License is a free, copyleft license for
11
+ software and other kinds of works.
13
12
 
14
13
  The licenses for most software and other practical works are designed
15
14
  to take away your freedom to share and change the works. By contrast,
16
- our General Public Licenses are intended to guarantee your freedom to
15
+ the GNU General Public License is intended to guarantee your freedom to
17
16
  share and change all versions of a program--to make sure it remains free
18
- software for all its users.
17
+ software for all its users. We, the Free Software Foundation, use the
18
+ GNU General Public License for most of our software; it applies also to
19
+ any other work released this way by its authors. You can apply it to
20
+ your programs, too.
19
21
 
20
22
  When we speak of free software, we are referring to freedom, not
21
23
  price. Our General Public Licenses are designed to make sure that you
@@ -24,34 +26,44 @@ them if you wish), that you receive source code or can get it if you
24
26
  want it, that you can change the software or use pieces of it in new
25
27
  free programs, and that you know you can do these things.
26
28
 
27
- Developers that use our General Public Licenses protect your rights
28
- with two steps: (1) assert copyright on the software, and (2) offer
29
- you this License which gives you legal permission to copy, distribute
30
- and/or modify the software.
31
-
32
- A secondary benefit of defending all users' freedom is that
33
- improvements made in alternate versions of the program, if they
34
- receive widespread use, become available for other developers to
35
- incorporate. Many developers of free software are heartened and
36
- encouraged by the resulting cooperation. However, in the case of
37
- software used on network servers, this result may fail to come about.
38
- The GNU General Public License permits making a modified version and
39
- letting the public access it on a server without ever releasing its
40
- source code to the public.
41
-
42
- The GNU Affero General Public License is designed specifically to
43
- ensure that, in such cases, the modified source code becomes available
44
- to the community. It requires the operator of a network server to
45
- provide the source code of the modified version running there to the
46
- users of that server. Therefore, public use of a modified version, on
47
- a publicly accessible server, gives the public access to the source
48
- code of the modified version.
49
-
50
- An older license, called the Affero General Public License and
51
- published by Affero, was designed to accomplish similar goals. This is
52
- a different license, not a version of the Affero GPL, but Affero has
53
- released a new version of the Affero GPL which permits relicensing under
54
- this license.
29
+ To protect your rights, we need to prevent others from denying you
30
+ these rights or asking you to surrender the rights. Therefore, you have
31
+ certain responsibilities if you distribute copies of the software, or if
32
+ you modify it: responsibilities to respect the freedom of others.
33
+
34
+ For example, if you distribute copies of such a program, whether
35
+ gratis or for a fee, you must pass on to the recipients the same
36
+ freedoms that you received. You must make sure that they, too, receive
37
+ or can get the source code. And you must show them these terms so they
38
+ know their rights.
39
+
40
+ Developers that use the GNU GPL protect your rights with two steps:
41
+ (1) assert copyright on the software, and (2) offer you this License
42
+ giving you legal permission to copy, distribute and/or modify it.
43
+
44
+ For the developers' and authors' protection, the GPL clearly explains
45
+ that there is no warranty for this free software. For both users' and
46
+ authors' sake, the GPL requires that modified versions be marked as
47
+ changed, so that their problems will not be attributed erroneously to
48
+ authors of previous versions.
49
+
50
+ Some devices are designed to deny users access to install or run
51
+ modified versions of the software inside them, although the manufacturer
52
+ can do so. This is fundamentally incompatible with the aim of
53
+ protecting users' freedom to change the software. The systematic
54
+ pattern of such abuse occurs in the area of products for individuals to
55
+ use, which is precisely where it is most unacceptable. Therefore, we
56
+ have designed this version of the GPL to prohibit the practice for those
57
+ products. If such problems arise substantially in other domains, we
58
+ stand ready to extend this provision to those domains in future versions
59
+ of the GPL, as needed to protect the freedom of users.
60
+
61
+ Finally, every program is threatened constantly by software patents.
62
+ States should not allow patents to restrict development and use of
63
+ software on general-purpose computers, but in those that do, we wish to
64
+ avoid the special danger that patents applied to a free program could
65
+ make it effectively proprietary. To prevent this, the GPL assures that
66
+ patents cannot be used to render the program non-free.
55
67
 
56
68
  The precise terms and conditions for copying, distribution and
57
69
  modification follow.
@@ -60,7 +72,7 @@ modification follow.
60
72
 
61
73
  0. Definitions.
62
74
 
63
- "This License" refers to version 3 of the GNU Affero General Public License.
75
+ "This License" refers to version 3 of the GNU General Public License.
64
76
 
65
77
  "Copyright" also means copyright-like laws that apply to other kinds of
66
78
  works, such as semiconductor masks.
@@ -537,45 +549,35 @@ to collect a royalty for further conveying from those to whom you convey
537
549
  the Program, the only way you could satisfy both those terms and this
538
550
  License would be to refrain entirely from conveying the Program.
539
551
 
540
- 13. Remote Network Interaction; Use with the GNU General Public License.
541
-
542
- Notwithstanding any other provision of this License, if you modify the
543
- Program, your modified version must prominently offer all users
544
- interacting with it remotely through a computer network (if your version
545
- supports such interaction) an opportunity to receive the Corresponding
546
- Source of your version by providing access to the Corresponding Source
547
- from a network server at no charge, through some standard or customary
548
- means of facilitating copying of software. This Corresponding Source
549
- shall include the Corresponding Source for any work covered by version 3
550
- of the GNU General Public License that is incorporated pursuant to the
551
- following paragraph.
552
+ 13. Use with the GNU Affero General Public License.
552
553
 
553
554
  Notwithstanding any other provision of this License, you have
554
555
  permission to link or combine any covered work with a work licensed
555
- under version 3 of the GNU General Public License into a single
556
+ under version 3 of the GNU Affero General Public License into a single
556
557
  combined work, and to convey the resulting work. The terms of this
557
558
  License will continue to apply to the part which is the covered work,
558
- but the work with which it is combined will remain governed by version
559
- 3 of the GNU General Public License.
559
+ but the special requirements of the GNU Affero General Public License,
560
+ section 13, concerning interaction through a network will apply to the
561
+ combination as such.
560
562
 
561
563
  14. Revised Versions of this License.
562
564
 
563
565
  The Free Software Foundation may publish revised and/or new versions of
564
- the GNU Affero General Public License from time to time. Such new versions
565
- will be similar in spirit to the present version, but may differ in detail to
566
+ the GNU General Public License from time to time. Such new versions will
567
+ be similar in spirit to the present version, but may differ in detail to
566
568
  address new problems or concerns.
567
569
 
568
570
  Each version is given a distinguishing version number. If the
569
- Program specifies that a certain numbered version of the GNU Affero General
571
+ Program specifies that a certain numbered version of the GNU General
570
572
  Public License "or any later version" applies to it, you have the
571
573
  option of following the terms and conditions either of that numbered
572
574
  version or of any later version published by the Free Software
573
575
  Foundation. If the Program does not specify a version number of the
574
- GNU Affero General Public License, you may choose any version ever published
576
+ GNU General Public License, you may choose any version ever published
575
577
  by the Free Software Foundation.
576
578
 
577
579
  If the Program specifies that a proxy can decide which future
578
- versions of the GNU Affero General Public License can be used, that proxy's
580
+ versions of the GNU General Public License can be used, that proxy's
579
581
  public statement of acceptance of a version permanently authorizes you
580
582
  to choose that version for the Program.
581
583
 
@@ -633,29 +635,40 @@ the "copyright" line and a pointer to where the full notice is found.
633
635
  Copyright (C) <year> <name of author>
634
636
 
635
637
  This program is free software: you can redistribute it and/or modify
636
- it under the terms of the GNU Affero General Public License as published
637
- by the Free Software Foundation, either version 3 of the License, or
638
+ it under the terms of the GNU General Public License as published by
639
+ the Free Software Foundation, either version 3 of the License, or
638
640
  (at your option) any later version.
639
641
 
640
642
  This program is distributed in the hope that it will be useful,
641
643
  but WITHOUT ANY WARRANTY; without even the implied warranty of
642
644
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643
- GNU Affero General Public License for more details.
645
+ GNU General Public License for more details.
644
646
 
645
- You should have received a copy of the GNU Affero General Public License
647
+ You should have received a copy of the GNU General Public License
646
648
  along with this program. If not, see <https://www.gnu.org/licenses/>.
647
649
 
648
650
  Also add information on how to contact you by electronic and paper mail.
649
651
 
650
- If your software can interact with users remotely through a computer
651
- network, you should also make sure that it provides a way for users to
652
- get its source. For example, if your program is a web application, its
653
- interface could display a "Source" link that leads users to an archive
654
- of the code. There are many ways you could offer source, and different
655
- solutions will be better for different programs; see section 13 for the
656
- specific requirements.
652
+ If the program does terminal interaction, make it output a short
653
+ notice like this when it starts in an interactive mode:
654
+
655
+ <program> Copyright (C) <year> <name of author>
656
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
+ This is free software, and you are welcome to redistribute it
658
+ under certain conditions; type `show c' for details.
659
+
660
+ The hypothetical commands `show w' and `show c' should show the appropriate
661
+ parts of the General Public License. Of course, your program's commands
662
+ might be different; for a GUI interface, you would use an "about box".
657
663
 
658
664
  You should also get your employer (if you work as a programmer) or school,
659
665
  if any, to sign a "copyright disclaimer" for the program, if necessary.
660
- For more information on this, and how to apply and follow the GNU AGPL, see
666
+ For more information on this, and how to apply and follow the GNU GPL, see
661
667
  <https://www.gnu.org/licenses/>.
668
+
669
+ The GNU General Public License does not permit incorporating your program
670
+ into proprietary programs. If your program is a subroutine library, you
671
+ may consider it more useful to permit linking proprietary applications with
672
+ the library. If this is what you want to do, use the GNU Lesser General
673
+ Public License instead of this License. But first, please read
674
+ <https://www.gnu.org/licenses/why-not-lgpl.html>.
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include README.md
3
+ recursive-include tests/certs *.pem