fix: Permissions check should have find invoke chown directly on returned paths#4696
fix: Permissions check should have find invoke chown directly on returned paths#4696neil-lcv-cs wants to merge 1 commit into
find invoke chown directly on returned paths#4696Conversation
|
LGTM.
Any idea, what the purpose of |
Its only usage seems to be here: docker-mailserver/target/scripts/startup/setup-stack.sh Lines 92 to 95 in 005ea8f There was that part |
polarathene
left a comment
There was a problem hiding this comment.
I think there might be some minor concerns to address so this doesn't cause any subtle unexpected breakages (we might be lacking test coverage in some cases?)
| function _chown_var_mail() { | ||
| # if needed, fix permissions for all files and folders 3 levels deep /var/mail | ||
| log 'trace' 'Fixing /var/mail permissions' | ||
| find /var/mail -maxdepth 3 \( \! -user "${DMS_VMAIL_UID}" -o \! -group "${DMS_VMAIL_GID}" \) -exec chown "${DMS_VMAIL_UID}:${DMS_VMAIL_GID}" {} + |
There was a problem hiding this comment.
While I understand why you'd like to drop the chown -R to only run chown, the -maxdepth 3 will prevent recursively applying chown when necessary.
chown -R 5000:5000 /var/mail was introduced into the source since the first pushed commit IIRC. There was no related context for that intention provided at the time unfortunately.
That was later changed to the conditional check with -maxdepth 3 because of the overhead of chown -R on larger /var/mail contents with each container start.
I'm not concerned about container setup time where a user deploys DMS with /var/mail contents that they've migrated Dovecot mail storage from another source than DMS, or even from a DMS backup where the user copied the contents but didn't preserve ownership.
We do copy over some user config however like this:
docker-mailserver/target/scripts/helpers/accounts.sh
Lines 64 to 70 in e532b37
There is no ownership correction applied, that appears to be deferred to this utility command. In your case where you add a user account, that mkdir alone would be triggering the condition at runtime to cause the chown -R over all of /var/mail.
Likewise we probably don't want to drop the -maxdepth 3 limit, that is an adequate check AFAIK and covers the expectations for DMS at least (/var/mail/<domain-part>/<local-part>/*). No need to iterate over all files/folders beyond that AFAIK.
Some configurations may deviate from that convention (LDAP), but I don't recall anyone having reported performance concerns that has done such.
- AFAIK, an existing domain-part (1st depth level) won't be affected, while new accounts will add their own
local-partpath (2nd depth level) and I guess anything in that respective folder (third depth level) which would be redundant forchown -R(but as you're using{} +, provided all related paths are bundled it probably makes no difference and the child content would be coalesced with the parent folder path?). - Any content changes that add new files like the sieve scripts, when all other content has correct ownership however may fail to get detected by
find. Originally we didn't have ahome/subdirectory in the users mailbox directory, so that should probably get addressed separately in it's own related script logic.
There is also a bug with the current find -> chown affecting /var/mail/* content that breaks Postfix from delivering internal mail for system users at /var/mail/<user> via it's local delivery agent (as opposed to virtual which routes to Dovecot to handle), where ownership is expected to match the UID/GID of the user as per their /etc/passwd entry, otherwise Postfix fails to deliver new mail to that user file in /var/mail/ after ownership is modified.
Technically this shouldn't be a concern for DMS users, especially if they've got /etc/aliases setup correctly via our POSTMASTER_ADDRESS ENV + postfix-aliases.cf, DMS could improve on that concern though 😓
It is however a known issue for users preferring LDAP, with a workaround to not have per-user ownership (by configuring Dovecot to use static vmail UID/GID like the default file account provisioner does)
There was a problem hiding this comment.
This should be valid?:
| find /var/mail -maxdepth 3 \( \! -user "${DMS_VMAIL_UID}" -o \! -group "${DMS_VMAIL_GID}" \) -exec chown "${DMS_VMAIL_UID}:${DMS_VMAIL_GID}" {} + | |
| find /var/mail -maxdepth 3 \( \! -user "${DMS_VMAIL_UID}" -o \! -group "${DMS_VMAIL_GID}" \) -exec chown -R "${DMS_VMAIL_UID}:${DMS_VMAIL_GID}" {} + |
Otherwise we need to be aware of more scenarios where the lack of -R flag for chown can go awry.
| # Legacy workaround handled here, only seems necessary for _create_accounts: | ||
| # - `helpers/accounts.sh` logic creates folders/files with wrong ownership. | ||
| _chown_var_mail_if_necessary | ||
| _chown_var_mail |
There was a problem hiding this comment.
If we are certain that this is only needed for helpers/accounts.sh, we can probably fix ownership in that script itself?
Past involvement from me also suggests it could be valid solution:
- [BUG] Restarting the container changes the owner of folders in /var/mail to 5000 #2238 (comment) (suggests to provide a convenience via
setup.shif users need to manually invoke this only upon startup, they could likewise useuser-patches.shfor this now) - [TODO]: Migrate away from legacy
dockeruser + group #3557 (comment) (detailed history on the functionality for reference) - [TODO]: Migrate away from legacy
dockeruser + group #3557 (comment)- A user mentions that
find -maxdepth 3results in 30k paths but that is actually due to LDAP use with shorter mail-storage paths. - Avoiding the 30k overhead would be preferable but after adjusting the storage path to have another folder level to align with
find -maxdepth 3they reported no overhead concerns (container startup, LDAP users aren't affected by the helper at runtime).
- A user mentions that
- Don't change owners in /var/mail recursively #2256 (comment) (various test failures will be raised to catch issues from dropping this helper call, pretty much all due to a Dovecot vmail (
dockeruser/group) ownership mismatch as mailbox dirs would berootIIRC)
There was a problem hiding this comment.
If interested in pursuing this, I think we can remove the _chown_var_mail line here in favour of adding to this helpers/accounts.sh logic:
docker-mailserver/target/scripts/helpers/accounts.sh
Lines 64 to 69 in e532b37
+ local MAILBOX_HOME="/var/mail/${DOMAIN}/${USER}/home"
- mkdir -p "/var/mail/${DOMAIN}/${USER}/home"
+ mkdir -p "${MAILBOX_HOME}"
+ chown "${DMS_VMAIL_UID}:${DMS_VMAIL_GID}" "${MAILBOX_HOME}"
- # copy user provided sieve file, if present
+ # Copy user provided `.sieve` file:
if [[ -e "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" ]]; then
- cp "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" "/var/mail/${DOMAIN}/${USER}/home/.dovecot.sieve"
+ cp "/tmp/docker-mailserver/${LOGIN}.dovecot.sieve" "${MAILBOX_HOME}/.dovecot.sieve"
+ chown "${DMS_VMAIL_UID}:${DMS_VMAIL_GID}" "${MAILBOX_HOME}/.dovecot.sieve"
fiThat way we skip the find operation, I'm just not sure if we should do that for DMS v16 given we might be overlooking something and not have adequate test coverage for it 😓 Probably better for now to just make the change the PR presently proposes.
Yeah, it was expected that if the I assume that's a non-issue now with the conditional dropped and just executing via |
find results during permission checkfind invoke chown directly on returned paths
Description
As stated in #4112, this avoids running chown on a huge number of files and folders by directly using it on the results of the
findcommand.I renamed the function to omit the
_if_necessaryparts as it is not possible anymore to check when find triggers a chown or not. I am not sure if it would be useful to know this information anyway.Note: The function does not return 1 in case of error anymore. I guess we should reimplement that before merging.
Type of change
Checklist
docs/)CHANGELOG.md