static void GetPathToThisProcess(char* outbuf, size_t maxLen) { FILE *f; char buf[256], *p, *q; pid_t aPID = getpid(); *outbuf = '\0'; sprintf(buf, "ps -xwo command -p %d", (int)aPID); f = popen(buf, "r"); if (f == NULL) return; PersistentFGets (outbuf, maxLen, f); // Discard header line PersistentFGets (outbuf, maxLen, f); pclose(f); // Remove trailing newline if present p = strchr(outbuf, '\n'); if (p) *p = '\0'; // Strip off any arguments p = strstr(outbuf, " -"); q = p; if (p) { while (*p == ' ') { q = p; if (--p < outbuf) break; } } if (q) *q = '\0'; }
pid_t FindProcessPID(char* name, pid_t thePID) { FILE *f; char buf[1024]; size_t n = 0; pid_t aPID; if (name != NULL) // Search ny name n = strlen(name); f = popen("ps -a -x -c -o command,pid", "r"); if (f == NULL) return 0; while (PersistentFGets(buf, sizeof(buf), f)) { if (name != NULL) { // Search by name if (strncmp(buf, name, n) == 0) { aPID = atol(buf+16); pclose(f); return aPID; } } else { // Search by PID aPID = atol(buf+16); if (aPID == thePID) { pclose(f); return aPID; } } } pclose(f); return 0; }
int FindSkinName(char *name, size_t len) { FILE *f; char buf[MAXPATHLEN]; char *pattern = "/BOINC Data/skins/"; char *p, *q; name[0] = '\0'; f = popen("lsbom -d -s ./Contents/Archive.bom", "r"); if (f == NULL) return 0; while (PersistentFGets(buf, sizeof(buf), f)) { p = strstr(buf, pattern); if (p) { p += strlen(pattern); q = strchr(p, '/'); if (q) *q = 0; q = strchr(p, '\n'); if (q) *q = 0; if (strlen(p) > (len-1)) return 0; strlcpy(name, p, len); pclose(f); return 1; } } pclose(f); return 0; }
static Boolean IsUserLoggedIn(const char *userName){ char s[1024]; sprintf(s, "w -h \"%s\"", userName); FILE *f = popen(s, "r"); if (f) { if (PersistentFGets(s, sizeof(s), f) != NULL) { pclose (f); printf("User %s is currently logged in\n", userName); return true; // this user is logged in (perhaps via fast user switching) } pclose (f); } return false; }
bool CBOINCClientManager::ProcessExists(pid_t thePID) { FILE *f; char buf[256]; pid_t aPID; f = popen("ps -a -x -c -o pid,state", "r"); if (f == NULL) return false; while (PersistentFGets(buf, sizeof(buf), f)) { aPID = atol(buf); if (aPID == thePID) { if (strchr(buf, 'Z')) // A 'zombie', stopped but waiting break; // for us (its parent) to quit pclose(f); return true; } } pclose(f); return false; }
OSErr GetCurrentScreenSaverSelection(passwd *pw, char *moduleName, size_t maxLen) { char buf[1024]; FILE *f; char *p, *q; int i; *moduleName = '\0'; sprintf(buf, "su -l \"%s\" -c 'defaults -currentHost read com.apple.screensaver moduleDict'", pw->pw_name); f = popen(buf, "r"); if (f == NULL) { fprintf(stderr, "Could not get current screensaver selection for user %s\n", pw->pw_name); fflush(stderr); return fnfErr; } while (PersistentFGets(buf, sizeof(buf), f)) { p = strstr(buf, "moduleName = "); if (p) { p += 13; // Point past "moduleName = " q = moduleName; for (i=0; i<maxLen-1; ++i) { if (*p == '"') { ++p; continue; } if (*p == ';') break; *q++ = *p++; } *q = '\0'; pclose(f); return 0; } } pclose(f); return fnfErr; }
// Find all visible users. // If user is a member of group admin, add user to groups boinc_master and boinc_project. // Optionally add non-admin users to group boinc_master but not to group boinc_project. // Set login item for all members of group boinc_master to launch BOINC Manager. // If our install package included a skin, set those user's preferences to use that skin. // Optionally set BOINC as screensaver for all users running BOINC. OSErr UpdateAllVisibleUsers(long brandID) { DIR *dirp; dirent *dp; passwd *pw; uid_t saved_uid; Boolean deleteLoginItem; char skinName[256]; char s[256]; group grpAdmin, *grpAdminPtr; char adminBuf[32768]; group grpBOINC_master, *grpBOINC_masterPtr; char bmBuf[32768]; Boolean saverAlreadySetForAll = true; Boolean setSaverForAllUsers = false; Boolean allNonAdminUsersAreSet = true; Boolean allowNonAdminUsersToRunBOINC = false; Boolean found = false; FILE *f; OSStatus err; Boolean isGroupMember; #ifdef SANDBOX char *p; short i; err = getgrnam_r("admin", &grpAdmin, adminBuf, sizeof(adminBuf), &grpAdminPtr); if (err) { // Should never happen unless buffer too small puts("getgrnam(\"admin\") failed\n"); return -1; } 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; } #endif // SANDBOX FindSkinName(skinName, sizeof(skinName)); // Step through all users puts("Beginning first pass through all users\n"); dirp = opendir("/Users"); if (dirp == NULL) { // Should never happen puts("[1] opendir(\"/Users\") failed\n"); return -1; } while (true) { dp = readdir(dirp); if (dp == NULL) break; // End of list printf("[1] Checking user %s\n", dp->d_name); if (dp->d_name[0] == '.') continue; // Ignore names beginning with '.' // getpwnam works with either the full / login name (pw->pw_gecos) // or the short / Posix name (pw->pw_name) pw = getpwnam(dp->d_name); if (pw == NULL) { // "Deleted Users", "Shared", etc. printf("[1] %s not in getpwnam data base\n", dp->d_name); continue; } printf("[1] User %s: Posix name=%s, Full name=%s\n", dp->d_name, pw->pw_name, pw->pw_gecos); #ifdef SANDBOX isGroupMember = false; i = 0; while ((p = grpAdmin.gr_mem[i]) != NULL) { // Step through all users in group admin if (strcmp(p, pw->pw_name) == 0) { // User is a member of group admin, so add user to groups boinc_master and boinc_project printf("[1] User %s is a member of group admin\n", pw->pw_name); err = AddAdminUserToGroups(p); if (err != noErr) return err; isGroupMember = true; break; } ++i; } if (!isGroupMember) { i = 0; while ((p = grpBOINC_master.gr_mem[i]) != NULL) { // Step through all users in group boinc_master if (strcmp(p, pw->pw_name) == 0) { // User is a member of group boinc_master printf("[1] User %s is a member of group boinc_master\n", pw->pw_name); isGroupMember = true; break; } ++i; } } if (!isGroupMember) { allNonAdminUsersAreSet = false; } #else // SANDBOX isGroupMember = true; #endif // SANDBOX if (isGroupMember) { if ((strcmp(loginName, dp->d_name) == 0) || (strcmp(loginName, pw->pw_name) == 0)) { currentUserCanRunBOINC = true; } saved_uid = geteuid(); seteuid(pw->pw_uid); // Temporarily set effective uid to this user 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", pw->pw_name); f = popen(s, "r"); } if (f) { found = false; while (PersistentFGets(s, sizeof(s), f)) { if (strstr(s, saverName[brandID])) { found = true; break; } } pclose(f); if (!found) { saverAlreadySetForAll = false; } } seteuid(saved_uid); // Set effective uid back to privileged user } // End if (isGroupMember) } // End while (true) closedir(dirp); ResynchSystem(); if (! allNonAdminUsersAreSet) { if (ShowMessage(true, "Users who are permitted to administer this computer will automatically be allowed to " "run and control %s.\n\n" "Do you also want non-administrative users to be able to run and control %s on this Mac?", brandName[brandID], brandName[brandID]) ) { allowNonAdminUsersToRunBOINC = true; currentUserCanRunBOINC = true; saverAlreadySetForAll = false; printf("[2] User answered Yes to allowing non-admin users to run %s\n", brandName[brandID]); } else { printf("[2] User answered No to allowing non-admin users to run %s\n", brandName[brandID]); } } else { puts("[2] All non-admin users are already members of group boinc_master\n"); } if (! saverAlreadySetForAll) { setSaverForAllUsers = ShowMessage(true, "Do you want to set %s as the screensaver for all %s users on this Mac?", brandName[brandID], brandName[brandID]); } // Step through all users a second time, setting non-admin users and / or our screensaver puts("Beginning second pass through all users\n"); dirp = opendir("/Users"); if (dirp == NULL) { // Should never happen puts("[2] opendir(\"/Users\") failed\n"); return -1; } while (true) { dp = readdir(dirp); if (dp == NULL) break; // End of list printf("[2] Checking user %s\n", dp->d_name); if (dp->d_name[0] == '.') continue; // Ignore names beginning with '.' pw = getpwnam(dp->d_name); if (pw == NULL) { // "Deleted Users", "Shared", etc. printf("[2] %s not in getpwnam data base\n", dp->d_name); continue; } printf("[2] User %s: Posix name=%s, Full name=%s\n", dp->d_name, pw->pw_name, pw->pw_gecos); #ifdef SANDBOX isGroupMember = false; i = 0; while ((p = grpAdmin.gr_mem[i]) != NULL) { // Step through all users in group admin if (strcmp(p, pw->pw_name) == 0) { // User is a member of group admin printf("[2] User %s is a member of group admin\n", pw->pw_name); isGroupMember = true; break; } ++i; } // If allNonAdminUsersAreSet, some older versions added non-admin users only to group // boinc_master; ensure all permitted BOINC users are also members of group boinc_project if (isGroupMember || allowNonAdminUsersToRunBOINC || allNonAdminUsersAreSet) { // Add to group boinc_master but not group boinc_project err = AddAdminUserToGroups(pw->pw_name); printf("[2] Calling AddAdminUserToGroups(%s)\n", pw->pw_name); isGroupMember = true; } #else // SANDBOX isGroupMember = true; #endif // SANDBOX saved_uid = geteuid(); seteuid(pw->pw_uid); // Temporarily set effective uid to this user deleteLoginItem = CheckDeleteFile(dp->d_name); if (CheckDeleteFile(pw->pw_name)) { deleteLoginItem = true; } if (!isGroupMember) { deleteLoginItem = true; } SetLoginItem(brandID, deleteLoginItem); // Set login item for this user if (isGroupMember) { SetSkinInUserPrefs(dp->d_name, skinName); if (setSaverForAllUsers) { if (OSVersion < 0x1060) { sprintf(s, "defaults -currentHost write com.apple.screensaver moduleName %s", saverNameEscaped[brandID]); system (s); sprintf(s, "defaults -currentHost write com.apple.screensaver modulePath /Library/Screen\\ Savers/%s.saver", saverNameEscaped[brandID]); } else { sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName %s path /Library/Screen\\ Savers/%s.saver", pw->pw_name, saverNameEscaped[brandID], saverNameEscaped[brandID]); } system (s); } } seteuid(saved_uid); // Set effective uid back to privileged user } closedir(dirp); ResynchSystem(); return noErr; }
// 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 }
int main(int argc, char *argv[]) { Boolean AddUsers = false; Boolean SetSavers = false; Boolean isBMGroupMember, isBPGroupMember; Boolean saverIsSet = false; passwd *pw; uid_t saved_uid; long OSVersion; group grpBOINC_master, *grpBOINC_masterPtr; group grpBOINC_project, *grpBOINC_projectPtr; char bmBuf[32768]; char bpBuf[32768]; short index, i; char *p; char s[256]; FILE *f; OSStatus err; #ifndef _DEBUG if (getuid() != 0) { printf("This program must be run as root\n"); printUsage(); return 0; } #endif if (argc < 3) { printUsage(); return 0; } if (strcmp(argv[1], "-a") == 0) { AddUsers = true; } else if (strcmp(argv[1], "-s") == 0) { AddUsers = true; SetSavers = true; } else if (strcmp(argv[1], "-r") != 0) { printUsage(); return 0; } err = Gestalt(gestaltSystemVersion, &OSVersion); if (err != noErr) return err; 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; } err = getgrnam_r("boinc_project", &grpBOINC_project, bpBuf, sizeof(bpBuf), &grpBOINC_projectPtr); if (err) { // Should never happen unless buffer too small puts("getgrnam(\"boinc_project\") failed\n"); return -1; } for (index=2; index<argc; index++) { // getpwnam works with either the full / login name (pw->pw_gecos) // or the short / Posix name (pw->pw_name) pw = getpwnam(argv[index]); if (pw == NULL) { printf("User %s not found.\n", argv[index]); continue; } isBMGroupMember = false; i = 0; while ((p = grpBOINC_master.gr_mem[i]) != NULL) { // Step through all users in group boinc_master if (strcmp(p, pw->pw_name) == 0) { // Only the short / Posix names are in the list // User is a member of group boinc_master isBMGroupMember = true; break; } ++i; } isBPGroupMember = false; i = 0; while ((p = grpBOINC_project.gr_mem[i]) != NULL) { // Step through all users in group boinc_project if (strcmp(p, pw->pw_name) == 0) { // Only the short / Posix names are in the list // User is a member of group boinc_master isBPGroupMember = true; break; } ++i; } if ((!isBMGroupMember) && AddUsers) { sprintf(s, "dscl . -merge /groups/boinc_master users %s", pw->pw_name); system(s); } if ((!isBPGroupMember) && AddUsers) { sprintf(s, "dscl . -merge /groups/boinc_project users %s", pw->pw_name); system(s); } if (isBMGroupMember && (!AddUsers)) { sprintf(s, "dscl . -delete /Groups/boinc_master GroupMembership %s", pw->pw_name); system(s); } if (isBPGroupMember && (!AddUsers)) { sprintf(s, "dscl . -delete /Groups/boinc_project GroupMembership %s", pw->pw_name); system(s); } saved_uid = geteuid(); seteuid(pw->pw_uid); // Temporarily set effective uid to this user SetLoginItem(AddUsers); // Set or remove login item for this user if (OSVersion < 0x1060) { sprintf(s, "sudo -u %s defaults -currentHost read com.apple.screensaver moduleName", pw->pw_name); } else { sprintf(s, "sudo -u %s defaults -currentHost read com.apple.screensaver moduleDict -dict", pw->pw_name); } f = popen(s, "r"); if (f) { saverIsSet = false; while (PersistentFGets(s, sizeof(s), f)) { if (strstr(s, "BOINCSaver")) { saverIsSet = true; break; } } pclose(f); } if ((!saverIsSet) && SetSavers) { if (OSVersion < 0x1060) { sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleName BOINCSaver", pw->pw_name); system(s); sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver modulePath \"/Library/Screen Savers/BOINCSaver.saver\"", pw->pw_name); system(s); } else { sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName BOINCSaver path \"/Library/Screen Savers/BOINCSaver.saver\"", pw->pw_name); system(s); } } if (saverIsSet && (!AddUsers)) { if (OSVersion < 0x1060) { sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleName Flurry", pw->pw_name); system(s); sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver modulePath \"/System/Library/Screen Savers/Flurry.saver\"", pw->pw_name); system(s); } else { sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName Flurry path \"/System/Library/Screen Savers/Flurry.saver\"", pw->pw_name); system(s); } } seteuid(saved_uid); // Set effective uid back to privileged user } return 0; }
int main(int argc, char *argv[]) { long brandID = 0; Boolean AddUsers = false; Boolean SetSavers = false; Boolean isBMGroupMember, isBPGroupMember; Boolean saverIsSet = false; passwd *pw; uid_t saved_uid; group grpBOINC_master, *grpBOINC_masterPtr; group grpBOINC_project, *grpBOINC_projectPtr; char bmBuf[32768]; char bpBuf[32768]; char loginName[256]; short index, i; FILE *f; int flag; char *p; char s[1024], buf[1024]; OSStatus err; brandID = GetBrandID(); #ifndef _DEBUG if (getuid() != 0) { printf("This program must be run as root\n"); printUsage(brandID); return 0; } #endif saved_uid = geteuid(); if (argc < 3) { printUsage(brandID); return 0; } if (strcmp(argv[1], "-a") == 0) { AddUsers = true; } else if (strcmp(argv[1], "-s") == 0) { AddUsers = true; SetSavers = true; } else if (strcmp(argv[1], "-r") != 0) { printUsage(brandID); return 0; } printf("\n"); if (!check_branding_arrays(s, sizeof(s))) { printf("Branding array has too few entries: %s\n", s); return -1; } loginName[0] = '\0'; strncpy(loginName, getenv("USER"), sizeof(loginName)-1); 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; } err = getgrnam_r("boinc_project", &grpBOINC_project, bpBuf, sizeof(bpBuf), &grpBOINC_projectPtr); if (err) { // Should never happen unless buffer too small puts("getgrnam(\"boinc_project\") failed\n"); return -1; } for (index=2; index<argc; index++) { // getpwnam works with either the full / login name (pw->pw_gecos) // or the short / Posix name (pw->pw_name) pw = getpwnam(argv[index]); if ((pw == NULL) || (pw->pw_uid < 501)) { printf("User %s not found.\n\n", argv[index]); continue; } flag = 0; sprintf(s, "dscl . -read \"/Users/%s\" NFSHomeDirectory", pw->pw_name); f = popen(s, "r"); if (!f) { flag = 1; } else { while (PersistentFGets(buf, sizeof(buf), f)) { p = strrchr(buf, ' '); if (p) { if (strstr(p, "/var/empty") != NULL) { flag = 1; break; } } } pclose(f); } if (flag) { sprintf(s, "dscl . -read \"/Users/%s\" UserShell", pw->pw_name); f = popen(s, "r"); if (!f) { flag |= 2; } else { while (PersistentFGets(buf, sizeof(buf), f)) { p = strrchr(buf, ' '); if (p) { if (strstr(p, "/usr/bin/false") != NULL) { flag |= 2; break; } } } pclose(f); } } if (flag == 3) { // if (Home Directory == "/var/empty") && (UserShell == "/usr/bin/false") printf("%s is not a valid user name.\n\n", argv[index]); continue; } printf("%s user %s (/Users/%s)\n", AddUsers? "Adding" : "Removing", pw->pw_gecos, pw->pw_name); isBMGroupMember = false; i = 0; while ((p = grpBOINC_master.gr_mem[i]) != NULL) { // Step through all users in group boinc_master if (strcmp(p, pw->pw_name) == 0) { // Only the short / Posix names are in the list // User is a member of group boinc_master isBMGroupMember = true; break; } ++i; } isBPGroupMember = false; i = 0; while ((p = grpBOINC_project.gr_mem[i]) != NULL) { // Step through all users in group boinc_project if (strcmp(p, pw->pw_name) == 0) { // Only the short / Posix names are in the list // User is a member of group boinc_master isBPGroupMember = true; break; } ++i; } if ((!isBMGroupMember) && AddUsers) { sprintf(s, "dscl . -merge /groups/boinc_master GroupMembership %s", pw->pw_name); callPosixSpawn(s); } if ((!isBPGroupMember) && AddUsers) { sprintf(s, "dscl . -merge /groups/boinc_project GroupMembership %s", pw->pw_name); callPosixSpawn(s); } if (isBMGroupMember && (!AddUsers)) { sprintf(s, "dscl . -delete /Groups/boinc_master GroupMembership %s", pw->pw_name); callPosixSpawn(s); } if (isBPGroupMember && (!AddUsers)) { sprintf(s, "dscl . -delete /Groups/boinc_project GroupMembership %s", pw->pw_name); callPosixSpawn(s); } if (!AddUsers) { // Delete per-user BOINC Manager and screensaver files sprintf(s, "rm -fR \"/Users/%s/Library/Application Support/BOINC\"", pw->pw_name); callPosixSpawn (s); } // Set or remove login item for this user bool useOSASript = false; if ((compareOSVersionTo(10, 13) < 0) || (strcmp(loginName, pw->pw_name) == 0) || (strcmp(loginName, pw->pw_gecos) == 0)) { useOSASript = true; } #if USE_OSASCRIPT_FOR_ALL_LOGGED_IN_USERS if (! useOSASript) { useOSASript = IsUserLoggedIn(pw->pw_name); } #endif if (useOSASript) { snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist", pw->pw_name); boinc_delete_file(s); SetLoginItemOSAScript(brandID, !AddUsers, pw->pw_name); } else { SetLoginItemLaunchAgent(brandID, !AddUsers, pw); } saverIsSet = false; err = GetCurrentScreenSaverSelection(pw, s, sizeof(s) -1); #if VERBOSE fprintf(stderr, "Current Screensaver Selection for user %s is: \"%s\"\n", pw->pw_name, s); #endif if (err == noErr) { if (!strcmp(s, saverName[brandID])) { saverIsSet = true; } } if (SetSavers) { if (saverIsSet) { printf("Screensaver already set to %s for user %s (/Users/%s)\n", saverName[brandID], pw->pw_gecos, pw->pw_name); } else { printf("Setting screensaver to %s for user %s (/Users/%s)\n", saverName[brandID], pw->pw_gecos, pw->pw_name); } } if ((!saverIsSet) && SetSavers) { seteuid(pw->pw_uid); // Temporarily set effective uid to this user sprintf(s, "/Library/Screen Savers/%s.saver", saverName[brandID]); err = SetScreenSaverSelection(pw, saverName[brandID], s, 0); #if VERBOSE fprintf(stderr, "SetScreenSaverSelection for user %s (uid %d) to \"%s\" returned error %d\n", pw->pw_name, geteuid(), saverName[brandID], err); #endif seteuid(saved_uid); // Set effective uid back to privileged user // This seems to work also: // sprintf(buf, "su -l \"%s\" -c 'defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName \"%s\" path \"%s\ type 0'", pw->pw_name, saverName[brandID], s); // callPosixSpawn(s); } if (saverIsSet && (!AddUsers)) { printf("Setting screensaver to Flurry for user %s (/Users/%s)\n", pw->pw_gecos, pw->pw_name); seteuid(pw->pw_uid); // Temporarily set effective uid to this user err = SetScreenSaverSelection(pw, "Flurry", "/System/Library/Screen Savers/Flurry.saver", 0); #if VERBOSE fprintf(stderr, "SetScreenSaverSelection for user %s (%d) to Flurry returned error %d\n", pw->pw_name, geteuid(), err); #endif seteuid(saved_uid); // Set effective uid back to privileged user } seteuid(saved_uid); // Set effective uid back to privileged user printf("\n"); } printf("WARNING: Changes may require a system restart to take effect.\n"); return 0; }