Commit 781c9140 authored by Charlie Fenton's avatar Charlie Fenton

Mac Installer: Check for our users and groups having IDs which conflict with...

Mac Installer: Check for our users and  groups having IDs which conflict with other users and groups on the system

svn path=/trunk/boinc/; revision=19719
parent c2eb2383
...@@ -9442,7 +9442,7 @@ Charlie 23 Nov 2009 ...@@ -9442,7 +9442,7 @@ Charlie 23 Nov 2009
take longer than expected. take longer than expected.
clientgui/ clientgui/
BOINCSimpleGUI.cpp, .h sg_BoincSimpleGUI.cpp, .h
Mac/ Mac/
MacAccessibility.cpp MacAccessibility.cpp
MacAccessibility.h (added) MacAccessibility.h (added)
...@@ -9527,3 +9527,22 @@ Rom 25 Nov 2009 ...@@ -9527,3 +9527,22 @@ Rom 25 Nov 2009
client/ client/
http_curl.cpp, .h http_curl.cpp, .h
Charlie 26 Nov 2009
- MGR: Don't localize keyboard shortcut for Close Window.
- MGR: Tweaks to Mac accessibility.
- Mac Installer: Check for our boinc_master and boinc_project users and
groups having IDs which conflict with other users and groups on the
system. This can happen when a newer version of the OS includes new
users or groups, or when software is installed which defines them.
This was causing some of the problems reported by users. If the
installer finds a conflict, it deletes our user or group and creates
a new one with a unique ID.
clientgui/
AdvancedFrame.cpp
sg_BoincSimpleGUI.cpp
Mac/
MacAccessibility.cpp
mac_installer/
PostInstall.cpp
...@@ -38,9 +38,16 @@ ...@@ -38,9 +38,16 @@
#include "SetupSecurity.h" #include "SetupSecurity.h"
#define boinc_master_user_name "boinc_master"
#define boinc_master_group_name "boinc_master"
#define boinc_project_user_name "boinc_project"
#define boinc_project_group_name "boinc_project"
void Initialize(void); /* function prototypes */ void Initialize(void); /* function prototypes */
int DeleteReceipt(void); int DeleteReceipt(void);
OSStatus CheckLogoutRequirement(int *finalAction); OSStatus CheckLogoutRequirement(int *finalAction);
void CheckUserAndGroupConflicts();
Boolean SetLoginItem(long brandID, Boolean deleteLogInItem); Boolean SetLoginItem(long brandID, Boolean deleteLogInItem);
void SetSkinInUserPrefs(char *userName, char *skinName); void SetSkinInUserPrefs(char *userName, char *skinName);
Boolean CheckDeleteFile(char *name); Boolean CheckDeleteFile(char *name);
...@@ -104,9 +111,9 @@ int main(int argc, char *argv[]) ...@@ -104,9 +111,9 @@ int main(int argc, char *argv[])
uid_t saved_euid, saved_uid, b_m_uid; uid_t saved_euid, saved_uid, b_m_uid;
passwd *pw; passwd *pw;
int finalInstallAction; int finalInstallAction;
#else #else // SANDBOX
group *grp; group *grp;
#endif #endif // SANDBOX
appName[0] = "/Applications/BOINCManager.app"; appName[0] = "/Applications/BOINCManager.app";
appNameEscaped[0] = "/Applications/BOINCManager.app"; appNameEscaped[0] = "/Applications/BOINCManager.app";
...@@ -203,6 +210,8 @@ int main(int argc, char *argv[]) ...@@ -203,6 +210,8 @@ int main(int argc, char *argv[])
#ifdef SANDBOX #ifdef SANDBOX
CheckUserAndGroupConflicts();
for (i=0; i<5; ++i) { for (i=0; i<5; ++i) {
err = CreateBOINCUsersAndGroups(); err = CreateBOINCUsersAndGroups();
if (err != noErr) { if (err != noErr) {
...@@ -465,7 +474,7 @@ OSStatus CheckLogoutRequirement(int *finalAction) ...@@ -465,7 +474,7 @@ OSStatus CheckLogoutRequirement(int *finalAction)
group *grp = NULL; group *grp = NULL;
int i; int i;
Boolean isMember = false; Boolean isMember = false;
#endif #endif // SANDBOX
*finalAction = restartRequired; *finalAction = restartRequired;
...@@ -487,7 +496,7 @@ OSStatus CheckLogoutRequirement(int *finalAction) ...@@ -487,7 +496,7 @@ OSStatus CheckLogoutRequirement(int *finalAction)
*finalAction = nothingrequired; *finalAction = nothingrequired;
return noErr; return noErr;
} }
#endif #endif // SANDBOX
getcwd(path, sizeof(path)); getcwd(path, sizeof(path));
strlcat(path, "/Contents/Info.plist", sizeof(path)); strlcat(path, "/Contents/Info.plist", sizeof(path));
...@@ -536,6 +545,119 @@ OSStatus CheckLogoutRequirement(int *finalAction) ...@@ -536,6 +545,119 @@ OSStatus CheckLogoutRequirement(int *finalAction)
} }
// Some newer versions of the OS define users and groups which may conflict with
// our previously created boinc_master or boinc_project user or group. This could
// also happen when the user installs new software. So we must check for such
// duplicate UserIDs and groupIDs; if found, we delete our user or group so that
// the PostInstall application will cerate a new one that does not conflict.
// NOTE: getgrnam and getgrgid use one static memory area to return their results,
// so each call to getgrnam or getgrgid overwrites the data from any previous calls.
void CheckUserAndGroupConflicts()
{
#ifdef SANDBOX
passwd *pw = NULL;
group *grp = NULL;
gid_t boinc_master_gid = 0, boinc_project_gid = 0;
uid_t boinc_master_uid = 0, boinc_project_uid = 0;
FILE *f;
char cmd[256], buf[256];
int entryCount;
entryCount = 0;
grp = getgrnam(boinc_master_group_name);
if (grp) {
boinc_master_gid = grp->gr_gid;
sprintf(cmd, "dscl . -search /Groups PrimaryGroupID %d", boinc_master_gid);
f = popen(cmd, "r");
if (f) {
while (PersistentFGets(buf, sizeof(buf), f)) {
if (strstr(buf, "PrimaryGroupID")) {
++entryCount;
}
}
pclose(f);
}
}
if (entryCount > 1) {
system ("dscl . -delete /groups/boinc_master");
// User boinc_master must have group boinc_master as its primary group.
// Since this group no longer exists, delete the user as well.
system ("dscl . -delete /users/boinc_master");
ResynchSystem();
}
entryCount = 0;
grp = getgrnam(boinc_project_group_name);
if (grp) {
boinc_project_gid = grp->gr_gid;
sprintf(cmd, "dscl . -search /Groups PrimaryGroupID %d", boinc_project_gid);
f = popen(cmd, "r");
if (f) {
while (PersistentFGets(buf, sizeof(buf), f)) {
if (strstr(buf, "PrimaryGroupID")) {
++entryCount;
}
}
pclose(f);
}
}
if (entryCount > 1) {
system ("dscl . -delete /groups/boinc_project");
// User boinc_project must have group boinc_project as its primary group.
// Since this group no longer exists, delete the user as well.
system ("dscl . -delete /users/boinc_project");
ResynchSystem();
}
entryCount = 0;
pw = getpwnam(boinc_master_user_name);
if (pw) {
boinc_master_uid = pw->pw_uid;
sprintf(cmd, "dscl . -search /Users UniqueID %d", boinc_master_uid);
f = popen(cmd, "r");
if (f) {
while (PersistentFGets(buf, sizeof(buf), f)) {
if (strstr(buf, "UniqueID")) {
++entryCount;
}
}
pclose(f);
}
}
if (entryCount > 1) {
system ("dscl . -delete /users/boinc_master");
ResynchSystem();
}
entryCount = 0;
pw = getpwnam(boinc_project_user_name);
if (pw) {
boinc_project_uid = pw->pw_uid;
sprintf(cmd, "dscl . -search /Users UniqueID %d", boinc_project_uid);
f = popen(cmd, "r");
if (f) {
while (PersistentFGets(buf, sizeof(buf), f)) {
if (strstr(buf, "UniqueID")) {
++entryCount;
}
}
pclose(f);
}
}
if (entryCount > 1) {
system ("dscl . -delete /users/boinc_project");
ResynchSystem();
}
#endif // SANDBOX
}
Boolean SetLoginItem(long brandID, Boolean deleteLogInItem) Boolean SetLoginItem(long brandID, Boolean deleteLogInItem)
{ {
Boolean Success; Boolean Success;
...@@ -778,7 +900,7 @@ OSErr UpdateAllVisibleUsers(long brandID) ...@@ -778,7 +900,7 @@ OSErr UpdateAllVisibleUsers(long brandID)
puts("getgrnam(\"boinc_master\") failed\n"); puts("getgrnam(\"boinc_master\") failed\n");
return -1; return -1;
} }
#endif #endif // SANDBOX
FindSkinName(skinName, sizeof(skinName)); FindSkinName(skinName, sizeof(skinName));
...@@ -830,9 +952,9 @@ OSErr UpdateAllVisibleUsers(long brandID) ...@@ -830,9 +952,9 @@ OSErr UpdateAllVisibleUsers(long brandID)
if (!isGroupMember) { if (!isGroupMember) {
allNonAdminUsersAreSet = false; allNonAdminUsersAreSet = false;
} }
#else #else // SANDBOX
isGroupMember = true; isGroupMember = true;
#endif #endif // SANDBOX
if (isGroupMember) { if (isGroupMember) {
saved_uid = geteuid(); saved_uid = geteuid();
...@@ -931,9 +1053,9 @@ OSErr UpdateAllVisibleUsers(long brandID) ...@@ -931,9 +1053,9 @@ OSErr UpdateAllVisibleUsers(long brandID)
isGroupMember = true; isGroupMember = true;
} }
} }
#else #else // SANDBOX
isGroupMember = true; isGroupMember = true;
#endif #endif // SANDBOX
saved_uid = geteuid(); saved_uid = geteuid();
seteuid(pw->pw_uid); // Temporarily set effective uid to this user seteuid(pw->pw_uid); // Temporarily set effective uid to this user
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment