diff --git a/app/_server/actions/cronjobs/index.ts b/app/_server/actions/cronjobs/index.ts index 277eea3..5c0a70c 100644 --- a/app/_server/actions/cronjobs/index.ts +++ b/app/_server/actions/cronjobs/index.ts @@ -10,7 +10,7 @@ import { cleanupCrontab, type CronJob, } from "@/app/_utils/system"; -import { getAllTargetUsers } from "@/app/_utils/system/hostCrontab"; +import { getAllTargetUsers, getUserInfo } from "@/app/_utils/system/hostCrontab"; import { revalidatePath } from "next/cache"; import { getScriptPath } from "@/app/_utils/scripts"; import { exec } from "child_process"; @@ -224,7 +224,13 @@ export const runCronJob = async ( let command = job.command; if (isDocker) { - command = `nsenter -t 1 -m -u -i -n -p sh -c "${job.command}"`; + const userInfo = await getUserInfo(job.user); + + if (userInfo && userInfo.username !== "root") { + command = `nsenter -t 1 -m -u -i -n -p --setuid=${userInfo.uid} --setgid=${userInfo.gid} sh -c "${job.command}"`; + } else { + command = `nsenter -t 1 -m -u -i -n -p sh -c "${job.command}"`; + } } const { stdout, stderr } = await execAsync(command, { diff --git a/app/_utils/system/hostCrontab.ts b/app/_utils/system/hostCrontab.ts index dd8ad7c..42e5646 100644 --- a/app/_utils/system/hostCrontab.ts +++ b/app/_utils/system/hostCrontab.ts @@ -3,6 +3,12 @@ import { promisify } from "util"; const execAsync = promisify(exec); +export interface UserInfo { + username: string; + uid: number; + gid: number; +} + const execHostCrontab = async (command: string): Promise => { try { const { stdout } = await execAsync( @@ -166,3 +172,42 @@ export const writeHostCrontabForUser = async ( return false; } } + +export async function getUserInfo(username: string): Promise { + try { + const isDocker = process.env.DOCKER === "true"; + + if (isDocker) { + // Get user info from host system + const uidResult = await execHostCrontab(`id -u ${username}`); + const gidResult = await execHostCrontab(`id -g ${username}`); + + const uid = parseInt(uidResult.trim()); + const gid = parseInt(gidResult.trim()); + + if (isNaN(uid) || isNaN(gid)) { + console.error(`Invalid UID/GID for user ${username}`); + return null; + } + + return { username, uid, gid }; + } else { + // Get user info from local system + const { stdout } = await execAsync(`id -u ${username}`); + const uid = parseInt(stdout.trim()); + + const { stdout: gidStdout } = await execAsync(`id -g ${username}`); + const gid = parseInt(gidStdout.trim()); + + if (isNaN(uid) || isNaN(gid)) { + console.error(`Invalid UID/GID for user ${username}`); + return null; + } + + return { username, uid, gid }; + } + } catch (error) { + console.error(`Error getting user info for ${username}:`, error); + return null; + } +} diff --git a/docker-compose.yml b/docker-compose.yml index da6d345..f355dc6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: cronjob-manager: - image: ghcr.io/fccview/cronmaster:2.3.0 + image: ghcr.io/fccview/cronmaster:1.3.0 container_name: cronmaster user: "root" ports: