univ-of-utah-marriott-library-apple/privacy_services_manager

Users Application Support directory gets set with root permissions.

dhoer opened this issue · 32 comments

dhoer commented

When provisioning Mac OS X 10.10 for the first time with privacy_services_manager, the Application Support directory gets set with root permissions. This happens only if a user hasn't logged in. If the user logged in before calling privacy_services_manager, then it preserves the directory and it's permissions.

Here are the Application Support permissions without privacy_services_manager called:

drwxr-xr-x  11 vagrant  staff   374 Sep 27 15:16 Application Support

Here are the contents of Application Support directory without privacy services manager called:

drwxr-xr-x  11 vagrant  staff  374 Sep 27 15:16 .
drwxr-xr-x@ 23 vagrant  staff  782 Sep 27 15:13 ..
drwx------  11 vagrant  staff  374 Sep 27 15:13 AddressBook
drwxr-xr-x   5 vagrant  staff  170 Sep 27 15:13 CallHistoryDB
drwxr-xr-x   2 vagrant  staff   68 Sep 27 15:13 CallHistoryTransactions
drwxr-xr-x   2 vagrant  staff   68 Sep 27 15:13 CloudDocs
drwx------   2 vagrant  staff   68 Sep 27 15:13 CrashReporter
drwxr-xr-x   3 vagrant  staff  102 Sep 27 15:13 Dock
drwx------   3 vagrant  staff  102 Sep 27 15:13 com.apple.TCC
drwxr-xr-x   4 vagrant  staff  136 Sep 27 15:16 com.apple.spotlight
-rw-r--r--   1 vagrant  staff  420 Sep 27 15:16 com.apple.spotlight.Shortcuts

Here are the Application Support permissions with privacy_services_manager called:

drwx------   3 root     staff   102 Sep 27 15:35 Application Support

Here are the contents of Application Support directory with privacy services manager called.

drwxr-xr-x   3 root     staff  102 Sep 27 15:35 .
drwxr-xr-x@ 27 vagrant  staff  918 Sep 27 15:37 ..
drwx------   3 root     staff  102 Sep 27 15:35 com.apple.TCC
dhoer commented

Here are the privacy_services_manager commands being executed:

- execute sudo /usr/local/bin/privacy_services_manager.py --user vagrant --admin add accessibility /System/Library/CoreServices/RemoteManagement/ARDAgent.app
- execute sudo /usr/local/bin/privacy_services_manager.py --user vagrant --admin add accessibility /usr/libexec/sshd-keygen-wrapper

Hello Dennis:

Sorry about the issue, we will troubleshoot and fix it and let you know status.

On Sep 27, 2015, at 4:50 PM, Dennis Hoer <notifications@github.commailto:notifications@github.com> wrote:

Here are the privacy_services_manager commands being executed:

  • execute sudo /usr/local/bin/privacy_services_manager.py --user vagrant --admin add accessibility /System/Library/CoreServices/RemoteManagement/ARDAgent.app
  • execute sudo /usr/local/bin/privacy_services_manager.py --user vagrant --admin add accessibility /usr/libexec/sshd-keygen-wrapper


Reply to this email directly or view it on GitHubhttps://github.com//issues/37#issuecomment-143599726.

Thanks:

Richard Glaser
University of Utah, Marriott Library ITS
richard.glaser@utah.edumailto:richard.glaser@utah.edu

Hi again, @dhoer!

I think I need a little more information to try to duplicate this issue.

  1. Which Application Support directory are you looking at? (/Users/vagrant/Library/Application Support or /Library/Application Support?)
  2. Is vagrant the only non-root user on this machine?
dhoer commented

/Users/vagrant/Library/Application Support

What I think is going on is the application support directory and tcc database are not there so it creates the directory and database as root instead of vagrant user.

How do you suggest the tool gets the user to assign the proper permissions if the items don't exist?

Thanks,

Richard Glaser
University of Utah
Student Computing Labs

