diff --git a/checkin_notes b/checkin_notes index 1d03cc9f41..ebddf66cc2 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6465,3 +6465,53 @@ Charlie 1 Dec 2009 mac_installer/ License.rtf + +Charlie 5 Dec 2009 + - Mac installer: fix a bug where installer would not start Maanger + because getlogin() is not reliable under OS 10.6 when running + with authentication; use getenv("USER") instead. + + mac_installer/ + PostInstall.cpp + +Charlie 16 Dec 2009 + - Mac Uninstaller: Properly change screensaver settings under OS 10.6. + + mac_installer/ + uninstall.cpp + +Charlie 18 Dec 2009 + - MGR: fix another bug due to changes for Snow Leopard compatibility: + on OS 10.4.11 (Tiger) and perhaps others, when Automatic Login is + set, getlogin() returns "root" for a time after the system is first + booted, causing the Manager to think the user is not a member of + group boinc_master. So check "USER" environment variable instead. + + client/ + check_security.cpp + +Charlie 7 Jan 2010 + - Mac: Fix bug in backtrace code which showed up only under OS 10.6. + + lib/ + mac/ + mac_backtrace.C + +Charlie 16 Jan 2010 + - Mac Installer: fix bug launching client when configured as a service. + + mac_installer/ + PostInstall.cpp + +Charlie 22 Jan 2010 + Mac Sandbox: To keep authenticators private, make all .xml files readable + only by user and group boinc_master; except ss_config.xml is world- + readable so screensaver coordinator can access it. All other files + except gui_rpc_auth.cfg are world-readable to allow access by + screensavers. + + clientgui/ + mac/ + SetupSecurity.cpp + mac_build/ + Mac_SA_Secure.sh diff --git a/client/check_security.cpp b/client/check_security.cpp index d3e5297b40..94487d479b 100644 --- a/client/check_security.cpp +++ b/client/check_security.cpp @@ -673,7 +673,9 @@ bool IsUserInGroupBM() { return true; // User's primary group is boinc_master } - userName = getlogin(); + // On some systems with Automatic Login set, getlogin() returns "root" for a + // time after the system is first booted, so we check "USER" environment variable. + userName = getenv("USER"); if (userName) { for (i=0; ; i++) { // Step through all users in group boinc_master groupMember = grp->gr_mem[i]; diff --git a/clientgui/mac/SetupSecurity.cpp b/clientgui/mac/SetupSecurity.cpp index b52eebd9b2..faabc2b595 100644 --- a/clientgui/mac/SetupSecurity.cpp +++ b/clientgui/mac/SetupSecurity.cpp @@ -33,6 +33,7 @@ #include "SetupSecurity.h" static OSStatus UpdateNestedDirectories(char * basepath); +static OSStatus MakeXMLFilesPrivate(char * basepath); static OSStatus GetAuthorization(void); OSStatus DoPrivilegedExec(const char *pathToTool, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5); #ifndef __x86_64__ @@ -147,15 +148,15 @@ saverName[2] = "Progress Thru Processors"; strlcpy(fullpath, dir_path, sizeof(fullpath)); #ifdef _DEBUG - // chmod -R u+rw,g+rw,o+r-w path/BOINCManager.app + // chmod -R u=rwx,g=rwx,o=rx path/BOINCManager.app // 0775 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write permission for user; read and execute permission for group and others - err = DoPrivilegedExec(chmodPath, "-R", "u+rw,g+rw,o+r-w", fullpath, NULL, NULL); + // Set read, write permission for user; read and execute permission for group and others + err = DoPrivilegedExec(chmodPath, "-R", "u=rwx,g=rwx,o=rx", fullpath, NULL, NULL); #else - // chmod -R u+r-w,g+r-w,o+r-w path/BOINCManager.app - // 0555 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write permission for user; read and execute permission for group and others - err = DoPrivilegedExec(chmodPath, "-R", "u+r-w,g+r-w,o+r-w", fullpath, NULL, NULL); + // chmod -R u=rx,g=rx,o=rx path/BOINCManager.app + // 0555 = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH + // Set read, write permission for user; read and execute permission for group and others + err = DoPrivilegedExec(chmodPath, "-R", "u=rx,g=rx,o=rx", fullpath, NULL, NULL); #endif if (err) return err; @@ -178,14 +179,14 @@ saverName[2] = "Progress Thru Processors"; return err; #ifdef _DEBUG - // chmod u=rwx,g=rwsx,o=rx path/BOINCManager.app/Contents/MacOS/BOINCManager + // chmod u=rwx,g=rwx,o=rx path/BOINCManager.app/Contents/MacOS/BOINCManager // 0775 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write and execute permission for user & group, read & execute for others + // Set read, write and execute permission for user & group, read & execute for others err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=rx", fullpath, NULL, NULL, NULL); #else - // chmod u=rx,g=rsx,o=rx path/BOINCManager.app/Contents/MacOS/BOINCManager + // chmod u=rx,g=rx,o=rx path/BOINCManager.app/Contents/MacOS/BOINCManager // 0555 = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH - // read and execute permission for user, group & others + // Set read and execute permission for user, group & others err = DoPrivilegedExec(chmodPath, "u=rx,g=rx,o=rx", fullpath, NULL, NULL, NULL); #endif if (err) @@ -208,12 +209,12 @@ saverName[2] = "Progress Thru Processors"; #ifdef _DEBUG // chmod u=rwsx,g=rwsx,o=rx path/BOINCManager.app/Contents/Resources/boinc // 06775 = S_ISUID | S_ISGID | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH - // setuid-on-execution, setgid-on-execution plus read, write and execute permission for user & group, read & execute for others + // Set setuid-on-execution, setgid-on-execution plus read, write and execute permission for user & group, read & execute for others err = DoPrivilegedExec(chmodPath, "u=rwsx,g=rwsx,o=rx", fullpath, NULL, NULL, NULL); #else // chmod u=rsx,g=rsx,o=rx path/BOINCManager.app/Contents/Resources/boinc // 06555 = S_ISUID | S_ISGID | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH - // setuid-on-execution, setgid-on-execution plus read and execute permission for user, group & others + // Set setuid-on-execution, setgid-on-execution plus read and execute permission for user, group & others err = DoPrivilegedExec(chmodPath, "u=rsx,g=rsx,o=rx", fullpath, NULL, NULL, NULL); #endif if (err) @@ -238,7 +239,7 @@ saverName[2] = "Progress Thru Processors"; // chmod u=rwx,g=rwx,o=rx "/Library/Screen Savers/BOINCSaver.saver/Contents/Resources/gfx_switcher" // 0775 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write and execute permission for user & group; read and execute permission for others + // Set read, write and execute permission for user & group; read and execute permission for others err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=rx", fullpath, NULL, NULL, NULL); if (err) return err; @@ -251,7 +252,7 @@ saverName[2] = "Progress Thru Processors"; // chmod u=rsx,g=rx,o=rx "/Library/Screen Savers/BOINCSaver.saver/Contents/Resources/gfx_switcher" // 04555 = S_ISUID | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH - // setuid-on-execution plus read and execute permission for user, group & others + // Set setuid-on-execution plus read and execute permission for user, group & others err = DoPrivilegedExec(chmodPath, "u=rsx,g=rx,o=rx", fullpath, NULL, NULL, NULL); if (err) return err; @@ -281,22 +282,14 @@ int SetBOINCDataOwnersGroupsAndPermissions() { strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); // Does BOINC Data directory exist? - result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); + result = FSPathMakeRef((StringPtr)BOINCDataDirPath, &ref, &isDirectory); if ((result != noErr) || (! isDirectory)) return dirNFErr; // BOINC Data Directory does not exist // Set owner and group of BOINC Data directory's contents sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name); // chown -R boinc_master:boinc_master "/Library/Application Support/BOINC Data" - err = DoPrivilegedExec(chownPath, "-R", buf1, fullpath, NULL, NULL); - if (err) - return err; - - // Set permissions of BOINC Data directory's contents - // chmod -R u+rw,g+rw,o-rw "/Library/Application Support/BOINC Data" - // 0661 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH - // set read and write permission for user and group, no access for others (leaves execute bits unchanged) - err = DoPrivilegedExec(chmodPath, "-R", "u+rw,g+rw,o+r-w", fullpath, NULL, NULL); + err = DoPrivilegedExec(chownPath, "-R", buf1, BOINCDataDirPath, NULL, NULL); if (err) return err; @@ -304,19 +297,26 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Set owner and group of BOINC Data directory itself sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name); // chown boinc_master:boinc_master "/Library/Application Support/BOINC Data" - err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL); + err = DoPrivilegedExec(chownPath, buf1, BOINCDataDirPath, NULL, NULL, NULL); if (err) return err; #endif - // Set permissions of BOINC Data directory itself - // chmod u=rwx,g=rwx,o=x "/Library/Application Support/BOINC Data" - // 0771 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IXOTH - // read, write and execute permission for user & group; read and execute permission for others - err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=x", fullpath, NULL, NULL, NULL); + // Set permissions of BOINC Data directory's contents: + // ss_config.xml is world-readable so screensaver coordinator can read it + // all other *.xml are not world-readable to keep authenticators private + // gui_rpc_auth.cfg is not world-readable to keep RPC password private + // all other files are world-readable so default screensaver can read them + + // First make all files world-readable (temporarily) + // chmod -R u+rw,g+rw,o+r-w "/Library/Application Support/BOINC Data" + // 0661 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH + // Set read and write permission for user and group, read-only for others (leaves execute bits unchanged) + err = DoPrivilegedExec(chmodPath, "-R", "u+rw,g+rw,o+r-w", BOINCDataDirPath, NULL, NULL); if (err) return err; + // Next make gui_rpc_auth.cfg not world-readable to keep RPC password private // Does gui_rpc_auth.cfg file exist? strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); strlcat(fullpath, "/", MAXPATHLEN); @@ -335,12 +335,52 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // chmod u=rw,g=rw,o= "/Library/Application Support/BOINC Data/gui_rpc_auth.cfg" // 0660 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP - // read, write and execute permission for user, group & others + // Set read and write permission for user and group, no access for others err = DoPrivilegedExec(chmodPath, "u=rw,g=rw,o=", fullpath, NULL, NULL, NULL); if (err) return err; } // gui_rpc_auth.cfg + // Next make all *.xml files not world-readable to keep authenticators private + err = MakeXMLFilesPrivate(BOINCDataDirPath); + if (err) + return err; + + // Next make ss_config.xml world-readable so screensaver coordinator can read it + // Does screensaver config file ss_config.xml exist? + strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); + strlcat(fullpath, "/", MAXPATHLEN); + strlcat(fullpath, SS_CONFIG_FILE, MAXPATHLEN); + + result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); + if ((result == noErr) && (! isDirectory)) { + // Make ss_config.xml file world readable but writable only by user boinc_master and group boinc_master + + // Set owner and group of ss_config.xml file + sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name); + // chown boinc_master:boinc_master "/Library/Application Support/BOINC Data/ss_config.xml" + err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL); + if (err) + return err; + + // chmod u=rw,g=rw,o=r "/Library/Application Support/BOINC Data/ss_config.xml" + // 0664 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH + // Set read and write permission for user and group, read-only for others + err = DoPrivilegedExec(chmodPath, "u=rw,g=rw,o=r", fullpath, NULL, NULL, NULL); + if (err) + return err; + } // ss_config.xml + + + // Set permissions of BOINC Data directory itself + // chmod u=rwx,g=rwx,o=x "/Library/Application Support/BOINC Data" + // 0771 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IXOTH + // Set read, write and execute permission for user & group; execute-only permission for others + err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=x", BOINCDataDirPath, NULL, NULL, NULL); + if (err) + return err; + + // Does projects directory exist? strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); strlcat(fullpath, "/", MAXPATHLEN); @@ -365,17 +405,17 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Set permissions for projects directory itself (not its contents) // chmod u=rwx,g=rwx,o=rx "/Library/Application Support/BOINC Data/projects" // 0775 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write and execute permission for user & group; read and execute permission for others + // Set read, write and execute permission for user & group; read and execute permission for others err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=rx", fullpath, NULL, NULL, NULL); if (err) return err; // Set permissions of projects directory's contents // Contents of project directories must be world-readable so BOINC Client can read - // files written by projects whcih have user boinc_project and group boinc_project + // files written by projects which have user boinc_project and group boinc_project // chmod -R u+rw,g+rw,o+r-w "/Library/Application Support/BOINC Data/projects" // 0664 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH - // set read and write permission for user and group, no access for others (leaves execute bits unchanged) + // Set read and write permission for user and group, read-only for others (leaves execute bits unchanged) err = DoPrivilegedExec(chmodPath, "-R", "u+rw,g+rw,o+r-w", fullpath, NULL, NULL); if (err) return err; @@ -410,7 +450,7 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Set permissions for slots directory itself (not its contents) // chmod u=rwx,g=rwx,o=rx "/Library/Application Support/BOINC Data/slots" // 0775 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write and execute permission for user & group; read and execute permission for others + // Set read, write and execute permission for user & group; read and execute permission for others err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=rx", fullpath, NULL, NULL, NULL); if (err) return err; @@ -420,7 +460,7 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // files written by projects whcih have user boinc_project and group boinc_project // chmod -R u+rw,g+rw,o+r-w "/Library/Application Support/BOINC Data/slots" // 0664 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH - // set read and write permission for user and group, no access for others (leaves execute bits unchanged) + // Set read and write permission for user and group, read-only for others (leaves execute bits unchanged) err = DoPrivilegedExec(chmodPath, "-R", "u+rw,g+rw,o+r-w", fullpath, NULL, NULL); if (err) return err; @@ -446,10 +486,11 @@ int SetBOINCDataOwnersGroupsAndPermissions() { return err; #endif - // chmod -R u+r-w,g+r-w,o= "/Library/Application Support/BOINC Data/locale" + // chmod -R u+r-w,g+r-w,o+r-w "/Library/Application Support/BOINC Data/locale" // 0550 = S_IRUSR | S_IXUSR | S_IRGRP | S_IXUSR | S_IROTH | S_IXOTH - // set read and execute only permission for user, group, and others + // Set execute permission for user, group, and others if it was set for any err = DoPrivilegedExec(chmodPath, "-R", "+X", fullpath, NULL, NULL); + // Set read-only permission for user, group, and others (leaves execute bits unchanged) err = DoPrivilegedExec(chmodPath, "-R", "u+r-w,g+r-w,o+r-w", fullpath, NULL, NULL); if (err) return err; @@ -473,7 +514,7 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // chmod u=rx,g=rx,o= "/Library/Application Support/BOINC Data/switcher" // 0550 = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP - // set read and execute permission for user and group, no access for others + // Set read and execute permission for user and group, no access for others err = DoPrivilegedExec(chmodPath, "u=rx,g=rx,o=", fullpath, NULL, NULL, NULL); if (err) return err; @@ -493,7 +534,7 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Set permissions of switcher application // chmod u=s,g=rx,o= "/Library/Application Support/BOINC Data/switcher/switcher" // 04050 = S_ISUID | S_IRGRP | S_IXGRP - // setuid-on-execution, setgid-on-execution plus read and execute permission for group boinc_master only + // Set setuid-on-execution plus read and execute permission for group boinc_master only err = DoPrivilegedExec(chmodPath, "u=s,g=rx,o=", fullpath, NULL, NULL, NULL); if (err) return err; @@ -514,9 +555,9 @@ int SetBOINCDataOwnersGroupsAndPermissions() { return err; // Set permissions of setprojectgrp application - // chmod u=rx,g=rsx,o= "/Library/Application Support/BOINC Data/switcher/setprojectgrp" + // chmod u=rx,g=s,o= "/Library/Application Support/BOINC Data/switcher/setprojectgrp" // 02500 = S_ISGID | S_IRUSR | S_IXUSR - // setgid-on-execution plus read and execute permission for user only + // Set setgid-on-execution plus read and execute permission for user only err = DoPrivilegedExec(chmodPath, "u=rx,g=s,o=", fullpath, NULL, NULL, NULL); if (err) return err; @@ -541,7 +582,7 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Set permissions of AppStats application // chmod u=rsx,g=rx,o= "/Library/Application Support/BOINC Data/switcher/AppStats" // 04550 = S_ISUID | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP - // setuid-on-execution plus read and execute permission for user and group + // Set setuid-on-execution plus read and execute permission for user and group err = DoPrivilegedExec(chmodPath, "u=rsx,g=rx,o=", fullpath, NULL, NULL, NULL); if (err) return err; @@ -549,34 +590,55 @@ int SetBOINCDataOwnersGroupsAndPermissions() { #endif #endif // __APPLE__ - // Does screensaver config file ss_config.xml exist? - strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); - strlcat(fullpath, "/", MAXPATHLEN); - strlcat(fullpath, SS_CONFIG_FILE, MAXPATHLEN); - - result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); - if ((result == noErr) && (! isDirectory)) { - // Make ss_config.xml file world readable but writable only by user boinc_master and group boinc_master - - // Set owner and group of ss_config.xml file - sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name); - // chown boinc_master:boinc_master "/Library/Application Support/BOINC Data/ss_config.xml" - err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL); - if (err) - return err; - - // chmod u=rw,g=rw,o=r "/Library/Application Support/BOINC Data/ss_config.xml" - // 0664 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH - // read, write and execute permission for user, group & others - err = DoPrivilegedExec(chmodPath, "u=rw,g=rw,o=r", fullpath, NULL, NULL, NULL); - if (err) - return err; - } // ss_config.xml - return noErr; } +// make all *.xml files not world-readable to keep authenticators private +static OSStatus MakeXMLFilesPrivate(char * basepath) { + char fullpath[MAXPATHLEN]; + OSStatus retval = 0; + DIR *dirp; + int len; + dirent *dp; + + dirp = opendir(basepath); + if (dirp == NULL) // Should never happen + return -1; + + while (true) { + dp = readdir(dirp); + if (dp == NULL) + break; // End of list + + if (dp->d_name[0] == '.') + continue; // Ignore names beginning with '.' + + len = strlen(dp->d_name); + if (len < 5) + continue; + + if (strcmp(dp->d_name+len-4, ".xml")) + continue; + + strlcpy(fullpath, basepath, sizeof(fullpath)); + strlcat(fullpath, "/", sizeof(fullpath)); + strlcat(fullpath, dp->d_name, sizeof(fullpath)); + + // chmod u+rw,g+rw,o= "/Library/Application Support/BOINC Data/????.xml" + // 0660 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP0 + // Set read and write permission for user and group, no access for others + retval = DoPrivilegedExec(chmodPath, "u+rw,g+rw,o=", fullpath, NULL, NULL, NULL); + if (retval) + break; + } // End while (true) + + closedir(dirp); + + return retval; +} + + static OSStatus UpdateNestedDirectories(char * basepath) { Boolean isDirectory; char fullpath[MAXPATHLEN]; @@ -617,7 +679,7 @@ static OSStatus UpdateNestedDirectories(char * basepath) { if (isDirectory) { // chmod u=rwx,g=rwx,o=rx fullpath // 0775 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH - // read, write and execute permission for user & group; read and execute permission for others + // Set read, write and execute permission for user & group; read and execute permission for others retval = DoPrivilegedExec(chmodPath, "u=rwx,g=rwx,o=rx", fullpath, NULL, NULL, NULL); if (retval) break; @@ -785,14 +847,14 @@ int AddAdminUserToGroups(char *user_name, bool add_to_boinc_project) { return err; if (add_to_boinc_project) { - sprintf(buf1, "/groups/%s", boinc_project_group_name); + sprintf(buf1, "/groups/%s", boinc_project_group_name); - // "dscl . -merge /groups/boinc_project users user_name" - err = DoPrivilegedExec(dsclPath, ".", "-merge", buf1, "users", user_name); - if (err) - return err; + // "dscl . -merge /groups/boinc_project users user_name" + err = DoPrivilegedExec(dsclPath, ".", "-merge", buf1, "users", user_name); + if (err) + return err; } - + err = ResynchSystem(); if (err != noErr) return err; diff --git a/lib/mac/mac_backtrace.cpp b/lib/mac/mac_backtrace.cpp index cc6d79d8f3..15a948e465 100644 --- a/lib/mac/mac_backtrace.cpp +++ b/lib/mac/mac_backtrace.cpp @@ -178,17 +178,17 @@ void PrintBacktrace(void) { if (f) { setbuf(f, 0); for (i=0; igr_mem[i]) != NULL) { // Step through all users in group admin - if (strcmp(p, q) == 0) { + if (strcmp(p, loginName) == 0) { Success = true; // Logged in user is a member of group admin break; } @@ -441,7 +447,7 @@ int DeleteReceipt() if (finalInstallAction == launchWhenDone) { // If system is set up to run BOINC Client as a daemon using launchd, launch it // as a daemon and allow time for client to start before launching BOINC Manager. - err = stat("launchctl unload /Library/LaunchDaemons/edu.berkeley.boinc.plist", &sbuf); + err = stat("/Library/LaunchDaemons/edu.berkeley.boinc.plist", &sbuf); if (err == noErr) { system("launchctl unload /Library/LaunchDaemons/edu.berkeley.boinc.plist"); i = system("launchctl load /Library/LaunchDaemons/edu.berkeley.boinc.plist"); @@ -470,7 +476,7 @@ OSStatus CheckLogoutRequirement(int *finalAction) CFStringRef errorString = NULL; OSStatus err = noErr; #ifdef SANDBOX - char *p, *loginName = NULL; + char *p; group *grp = NULL; int i; Boolean isMember = false; @@ -478,8 +484,11 @@ OSStatus CheckLogoutRequirement(int *finalAction) *finalAction = restartRequired; + if (OSVersion < 0x1040) { + return noErr; // Always require restart on OS 10.3.9 + } + #ifdef SANDBOX - loginName = getlogin(); grp = getgrnam("boinc_master"); if (loginName && grp) { i = 0; @@ -492,7 +501,7 @@ OSStatus CheckLogoutRequirement(int *finalAction) } } - if (!isMember) { + if (!isMember && !currentUserCanRunBOINC) { *finalAction = nothingrequired; return noErr; } @@ -790,12 +799,10 @@ Boolean CheckDeleteFile(char *name) void SetEUIDBackToUser (void) { - char *p; uid_t login_uid; passwd *pw; - p = getlogin(); - pw = getpwnam(p); + pw = getpwnam(loginName); login_uid = pw->pw_uid; setuid(login_uid); @@ -879,16 +886,11 @@ OSErr UpdateAllVisibleUsers(long brandID) Boolean found = false; FILE *f; OSStatus err; - long OSVersion; Boolean isGroupMember; #ifdef SANDBOX char *p; short i; - err = Gestalt(gestaltSystemVersion, &OSVersion); - if (err != noErr) - return err; - err = getgrnam_r("admin", &grpAdmin, adminBuf, sizeof(adminBuf), &grpAdminPtr); if (err) { // Should never happen unless buffer too small puts("getgrnam(\"admin\") failed\n"); @@ -957,6 +959,10 @@ OSErr UpdateAllVisibleUsers(long brandID) #endif // SANDBOX if (isGroupMember) { + if (strcmp(loginName, dp->d_name) == 0) { + currentUserCanRunBOINC = true; + } + saved_uid = geteuid(); seteuid(pw->pw_uid); // Temporarily set effective uid to this user @@ -1004,6 +1010,7 @@ OSErr UpdateAllVisibleUsers(long brandID) brandName[brandID], brandName[brandID]) ) { allowNonAdminUsersToRunBOINC = true; + currentUserCanRunBOINC = true; saverAlreadySetForAll = false; } } @@ -1153,13 +1160,9 @@ int TestRPCBind() static OSStatus ResynchSystem() { - SInt32 response; OSStatus err = noErr; - err = Gestalt(gestaltSystemVersion, &response); - if (err) return err; - - if (response >= 0x1050) { + if (OSVersion >= 0x1050) { // OS 10.5 err = system("dscacheutil -flushcache"); err = system("dsmemberutil flushcache"); @@ -1168,8 +1171,7 @@ static OSStatus ResynchSystem() { err = system("lookupd -flushcache"); - err = Gestalt(gestaltSystemVersion, &response); - if ((err == noErr) && (response >= 0x1040)) + if (OSVersion >= 0x1040) err = system("memberd -r"); // Available only in OS 10.4 return noErr; diff --git a/mac_installer/uninstall.cpp b/mac_installer/uninstall.cpp index 9bab3aa488..fb8f5d9b36 100644 --- a/mac_installer/uninstall.cpp +++ b/mac_installer/uninstall.cpp @@ -359,17 +359,27 @@ static OSStatus CleanupAllVisibleUsers(void) DIR *dirp; dirent *dp; passwd *pw; - uid_t saved_uid; + uid_t saved_uid, saved_euid; char s[1024]; FILE *f; + long OSVersion = 0; + OSStatus err; Boolean changeSaver; + err = Gestalt(gestaltSystemVersion, &OSVersion); + if (err != noErr) { + OSVersion = 0; + } + dirp = opendir("/Users"); if (dirp == NULL) { // Should never happen ShowMessage(false, "opendir(\"/Users\") failed"); return -1; } + saved_uid = getuid(); + saved_euid = geteuid(); + while (true) { dp = readdir(dirp); if (dp == NULL) @@ -393,7 +403,9 @@ static OSStatus CleanupAllVisibleUsers(void) // ShowMessage(false, "Before seteuid(%d) for user %s, euid = %d", pw->pw_uid, dp->d_name, geteuid()); #endif - saved_uid = geteuid(); + if (OSVersion >= 0x1060) { + setuid(0); + } seteuid(pw->pw_uid); // Temporarily set effective uid to this user DeleteLoginItem(); // Delete our login item(s) for this user @@ -404,24 +416,44 @@ static OSStatus CleanupAllVisibleUsers(void) // Set screensaver to "Computer Name" default screensaver only // if it was BOINC, GridRepublic or Progress Thru Processors. changeSaver = false; - f = popen("defaults -currentHost read com.apple.screensaver moduleName", "r"); + if (OSVersion < 0x1060) { + f = popen("defaults -currentHost read com.apple.screensaver moduleName", "r"); + } else { + sprintf(s, "sudo -u %s defaults -currentHost read com.apple.screensaver moduleDict -dict", + dp->d_name); + f = popen(s, "r"); + } if (f) { - PersistentFGets(s, sizeof(s), f); - if (strstr(s, "BOINCSaver")) - changeSaver = true; - if (strstr(s, "GridRepublic")) - changeSaver = true; - if (strstr(s, "Progress Thru Processors")) - changeSaver = true; + while (PersistentFGets(s, sizeof(s), f)) { + if (strstr(s, "BOINCSaver")) { + changeSaver = true; + break; + } + if (strstr(s, "GridRepublic")) { + changeSaver = true; + break; + } + if (strstr(s, "Progress Thru Processors")) { + changeSaver = true; + break; + } + } pclose(f); } if (changeSaver) { - system ("defaults -currentHost write com.apple.screensaver moduleName \"Computer Name\""); - system ("defaults -currentHost write com.apple.screensaver modulePath \"/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/Computer Name.saver\""); + if (OSVersion < 0x1060) { + system ("defaults -currentHost write com.apple.screensaver moduleName \"Computer Name\""); + system ("defaults -currentHost write com.apple.screensaver modulePath \"/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/Computer Name.saver\""); + } else { + sprintf(s, + "sudo -u %s defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName \"Computer Name\" path \"/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/Computer Name.saver\"", + dp->d_name); + system (s); + } } - seteuid(saved_uid); // Set effective uid back to privileged user + seteuid(saved_euid); // Set effective uid back to privileged user #if TESTING // ShowMessage(false, "After seteuid(%d) for user %s, euid = %d, saved_uid = %d", pw->pw_uid, dp->d_name, geteuid(), saved_uid); #endif