mirror of
https://github.com/darlinghq/darling.git
synced 2024-11-27 06:10:36 +00:00
Make user's home specific to the prefix, provide a link to real home via LinuxHome
This commit is contained in:
parent
c3ebd26366
commit
4da40f9cf5
@ -97,8 +97,6 @@ install(DIRECTORY DESTINATION libexec/darling/usr/local/share)
|
||||
|
||||
InstallSymlink(/Volumes/SystemRoot/dev ${CMAKE_INSTALL_PREFIX}/libexec/darling/dev)
|
||||
InstallSymlink(private/tmp ${CMAKE_INSTALL_PREFIX}/libexec/darling/tmp)
|
||||
InstallSymlink(/Volumes/SystemRoot/home ${CMAKE_INSTALL_PREFIX}/libexec/darling/Users)
|
||||
InstallSymlink(Users ${CMAKE_INSTALL_PREFIX}/libexec/darling/home)
|
||||
|
||||
InstallSymlink(/proc/self/mounts ${CMAKE_INSTALL_PREFIX}/libexec/darling/etc/mtab)
|
||||
InstallSymlink(/Volumes/SystemRoot/etc/passwd ${CMAKE_INSTALL_PREFIX}/libexec/darling/etc/passwd)
|
||||
|
@ -84,16 +84,36 @@ __attribute__((constructor))
|
||||
|
||||
static unsigned long processEnvVariable(const char* var)
|
||||
{
|
||||
if (strncmp(var, "HOME=/Users/", 12) == 0)
|
||||
if (strncmp(var, "HOME=", 5) == 0)
|
||||
{
|
||||
const size_t len = strlen(var);
|
||||
char* home = malloc(len); // 1 byte shorter
|
||||
char* home = (char*) malloc(512);
|
||||
char* symlink_path = (char*) malloc(strlen(var+5) + 10);
|
||||
|
||||
strcpy(home, "HOME=/home/");
|
||||
strcpy(home + 11, var+12);
|
||||
strcpy(symlink_path, var+5);
|
||||
strcat(symlink_path, "/LinuxHome");
|
||||
|
||||
int len = readlink(symlink_path, home, 512-1);
|
||||
free(symlink_path);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
free(home);
|
||||
goto out;
|
||||
}
|
||||
home[len] = '\0';
|
||||
|
||||
if (strncmp(home, SYSTEM_ROOT, sizeof(SYSTEM_ROOT) - 1) != 0)
|
||||
{
|
||||
free(home);
|
||||
goto out;
|
||||
}
|
||||
|
||||
strcpy(home, "HOME=");
|
||||
memmove(home+5, home + sizeof(SYSTEM_ROOT) - 1, len - sizeof(SYSTEM_ROOT) + 2);
|
||||
|
||||
return (unsigned long) home;
|
||||
}
|
||||
out:
|
||||
return (unsigned long) var;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
This file is part of Darling.
|
||||
|
||||
Copyright (C) 2016-2018 Lubos Dolezel
|
||||
Copyright (C) 2016-2020 Lubos Dolezel
|
||||
|
||||
Darling is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -561,16 +561,16 @@ void spawnShell(const char** argv)
|
||||
"/sbin:"
|
||||
"/usr/local/bin");
|
||||
|
||||
const char *home = getenv("HOME");
|
||||
if (home)
|
||||
const char* login = getlogin();
|
||||
if (!login)
|
||||
{
|
||||
if (sscanf(home, "/home/%4096s", buffer1) == 1)
|
||||
snprintf(buffer2, sizeof(buffer2), "HOME=/Users/%s", buffer1);
|
||||
else
|
||||
snprintf(buffer2, sizeof(buffer2), "HOME=" SYSTEM_ROOT "%s", home);
|
||||
pushShellspawnCommand(sockfd, SHELLSPAWN_SETENV, buffer2);
|
||||
fprintf(stderr, "Cannot determine your user name\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(buffer2, sizeof(buffer2), "HOME=/Users/%s", login);
|
||||
pushShellspawnCommand(sockfd, SHELLSPAWN_SETENV, buffer2);
|
||||
|
||||
// Push shell arguments
|
||||
if (buffer != NULL)
|
||||
{
|
||||
@ -747,6 +747,8 @@ pid_t spawnInitProcess(void)
|
||||
|
||||
free(opts);
|
||||
|
||||
setupUserHome();
|
||||
|
||||
// This is executed once at prefix creation
|
||||
if (g_fixPermissions)
|
||||
fixDirectoryPermissions(prefix);
|
||||
@ -1238,3 +1240,96 @@ void setupCoredumpPattern(void)
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
const char* xdgDirectory(const char* name)
|
||||
{
|
||||
static char dir[4096];
|
||||
char* cmd = (char*) malloc(16 + strlen(name));
|
||||
|
||||
sprintf(cmd, "xdg-user-dir %s", name);
|
||||
|
||||
FILE* proc = popen(cmd, "r");
|
||||
|
||||
free(cmd);
|
||||
|
||||
if (!proc)
|
||||
return NULL;
|
||||
|
||||
fgets(dir, sizeof(dir)-1, proc);
|
||||
|
||||
pclose(proc);
|
||||
|
||||
size_t len = strlen(dir);
|
||||
if (len <= 1)
|
||||
return NULL;
|
||||
|
||||
if (dir[len-1] == '\n')
|
||||
dir[len-1] = '\0';
|
||||
return dir;
|
||||
}
|
||||
|
||||
void setupUserHome(void)
|
||||
{
|
||||
char buf[4096], buf2[4096];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/Users", prefix);
|
||||
|
||||
// Remove the old /Users symlink that may exist
|
||||
unlink(buf);
|
||||
|
||||
// mkdir /Users
|
||||
mkdir(buf, 0777);
|
||||
|
||||
// mkdir /Users/Shared
|
||||
strcat(buf, "/Shared");
|
||||
mkdir(buf, 0777);
|
||||
|
||||
const char* home = getenv("HOME");
|
||||
const char* login = getlogin();
|
||||
if (!login)
|
||||
{
|
||||
fprintf(stderr, "Cannot determine your user name\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!home)
|
||||
{
|
||||
fprintf(stderr, "Cannot determine your home directory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/Users/%s", prefix, login);
|
||||
|
||||
// mkdir /Users/$LOGIN
|
||||
mkdir(buf, 0755);
|
||||
|
||||
snprintf(buf2, sizeof(buf2), "/Volumes/SystemRoot%s", home);
|
||||
|
||||
strcat(buf, "/LinuxHome");
|
||||
unlink(buf);
|
||||
|
||||
// symlink /Users/$LOGIN/LinuxHome -> $HOME
|
||||
symlink(buf2, buf);
|
||||
|
||||
static const char* xdgmap[][2] = {
|
||||
{ "DESKTOP", "Desktop" },
|
||||
{ "DOWNLOAD", "Downloads" },
|
||||
{ "PUBLICSHARE", "Public" },
|
||||
{ "DOCUMENTS", "Documents" },
|
||||
{ "MUSIC", "Music" },
|
||||
{ "PICTURES", "Pictures" },
|
||||
{ "VIDEOS", "Movies" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(xdgmap) / sizeof(xdgmap[0]); i++)
|
||||
{
|
||||
const char* dir = xdgDirectory(xdgmap[i][0]);
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
snprintf(buf2, sizeof(buf2), "/Volumes/SystemRoot%s", dir);
|
||||
snprintf(buf, sizeof(buf), "%s/Users/%s/%s", prefix, login, xdgmap[i][1]);
|
||||
|
||||
unlink(buf);
|
||||
symlink(buf2, buf);
|
||||
}
|
||||
}
|
||||
|
@ -67,5 +67,6 @@ void loadKernelModule(void);
|
||||
void joinNamespace(pid_t pid, int type, const char* typeName);
|
||||
|
||||
void setupCoredumpPattern(void);
|
||||
void setupUserHome(void);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user