On Sep 29, 2015, at 12:22 PM, Dennis Hoer <notifications@github.commailto:notifications@github.com> wrote:

/Users/vagrant/Library/Application Support

What I think is going on is the application support directory and tcc database are not there so it creates the directory and database as root instead of vagrant user.


Reply to this email directly or view it on GitHubhttps://github.com//issues/37#issuecomment-144145372.

dhoer commented

The --user vagrant flag that was passed in.

I think you're right that it's being created as root when it doesn't exist.

The weird thing is that it shouldn't be created. accessibility is managed system-wide at all times, meaning the actual TCC database being modified is at /System/Library/Application Support instead of the user-specific TCC database.

There must be something in the code that blindly checks whether a user passed in via --user has a database, and if not it creates it, even if that database isn't going to be used. I didn't intend for that to happen (at least, I don't think I did... it's been a little while, haha).

I'll check into the creation process and get back to you with what I find.

dhoer commented

Thanks

I'm still working on this. I wasn't able to get to it as much as I would have liked yesterday.

Your proposed solution is the same thing I came up with after looking through the available options, so I think that's the way I'm going to take this. I'll update this issue when I've made more progress.

@dhoer would you download this file and check if it works? It's a new .dmg file with a version that I think fixes this issue.

dhoer commented

@pdarragh That would be hard for me to do since it builds the url in the cookbook: https://github.com/dhoer/chef-privacy_services_manager/blob/master/recipes/default.rb#L5-L6

Sorry, forgot this would auto-close when I merged branches.

Please let me know how the update goes. I changed how administrative override works, but it shouldn't break anything with your current cookbooks. I do recommend changing --admin to --no-check-bin for better readability and future-proofing, though, but the --admin flag will continue to work interchangeable for the foreseeable future.

dhoer commented

That didn't fix the issue. The users Application Support directory is still root. This causes Firefox startup to fail because profile cannot be loaded.

Also, if the --no-check-bin flag is set, does that mean the management tools dependency is no longer needed?

dhoer commented

One more thing, the group is admin instead of staff.

I'm not seeing the same thing in my environment.

I'm creating a brand-new user, who has never logged in (the username is tester). If I do ls /Users/tester/Library/Application\ Support/ I get:

$ ls -Flah /Users/tester/Library/Application\ Support/
total 0
drwx------   2 tester  staff    68B Oct  7 09:37 ./
drwx------  26 tester  staff   884B Oct  7 09:37 ../

I then ran Privacy Services Manager:

$ sudo privacy_services_manager.py --user tester --no-check-bin add accessibility  /usr/libexec/sshd-keygen-wrapper 
WARNING: Administrative override enabled. Be careful!
INFO: ################################################################################
Privacy Services Manager, version 1.7.0

    service:  accessibility
    action:   add
    app(s):   ['/usr/libexec/sshd-keygen-wrapper']
    user:     tester
    template: False
    language: N/A

INFO: Set to modify local permissions for user 'tester' at '/Users/tester/Library/Application Support/com.apple.TCC/TCC.db'.
INFO: Set to modify global permissions for all users at '/Library/Application Support/com.apple.TCC/TCC.db'.
INFO: TCC.db file was expected at '/Users/tester/Library/Application Support/com.apple.TCC/TCC.db' but was not found. Creating new TCC.db file...
INFO: TCC.db file created successfully.
INFO: Inserting '/usr/libexec/sshd-keygen-wrapper' in service 'accessibility'...
INFO: Inserted successfully.
INFO: Successfully completed.

After running this, when I check the contents of tester's Application Support directory:

$ ls -Flah /Users/tester/Library/Application\ Support/
total 0
drwx------   3 tester  staff   102B Oct  7 09:37 ./
drwx------  26 tester  staff   884B Oct  7 09:37 ../
drwx------   3 tester  staff   102B Oct  7 09:37 com.apple.TCC/

and:

$ ls -Flah /Users/tester/Library/Application\ Support/com.apple.TCC/
total 72
drwx------  3 tester  staff   102B Oct  7 09:37 ./
drwx------  3 tester  staff   102B Oct  7 09:37 ../
-rw-r--r--  1 tester  staff    36K Oct  7 09:37 TCC.db

