I have a program with hardcoded config files in /etc, which I do not have write permission to, because I have no root (except I can use pacman in sudo). I need a way for the program to see a file there, where there is not, with data in it. How would I do this?
1 Answer
If you don't have access to the source of the program or can't recompile it after modifying it but it's dynamically linked (and not setuid/setgid...), you can use a LD_PRELOAD trick to hijack the calls to open() or fopen() (or whatever library function the program uses to access the file; use ltrace or equivalent or a debugger to figure out which one(s)) so they open a different file.
Example:
$ cat redirect-open.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
static handle_redirect(char **pathname)
{
  char *target = getenv("TARGET_FILE");
  if (!target) abort();
  if (strcmp(*pathname, target) == 0) {
    *pathname = getenv("REDIRECTED_FILE");
    if (!*pathname) abort();
  }
}
int open(const char *pathname, int flags, mode_t mode)
{
  static int (*orig)(const char *, int, mode_t) = 0;
  if (!orig)
    orig = dlsym(RTLD_NEXT,"open");
  if (!orig) abort();
  handle_redirect(&pathname);
  return orig(pathname, flags, mode);
}
FILE *fopen(const char *pathname, const char *mode)
{
  static FILE *(*orig)(const char *, const char *) = 0;
  if (!orig)
    orig = dlsym(RTLD_NEXT,"fopen");
  if (!orig) abort();
  handle_redirect(&pathname);
  return orig(pathname, mode);
}
That hijacks open() and fopen() so that if they're asked to open $TARGET_FILE, they actually open $REDIRECTED_FILE instead.
$ make redirect-open CFLAGS=-fPIC LDFLAGS=-shared
$ echo hello > fakeshadow
$ cat /etc/shadow
cat: /etc/shadow: Permission denied
$ LD_PRELOAD=$PWD/redirect-open TARGET_FILE=/etc/shadow REDIRECTED_FILE=$PWD/fakeshadow cat /etc/shadow
hello

SETGIDthat group, have your/etc/config_fileowned byroot:the_new_group, with mode (permissions)0640(owner:rw, group:r, world:no access).