How can I lock files with specific passwords on mac, ideally through terminal?

Solution 1:

The /etc/hosts needs to be readable by other program in order to fulfill its purpose. If you encrypt the file in any way, those other programs will not be able to read the file - and it will stop working.

So in short, you cannot do this (i.e. encryption) in a meaningful manner.

However what you can do is ensure that others do not have passwords for administrative accounts on your Mac. If they do need more privileges for something, make it so that you assign access to that specific resource (for example via a sudo access limited to a specific program) - and ensure that you do not give out full administrative access.

An example of using sudo for giving access to edit a file is to use the "sudoedit" option in sudo. This allows you to give another person access to edit a file without letting their editor run as the privileged user (which is bound to let them "escape" and allow them to other things as the privileged user). It is achieved by copying the privileged file into a separate location, letting the user run their usual editor under their own user id to edit that file, and then copying its contents over the privileged file afterwards.

In sudoers you would specificy something like:

username  sudoedit /etc/hosts

By default this will allow "username" to edit that file, and requires him to enter his own login password before doing so.

If you want to the user to input a different password, that is not his login password, you have basically two ways of going about it.

One way is not to use "sudoedit": Instead create a custom program (can be a shell script) that simply inputs a string and checks that it matches the password you want, and then just mimics what sudoedit does. It can also be quite simple and just a "cp" command to copy over a specific path from the user's own home folder to /etc/hosts.

The alternative is to modify which passwords sudo will accept as valid. This is done by editing /etc/pam.d/sudo and uncommenting the standard lines beginning with "auth". Instead provide the authentication module and options you want to approve.

If you want to do something completely custom, you can compile your own PAM module that simply asks for a password and checks that it is a specific string. You can start with the source code for the default pam_opendirectory PAM module and simply rip out the OpenDirectory parts and replace it with a simple strcmp(). The source code for such a custom module is very few lines of code.

You can find the pam_opendirectory PAM module source code here:

https://opensource.apple.com/source/pam_modules/pam_modules-76/pam_opendirectory/pam_opendirectory.c.auto.html

Solution 2:

Ok, so here's a completely fresh answer that's not a "half-solution".

Whether this is what you actually are looking for, you can tell me.
But to reinforce the answers above:

  1. Change your default account to a non-administrator account.
  2. Create a new administrator account, with a unique password; this account will only every be used to edit /etc/hosts.
  3. Write a wrapper script/shell function to wrap/supersede sudo, also checking the arguments in $@ here to ensure /etc/hosts is the file in question.
  4. read the password for the unique admin user into a shell variable.
  5. Use the rest of the script to su to the admin user using that password, then then again to /usr/bin/sudo vi /etc/hosts.

You will then have a solution where when you "run sudo vim /etc/hosts, [you] must type a customized/specific password to write to the file."