So in my vanilla setup, everything seems to work as expected. The username is set correctly on both com.apple.TCC and TCC.db, and the group is set to the user's primary group ID (which you can check with id <username>, e.g.:

$ id tester
uid=502(tester) gid=20(staff) groups=<...>

I'm not really sure what's going on here, but my guess is that it's something specific in your environment. I'm happy to try to help you troubleshoot it further, because I want for this to be working correctly for you, but I don't know how to duplicate your issue in my environment. Any ideas?

dhoer commented

When I run it, it creates the following directory/file permissions:

drwx------   3 root     staff   102 Oct  6 23:16 Application Support
drwx------   3 vagrant  admin  102 Oct  6 23:16 com.apple.TCC
-rw-r--r--   1 vagrant  admin  36864 Oct  6 23:16 TCC.db

I'm not sure why there is a difference.

To run the cookbook by itself you will need VMWare Fusion, Vagrant, and ChefDK. Which is a little much to run the test case. But if you are up for it then once these are installed, then do the following:

git clone git@github.com:dhoer/chef-privacy_services_manager.git
cd chef-privacy_services_manager
git checkout create_tcc_issue
chef exec bundle exec 
chef exec kitchen test

Kitchen test will create the mac and will run privacy_services_manager. If it provisioned successfully, then it will run serverspec tests to verify the directory user permissions.

dhoer commented

From re-reading your comment. It looks like Application Support directory is already there. That does not seem to be the case with for me, so the py script must be creating it for me.

dhoer commented

I used Tim Sutton's packer template to create the mac image:
https://github.com/timsutton/osx-vm-templates

dhoer commented

I forgot you would need Hashicorp VMware Fusion provider plugin which costs money in order to run kitchen test. Can you try deleting Application Support directory before running psm and see if that duplicates the issue?

@dhoer I will try this when I'm back tomorrow morning, or earlier if I'm able to get to it. Sorry for the trouble! That's odd you don't have an Application Support directory, though... in vanilla OS X it's a default directory for a user to have.

I will probably have to implement a more involved fix where PSM manually generates each missing directory and keeps track of them to fix permissions later... If only os.makedirs took in a uid value to set the permissions as it goes!

...huh.

I assumed the Application Support directory to exist, because it's part of OS X's system specifications that it should exist for any user account at any time. It's considered a "key directory", as per this document, and is created by the system by default when a new user is created.

I'll rewrite that portion of the script to handle such cases more gracefully, but I think maybe @timsutton should also look into ensuring the directory exists appropriately in his VM templates. I'd advise you to maybe open a ticket on his project for it so he can keep track of the request? (I've @mentioned him here so he can see where you're coming from.)


As for the issue with the group ID, there's not terribly much I can do about that. To see the group ID I'm getting, open up a python instance and do the following:

>>> from pwd import getpwnam
>>> getpwnam('username').pw_gid

This gets the same information as the following system call:

$ id username -g

So the issue is that your vagrant user is registered to the admin group before anything else; it's that user's primary group identification. Here is a StackExchange post about adjusting a user's primary GID, but that can only be used after the user account is created. The better way to handle this would be to properly set the user's desired primary group during account creation.

It's curious to me that your user's own directory belongs to a group other than their primary. This may be another issue with the VM templates, or else possibly an error in your configuration of those templates (hard for me to say without being a user of those templates myself).

dhoer commented

@pdarragh @timsutton I took a look at this last night and Application Support directory does exist and with the correct user and group before calling psm.

drwxr-xr-x 9 vagrant staff 306 Oct 7 19:55 Application Support

So I'm not sure why it is getting overwritten by psm with root user and admin group when it preexisted.

dhoer commented

I think you need to cd to path /Library/Application Support for root or /Users/{}/Library/Application Support for user e.g. os.chdir(path) before line:
https://github.com/univ-of-utah-marriott-library-apple/privacy_services_manager/blob/master/privacy_services_management/tcc_services.py#L358

