Fix potential permission issues on manual runs

This commit is contained in:
fccview
2025-08-27 07:57:31 +01:00
parent 9445cdeebf
commit 376147fda0
3 changed files with 54 additions and 3 deletions

View File

@@ -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, {

View File

@@ -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<string> => {
try {
const { stdout } = await execAsync(
@@ -166,3 +172,42 @@ export const writeHostCrontabForUser = async (
return false;
}
}
export async function getUserInfo(username: string): Promise<UserInfo | null> {
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;
}
}

View File

@@ -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: