diff --git a/checkin_notes b/checkin_notes index 00f572f330..592b896998 100644 --- a/checkin_notes +++ b/checkin_notes @@ -9302,3 +9302,27 @@ Rom 17 Nov 2009 nvidiaicon.xpm (Added) win_build/ boincmgr.vcproj + +Charlie 18 Nov 2009 + - Mac installer: fix 2 installer bugs: + - Install by non-admin user failed to set login items. + - Clean installs failed with permissions error -1037. A reboot would + fix this, but system reboots are undesireable. The problem is + that when we create group boinc_master and add the user to the + group, it takes about a minute for the permissions to take effect. + I added a test which delays launching the manager until the + permissions are stable. + + clientgui/ + mac/ + SetVersion.cpp + mac_installer/ + make_GridRepublic.sh + make_ProgThruProc.sh + PostInstall.cpp + release_boinc.sh + WaitPermissions.cpp (Added) + mac_build/ + boinc.xcodeproj/ + project.pbxproj + WaitPermissions-Info.plist (Added) diff --git a/clientgui/mac/SetVersion.cpp b/clientgui/mac/SetVersion.cpp index f7a50b8e67..a99c5a6e29 100644 --- a/clientgui/mac/SetVersion.cpp +++ b/clientgui/mac/SetVersion.cpp @@ -63,6 +63,8 @@ int main(int argc, char** argv) { if (err) retval = err; err = FixInfoPlistFile("./Uninstaller-Info.plist"); if (err) retval = err; + err = FixInfoPlistFile("./WaitPermissions-Info.plist"); + if (err) retval = err; err = MakeInstallerInfoPlistFile("./Pkg-Info.plist", "BOINC Manager"); return retval; } diff --git a/mac_build/WaitPermissions-Info.plist b/mac_build/WaitPermissions-Info.plist new file mode 100644 index 0000000000..2aa565bc96 --- /dev/null +++ b/mac_build/WaitPermissions-Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + edu.berkeley.boinc.WaitPermissions + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 6.11.0 + + diff --git a/mac_build/boinc.xcodeproj/project.pbxproj b/mac_build/boinc.xcodeproj/project.pbxproj index b98498b3c0..4234bac6da 100755 --- a/mac_build/boinc.xcodeproj/project.pbxproj +++ b/mac_build/boinc.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ DDBD52900C16C3790074905B /* PBXTargetDependency */, DD095D1F0F3B22DE000902F5 /* PBXTargetDependency */, DDD3370C106224FF00867C7D /* PBXTargetDependency */, + DDB219B410B3BBD000417AEF /* PBXTargetDependency */, ); name = Build_All; productName = Build_All; @@ -277,6 +278,7 @@ DDAD31D80EC26B14002DA09D /* mac_address.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDAD31D60EC26B14002DA09D /* mac_address.cpp */; }; DDAD31D90EC26B14002DA09D /* mac_address.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDAD31D60EC26B14002DA09D /* mac_address.cpp */; }; DDAEC9FF07FA5A5C00A7BC36 /* SetVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDAEC9E707FA58A000A7BC36 /* SetVersion.cpp */; }; + DDB219B210B3BBA900417AEF /* WaitPermissions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB219B110B3BBA900417AEF /* WaitPermissions.cpp */; }; DDB693500ABFE9C600689FD8 /* procinfo_mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB6934F0ABFE9C600689FD8 /* procinfo_mac.cpp */; }; DDB6E3EF0D5B27AA00ED12B8 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; DDB74A6C0D74259E00E97A40 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDFE854A0B60CFD0009B43D9 /* AppKit.framework */; }; @@ -528,6 +530,13 @@ remoteGlobalIDString = DDAEC9E007FA583B00A7BC36; remoteInfo = SetVersion; }; + DDB219B310B3BBD000417AEF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 20286C28FDCF999611CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = DDB219A310B3BB6100417AEF; + remoteInfo = WaitPermissions; + }; DDB874660C850DB600E0DE1F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 20286C28FDCF999611CA2CEA /* Project object */; @@ -868,6 +877,9 @@ DDAD31D70EC26B14002DA09D /* mac_address.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mac_address.h; path = ../lib/mac_address.h; sourceTree = SOURCE_ROOT; }; DDAEC9E107FA583B00A7BC36 /* SetVersion */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SetVersion; sourceTree = BUILT_PRODUCTS_DIR; }; DDAEC9E707FA58A000A7BC36 /* SetVersion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SetVersion.cpp; path = ../clientgui/mac/SetVersion.cpp; sourceTree = SOURCE_ROOT; }; + DDB219A410B3BB6100417AEF /* WaitPermissions.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WaitPermissions.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DDB219A610B3BB6200417AEF /* WaitPermissions-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "WaitPermissions-Info.plist"; sourceTree = ""; }; + DDB219B110B3BBA900417AEF /* WaitPermissions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WaitPermissions.cpp; path = ../mac_installer/WaitPermissions.cpp; sourceTree = SOURCE_ROOT; }; DDB506F80958446900181B75 /* ProxyInfoPage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ProxyInfoPage.cpp; path = ../clientgui/ProxyInfoPage.cpp; sourceTree = SOURCE_ROOT; }; DDB506F90958446900181B75 /* ProxyInfoPage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ProxyInfoPage.h; path = ../clientgui/ProxyInfoPage.h; sourceTree = SOURCE_ROOT; }; DDB6934F0ABFE9C600689FD8 /* procinfo_mac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = procinfo_mac.cpp; sourceTree = ""; }; @@ -1099,6 +1111,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DDB219A210B3BB6100417AEF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DDB873F80C850BC800E0DE1F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1170,6 +1189,7 @@ DDFA60D40CB337D40037B88C /* gfx_switcher */, DD8916280F3B17E900DE5B1C /* boincscr */, DDD337021062235D00867C7D /* AddRemoveUser */, + DDB219A410B3BB6100417AEF /* WaitPermissions.app */, ); name = Products; sourceTree = SOURCE_ROOT; @@ -1193,6 +1213,7 @@ DD1277B5081F3D67007B5DE1 /* PostInstall-Info.plist */, DD1AFE8F0A512D2600EE5B82 /* Installer-Info.plist */, DD4688430C165F3C0089F500 /* Uninstaller-Info.plist */, + DDB219A610B3BB6200417AEF /* WaitPermissions-Info.plist */, ); name = "«PROJECTNAME»"; sourceTree = ""; @@ -1245,6 +1266,7 @@ DDB8D5A5081FC8C700A5A1E8 /* postinstall */, DD127880081F464E007B5DE1 /* postupgrade */, DDD33709106224E800867C7D /* AddRemoveUser.cpp */, + DDB219B110B3BBA900417AEF /* WaitPermissions.cpp */, ); name = mac_installer; sourceTree = SOURCE_ROOT; @@ -1901,6 +1923,23 @@ productReference = DDAEC9E107FA583B00A7BC36 /* SetVersion */; productType = "com.apple.product-type.tool"; }; + DDB219A310B3BB6100417AEF /* WaitPermissions */ = { + isa = PBXNativeTarget; + buildConfigurationList = DDB219AE10B3BB6200417AEF /* Build configuration list for PBXNativeTarget "WaitPermissions" */; + buildPhases = ( + DDB219A010B3BB6100417AEF /* Resources */, + DDB219A110B3BB6100417AEF /* Sources */, + DDB219A210B3BB6100417AEF /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WaitPermissions; + productName = WaitPermissions; + productReference = DDB219A410B3BB6100417AEF /* WaitPermissions.app */; + productType = "com.apple.product-type.application"; + }; DDB873E90C850BC800E0DE1F /* gfx2libboinc */ = { isa = PBXNativeTarget; buildConfigurationList = DDB873FC0C850BC800E0DE1F /* Build configuration list for PBXNativeTarget "gfx2libboinc" */; @@ -2039,6 +2078,7 @@ DDFA60C90CB337D40037B88C /* gfx_switcher */, DD89161C0F3B17E900DE5B1C /* ss_app */, DDD336F51062235D00867C7D /* AddRemoveUser */, + DDB219A310B3BB6100417AEF /* WaitPermissions */, ); }; /* End PBXProject section */ @@ -2116,6 +2156,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DDB219A010B3BB6100417AEF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ @@ -2642,6 +2689,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DDB219A110B3BB6100417AEF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DDB219B210B3BBA900417AEF /* WaitPermissions.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DDB873EA0C850BC800E0DE1F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2876,6 +2931,11 @@ target = DDAEC9E007FA583B00A7BC36 /* SetVersion */; targetProxy = DDAD19DE09090914004E7DD0 /* PBXContainerItemProxy */; }; + DDB219B410B3BBD000417AEF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DDB219A310B3BB6100417AEF /* WaitPermissions */; + targetProxy = DDB219B310B3BBD000417AEF /* PBXContainerItemProxy */; + }; DDB874670C850DB600E0DE1F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DDB873E90C850BC800E0DE1F /* gfx2libboinc */; @@ -5046,6 +5106,145 @@ }; name = i386_Deployment; }; + DDB219A710B3BB6200417AEF /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + }; + name = Development; + }; + DDB219A810B3BB6200417AEF /* Dev_noSandbox */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + }; + name = Dev_noSandbox; + }; + DDB219A910B3BB6200417AEF /* ppc_Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + }; + name = ppc_Deployment; + }; + DDB219AA10B3BB6200417AEF /* i386_Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + }; + name = i386_Deployment; + }; + DDB219AB10B3BB6200417AEF /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + ZERO_LINK = NO; + }; + name = Deployment; + }; + DDB219AC10B3BB6200417AEF /* Deployment-no64 */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + }; + name = "Deployment-no64"; + }; + DDB219AD10B3BB6200417AEF /* Deploy_noSandbox */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + INFOPLIST_FILE = "WaitPermissions-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + ); + PREBINDING = NO; + PRODUCT_NAME = WaitPermissions; + }; + name = Deploy_noSandbox; + }; DDB873FD0C850BC800E0DE1F /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5503,6 +5702,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = ppc_Deployment; }; + DDB219AE10B3BB6200417AEF /* Build configuration list for PBXNativeTarget "WaitPermissions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DDB219A710B3BB6200417AEF /* Development */, + DDB219A810B3BB6200417AEF /* Dev_noSandbox */, + DDB219A910B3BB6200417AEF /* ppc_Deployment */, + DDB219AA10B3BB6200417AEF /* i386_Deployment */, + DDB219AB10B3BB6200417AEF /* Deployment */, + DDB219AC10B3BB6200417AEF /* Deployment-no64 */, + DDB219AD10B3BB6200417AEF /* Deploy_noSandbox */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ppc_Deployment; + }; DDB873FC0C850BC800E0DE1F /* Build configuration list for PBXNativeTarget "gfx2libboinc" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/mac_installer/PostInstall.cpp b/mac_installer/PostInstall.cpp index a574b3e6dd..addecdfabc 100755 --- a/mac_installer/PostInstall.cpp +++ b/mac_installer/PostInstall.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2009 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -34,7 +34,6 @@ #include #include - #include "LoginItemAPI.h" //please take a look at LoginItemAPI.h for an explanation of the routines available to you. #include "SetupSecurity.h" @@ -42,13 +41,15 @@ void Initialize(void); /* function prototypes */ int DeleteReceipt(void); OSStatus CheckLogoutRequirement(int *finalAction); -void SetLoginItem(long brandID, Boolean deleteLogInItem); +Boolean SetLoginItem(long brandID, Boolean deleteLogInItem); void SetSkinInUserPrefs(char *userName, char *skinName); Boolean CheckDeleteFile(char *name); -void SetUIDBackToUser (void); +void SetEUIDBackToUser (void); +static char * PersistentFGets(char *buf, size_t buflen, FILE *f); OSErr UpdateAllVisibleUsers(long brandID); long GetBrandID(void); int TestRPCBind(void); +static OSStatus ResynchSystem(void); OSErr FindProcess (OSType typeToFind, OSType creatorToFind, ProcessSerialNumberPtr processSN); pid_t FindProcessPID(char* name, pid_t thePID); int FindSkinName(char *name, size_t len); @@ -72,7 +73,8 @@ static char *receiptNameEscaped[NUMBRANDS]; enum { launchWhenDone, logoutRequired, - restartRequired + restartRequired, + nothingrequired }; /****************************************************************** @@ -92,20 +94,20 @@ int main(int argc, char *argv[]) short itemHit; long brandID = 0; int i; - pid_t installerPID = 0, coreClientPID = 0; + pid_t installerPID = 0, coreClientPID = 0, waitPermissionsPID = 0; FSRef fileRef; OSStatus err, err_fsref; FILE *f; char s[256]; + char *q; #ifdef SANDBOX - uid_t savedeuid, b_m_uid; + uid_t saved_euid, saved_uid, b_m_uid; passwd *pw; int finalInstallAction; #else - char *q; group *grp; #endif - + appName[0] = "/Applications/BOINCManager.app"; appNameEscaped[0] = "/Applications/BOINCManager.app"; brandName[0] = "BOINC"; @@ -131,7 +133,7 @@ int main(int argc, char *argv[]) if (strcmp(argv[i], "-part2") == 0) return DeleteReceipt(); } - + Initialize(); ::GetCurrentProcess (&ourProcess); @@ -228,28 +230,6 @@ int main(int argc, char *argv[]) // print_to_log_file("check_security returned %d (repetition=%d)", err, i); } - err = CheckLogoutRequirement(&finalInstallAction); - - if (finalInstallAction != restartRequired) { - // Wait for BOINC's RPC socket address to become available to user boinc_master, in - // case we are upgrading from a version which did not run as user boinc_master. - savedeuid = geteuid(); - - pw = getpwnam("boinc_master"); - b_m_uid = pw->pw_uid; - seteuid(b_m_uid); - - for (i=0; i<120; i++) { - err = TestRPCBind(); - if (err == noErr) - break; - - sleep(1); - } - - seteuid(savedeuid); - } - #else // ! defined(SANDBOX) // The BOINC Manager and Core Client have the set-user-ID-on-execution @@ -328,6 +308,83 @@ int main(int argc, char *argv[]) if (err != noErr) return err; +#ifdef SANDBOX + err = CheckLogoutRequirement(&finalInstallAction); + + if (finalInstallAction == launchWhenDone) { + // Wait for BOINC's RPC socket address to become available to user boinc_master, in + // case we are upgrading from a version which did not run as user boinc_master. + saved_uid = getuid(); + saved_euid = geteuid(); + + pw = getpwnam("boinc_master"); + b_m_uid = pw->pw_uid; + seteuid(b_m_uid); + + for (i=0; i<120; i++) { + err = TestRPCBind(); + if (err == noErr) + break; + + sleep(1); + } + + seteuid(saved_euid); + + ProcessSerialNumber ourPSN; + ProcessInfoRec pInfo; + FSRef ourFSRef, theFSRef; + char thePath[MAXPATHLEN]; + + // Get the full path to this PostInstall application's bundle + err = GetCurrentProcess (&ourPSN); + if (err) + return -1000; // Should never happen + + memset(&pInfo, 0, sizeof(pInfo)); + pInfo.processInfoLength = sizeof( ProcessInfoRec ); + err = GetProcessInformation(&ourPSN, &pInfo); + if (err) + return -1001; // Should never happen + + err = GetProcessBundleLocation(&ourPSN, &ourFSRef); + if (err) + return -1002; // Should never happen + + err = FSRefMakePath (&ourFSRef, (UInt8*)thePath, sizeof(thePath)); + if (err) + return -1003; // Should never happen + + q = strrchr(thePath, '/'); + if (q == NULL) + return -1004; // Should never happen + + *++q = '\0'; + strlcat(thePath, "WaitPermissions.app", sizeof(thePath)); + err = FSPathMakeRef((StringPtr)thePath, &theFSRef, NULL); + + // When we first create the boinc_master group and add the current user to the + // new group, there is a delay before the new group membership is recognized. + // If we launch the BOINC Manager too soon, it will fail with a -1037 permissions + // error, so we wait until the current user can access the switcher application. + // Apparently, in order to get the changed permissions / group membership, we must + // launch a new process belonging to the user. It may also need to be in a new + // process group or new session. Neither system() nor popen() works, even after + // setting the uid and euid back to the logged in user, but LSOpenFSRef() does. + // The WaitPermissions application loops until it can access the switcher + // application. + err = LSOpenFSRef(&theFSRef, NULL); + + for (i=0; i<180; i++) { // Limit delay to 3 minutes + waitPermissionsPID = FindProcessPID("WaitPermissions", 0); + if (waitPermissionsPID == 0) { + break; + } + sleep(1); + } + } +#endif // SANDBOX + return 0; } @@ -344,10 +401,10 @@ int DeleteReceipt() int finalInstallAction; FSRef fileRef; char s[256]; + struct stat sbuf; OSStatus err_fsref; Initialize(); - err = CheckLogoutRequirement(&finalInstallAction); err = FindProcess ('APPL', 'xins', &installerPSN); @@ -373,14 +430,15 @@ int DeleteReceipt() err_fsref = FSPathMakeRef((StringPtr)appName[brandID], &fileRef, NULL); if (finalInstallAction == launchWhenDone) { - if (err_fsref == noErr) { - // 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. + // 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); + if (err == noErr) { system("launchctl unload /Library/LaunchDaemons/edu.berkeley.boinc.plist"); i = system("launchctl load /Library/LaunchDaemons/edu.berkeley.boinc.plist"); if (i == 0) sleep (2); - err = LSOpenFSRef(&fileRef, NULL); } + err = LSOpenFSRef(&fileRef, NULL); } return 0; @@ -402,9 +460,34 @@ OSStatus CheckLogoutRequirement(int *finalAction) CFStringRef valueNoRestart = CFSTR("NoRestart"); CFStringRef errorString = NULL; OSStatus err = noErr; - +#ifdef SANDBOX + char *p, *loginName = NULL; + group *grp = NULL; + int i; + Boolean isMember = false; +#endif *finalAction = restartRequired; + +#ifdef SANDBOX + loginName = getlogin(); + grp = getgrnam("boinc_master"); + if (loginName && grp) { + i = 0; + while ((p = grp->gr_mem[i]) != NULL) { // Step through all users in group boinc_master + if (strcmp(p, loginName) == 0) { + isMember = true; // Logged in user is a member of group boinc_master + break; + } + ++i; + } + } + + if (!isMember) { + *finalAction = nothingrequired; + return noErr; + } +#endif getcwd(path, sizeof(path)); strlcat(path, "/Contents/Info.plist", sizeof(path)); @@ -453,7 +536,7 @@ OSStatus CheckLogoutRequirement(int *finalAction) } -void SetLoginItem(long brandID, Boolean deleteLogInItem) +Boolean SetLoginItem(long brandID, Boolean deleteLogInItem) { Boolean Success; int NumberOfLoginItems, Counter; @@ -497,9 +580,11 @@ void SetLoginItem(long brandID, Boolean deleteLogInItem) } if (deleteLogInItem) - return; + return false; Success = AddLoginItemWithPropertiesToUser(kCurrentUser, appName[brandID], kHideOnLaunch); + + return Success; } // Sets the skin selection in the specified user's preferences to the specified skin @@ -581,7 +666,7 @@ Boolean CheckDeleteFile(char *name) return false; } -void SetUIDBackToUser (void) +void SetEUIDBackToUser (void) { char *p; uid_t login_uid; @@ -592,6 +677,7 @@ void SetUIDBackToUser (void) login_uid = pw->pw_uid; setuid(login_uid); + seteuid(login_uid); } @@ -780,6 +866,14 @@ OSErr UpdateAllVisibleUsers(long brandID) closedir(dirp); + ResynchSystem(); + + err = getgrnam_r("boinc_master", &grpBOINC_master, bmBuf, sizeof(bmBuf), &grpBOINC_masterPtr); + if (err) { // Should never happen unless buffer too small + puts("getgrnam(\"boinc_master\") failed\n"); + return -1; + } + if (! allNonAdminUsersAreSet) { if (ShowMessage(true, "Users who are permitted to administer this computer will automatically be allowed to " @@ -872,6 +966,8 @@ OSErr UpdateAllVisibleUsers(long brandID) closedir(dirp); + ResynchSystem(); + return noErr; } @@ -934,6 +1030,30 @@ int TestRPCBind() } +static OSStatus ResynchSystem() { + SInt32 response; + OSStatus err = noErr; + + err = Gestalt(gestaltSystemVersion, &response); + if (err) return err; + + if (response >= 0x1050) { + // OS 10.5 + err = system("dscacheutil -flushcache"); + err = system("dsmemberutil flushcache"); + return noErr; + } + + err = system("lookupd -flushcache"); + + err = Gestalt(gestaltSystemVersion, &response); + if ((err == noErr) && (response >= 0x1040)) + err = system("memberd -r"); // Available only in OS 10.4 + + return noErr; +} + + // --------------------------------------------------------------------------- /* This runs through the process list looking for the indicated application */ /* Searches for process by file type and signature (creator code) */ @@ -1016,7 +1136,7 @@ pid_t FindProcessPID(char* name, pid_t thePID) while (PersistentFGets(buf, sizeof(buf), f)) { - if (name != NULL) { // Search ny name + if (name != NULL) { // Search by name if (strncmp(buf, name, n) == 0) { aPID = atol(buf+16); diff --git a/mac_installer/WaitPermissions.cpp b/mac_installer/WaitPermissions.cpp new file mode 100644 index 0000000000..7391c3e21d --- /dev/null +++ b/mac_installer/WaitPermissions.cpp @@ -0,0 +1,103 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2009 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +/* WaitPermissions.cpp */ + +#define CREATE_LOG 1 /* for debugging */ + +#include + +#include // for stat +#include // getuid + +void print_to_log_file(const char *format, ...); +void strip_cr(char *buf); + +// When we first create the boinc_master group and add the current user to the +// new group, there is a delay before the new group membership is recognized. +// If we launch the BOINC Manager too soon, it will fail with a -1037 permissions +// error, so we wait until the current user can access the switcher application. +// Apparently, in order to get the changed permissions / group membership, we must +// launch a new process belonging to the user. It may also need to be in a new +// process group or new session. Neither system() nor popen() works, even after +// setting the uid and euid back to the logged in user, but LSOpenFSRef() does. +// This tiny application loops until it can access the switcher application. + +int main(int argc, char *argv[]) +{ + struct stat sbuf; + int i; + int retval; + + for (i=0; i<180; i++) { // Limit delay to 3 minutes + retval = stat("/Library/Application Support/BOINC Data/switcher/switcher", &sbuf); +// print_to_log_file("WaitPermissions: stat(switcher path) returned %d, uid = %d, euid = %d\n", retval, (int)getuid(), (int)geteuid()); + if (retval == 0) { + return 0; + } + sleep(1); + } + return retval; +} + +void strip_cr(char *buf) +{ + char *theCR; + + theCR = strrchr(buf, '\n'); + if (theCR) + *theCR = '\0'; + theCR = strrchr(buf, '\r'); + if (theCR) + *theCR = '\0'; +} + +// For debugging +void print_to_log_file(const char *format, ...) { +#if CREATE_LOG + FILE *f; + va_list args; + char path[256], buf[256]; + time_t t; + strcpy(path, "/Users/Shared/test_log.txt"); + // strcpy(path, "/Users/"); + // strcat(path, getlogin()); + // strcat(path, "/Documents/test_log.txt"); + f = fopen(path, "a"); + if (!f) return; + + // freopen(buf, "a", stdout); + // freopen(buf, "a", stderr); + + time(&t); + strcpy(buf, asctime(localtime(&t))); + strip_cr(buf); + + fputs(buf, f); + fputs(" ", f); + + va_start(args, format); + vfprintf(f, format, args); + va_end(args); + + fputs("\n", f); + fflush(f); + fclose(f); + chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + +#endif +} diff --git a/mac_installer/make_GridRepublic.sh b/mac_installer/make_GridRepublic.sh index b6fa06233b..f6eda122db 100644 --- a/mac_installer/make_GridRepublic.sh +++ b/mac_installer/make_GridRepublic.sh @@ -19,7 +19,7 @@ ## # Script to convert Macintosh BOINC installer to GridRepublic Desktop installer -# updated 7/8/09 by Charlie Fenton +# updated 11/18/09 by Charlie Fenton ## ## Usage: @@ -148,6 +148,7 @@ if [ "$1" = "6" ] && [ "$2" = "2" ]; then cp -fpR "PostInstall.app" "${IR_PATH}/" else cp -fpR "${SOURCE_PKG_PATH}/Resources/PostInstall.app" "${IR_PATH}/" + cp -fpR "${SOURCE_PKG_PATH}/Resources/WaitPermissions.app" "${IR_PATH}/" fi cp -fp "${SOURCE_PKG_PATH}/Resources/all_projects_list.xml" "${IR_PATH}/" diff --git a/mac_installer/make_ProgThruProc.sh b/mac_installer/make_ProgThruProc.sh index d2090492ec..779c95ac6e 100644 --- a/mac_installer/make_ProgThruProc.sh +++ b/mac_installer/make_ProgThruProc.sh @@ -19,7 +19,7 @@ ## # Script to convert Macintosh BOINC installer to Progress Thru Processors Desktop installer -# updated 7/8/09 by Charlie Fenton +# updated 11/18/09 by Charlie Fenton ## ## Usage: @@ -148,6 +148,7 @@ if [ "$1" = "6" ] && [ "$2" = "2" ]; then cp -fpR "PostInstall.app" "${IR_PATH}/" else cp -fpR "${SOURCE_PKG_PATH}/Resources/PostInstall.app" "${IR_PATH}/" + cp -fpR "${SOURCE_PKG_PATH}/Resources/WaitPermissions.app" "${IR_PATH}/" fi cp -fp "${SOURCE_PKG_PATH}/Resources/all_projects_list.xml" "${IR_PATH}/" diff --git a/mac_installer/release_boinc.sh b/mac_installer/release_boinc.sh index 9ce8b63d12..b83938e5a7 100644 --- a/mac_installer/release_boinc.sh +++ b/mac_installer/release_boinc.sh @@ -19,7 +19,7 @@ ## # Release Script for Macintosh BOINC Manager 10/31/07 by Charlie Fenton -## updated 8/21/09 by Charlie Fenton for OS 10.6 Snow Leopard screen saver +## updated 11/18/09 by Charlie Fenton for OS 10.6 Snow Leopard ## ## NOTE: This script uses PackageMaker, which is installed as part of the ## XCode developer tools. So you must have installed XCode Developer @@ -90,6 +90,7 @@ cp -fp mac_installer/postinstall ../BOINC_Installer/Installer\ Scripts/ cp -fp mac_installer/postupgrade ../BOINC_Installer/Installer\ Scripts/ cp -fpR $BUILDPATH/PostInstall.app ../BOINC_Installer/Installer\ Resources/ +cp -fpR $BUILDPATH/WaitPermissions.app ../BOINC_Installer/Installer\ Resources/ mkdir -p ../BOINC_Installer/Pkg_Root mkdir -p ../BOINC_Installer/Pkg_Root/Applications @@ -202,20 +203,19 @@ DarwinMajorVersion=`echo $DarwinVersion | sed 's/\([0-9]*\)[.].*/\1/' `; # Darwin version 6.x corresponds to OS 10.2.x # Build the installer package inside the wrapper application's bundle -if [ "$DarwinMajorVersion" = "9" ]; then - # OS 10.5 packagemaker +if [ "$DarwinMajorVersion" = "8" ]; then + # OS 10.4 packagemaker + /Developer/Tools/packagemaker -build -p ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg -f ../BOINC_Installer/Pkg_Root -r ../BOINC_Installer/Installer\ Resources/ -i mac_build/Pkg-Info.plist -d mac_Installer/Description.plist -ds +else + # OS 10.5 / OS 10.6 packagemaker /Developer/usr/bin/packagemaker -r ../BOINC_Installer/Pkg_Root -e ../BOINC_Installer/Installer\ Resources/ -s ../BOINC_Installer/Installer\ Scripts/ -f mac_build/Pkg-Info.plist -t "BOINC Manager" -n "$1.$2.$3" -b -o ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg # Remove TokenDefinitions.plist and IFPkgPathMappings in Info.plist, which would cause installer to find a previous copy of BOINCManager and install there sudo rm -f ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg/Contents/Resources/TokenDefinitions.plist defaults delete "$BOINCPath/../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC Installer.app/Contents/Resources/BOINC.pkg/Contents/Info" IFPkgPathMappings -else - # OS 10.4 packagemaker - /Developer/Tools/packagemaker -build -p ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg -f ../BOINC_Installer/Pkg_Root -r ../BOINC_Installer/Installer\ Resources/ -i mac_build/Pkg-Info.plist -d mac_Installer/Description.plist -ds fi # Allow the installer wrapper application to modify the package's Info.plist file -sudo chmod u+w,g+w,o+w ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg/Contents/Info.plist -sudo chmod u+w,g+w,o+w ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg/Contents/Info.plist +sudo chmod a+rw ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_universal/BOINC\ Installer.app/Contents/Resources/BOINC.pkg/Contents/Info.plist # Build the stand-alone client distribution cp -fpR mac_build/Mac_SA_Insecure.sh ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_universal-apple-darwin/