Let me just be sure we're on the same page with all the info:

  1. user vagrant is created but hasn't signed in
    1. ~vagrant/Library/Application Support/ directory exists with proper 755 vagrant:staff permissions
    2. ~vagrant/Library/Application Support/com.apple.TCC/ directory does not exist
  2. PSM is run with --user vagrant
    1. PSM creates ~vagrant/Library/Application Support/com.apple.TCC/TCC.db, owned by vagrant:admin where you were expecting vagrant:staff
    2. The permissions of ~vagrant/Library/Application Support/ directory change to 700 and owned by root:admin

Is this all correct?

It doesn't make any sense that you're seeing all of these permissions changes from PSM. com.apple.TCC is changed and TCC.db is changed. These are the only two items being modified with a call to os.chown. I'm totally at a loss for how you're getting these errors.


I think you need to cd to path /Library/Application Support for root or /Users/{}/Application Support for user

Changing directory within the Python instance will not change how the directories are created, if that's what you're suggesting. The issue is that the Python process is owned by root (because it has to be run with administrative permissions for modifying another user's database).

I would also recommend moving this chunk of code under this if statement

The username/groupid have to be taken outside of that if statement because they're used again after the TCC.db file is created to change its permissions, and it's bad form to get that kind of info twice (since it could hypothetically change between invocations, and I don't want a mismatch).

dhoer commented

One and two are both correct. I don't understand python syntax that well, but it seems that before the call to from pwd import getpwnam, there needs to be a chdir to users directory to get the proper permissions. Looking at the code, I don't understand what the present working directory (pwd) would be at the time of the from pwd call.

Ohh, gotcha. I wish the issue were so simple.

from pwd import getpwnam tells Python to open the pwd module and get the method named getpwnam. This module has access to the system's passwords database (like /etc/passwd in Linux, but I think dscl handles it in OS X). Where you are when you invoke this call will not affect the result of the calls; the information it gets is static across the system at any given point.

Open a terminal and do id USERNAME (substituting vagrant or whatever user you're interested in for USERNAME) to see some of the info. This information is what the pwd module is accessing. It gets out the user's uid and gid and uses those values to set the permissions on the TCC.db file and its parent directory (no other directories). Here is some information about users and groups, and here's the excerpt on primary groups:

Each user has a designated primary (or default) group and can also be a member of additional groups called secondary groups. When users create files or launch programs, those files and programs are associated with a primary or secondary group. A user who is a part of the group can access these file and programs if necessary permissions are available.

According to the information you've given, your vagrant user's primary group is admin, not staff. This is an issue with your configuration somewhere. A user's home directory should have group ownership of the primary group that the user belongs to. So really, the rest of your vagrant user's home directory should have vagrant:admin permissions. I can't tell you why that isn't the case.

I'm also totally at a loss for how your Application Support directory is being re-owned to root. If the directory already exists at the time that PSM is being invoked, then PSM doesn't touch it. If the directory doesn't exist, it gets created by the os.makedirs call. This call is equivalent to calling mkdir -p in the shell, which means every intermediate directory that is created will be owned by the user running the shell (root in this case). But this shouldn't be an issue, since the Application Support directory already exists.

My plan is to write a version of os.makedirs that'll progressively create each directory and set its permissions properly. Maybe that'll mitigate your issue.

dhoer commented

Ahh. Thanks for the explanation. Horrible naming of that module. I will have to verify that the primary group of vagrant user is admin.

@dhoer,

I rewrote the path-creation algorithm with 1.7.2. Give it a try when you've got a chance and let's see if it handles anything better. Fingers crossed.

dhoer commented

Thanks, I will try it out this weekend.

dhoer commented

@pdarragh Looks good, thanks for taking the time to get this fixed.

Woohoo! Glad to hear that it's finally resolved. Thanks for being patient with me while I got it worked out, and just let me know if you find anything else that needs to be changed!