Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sure file is created with the correct user or permissions?

The business model is a bit complex, so please forgive me if the explanation isn't 100% clear:

The Uploader interface (String upload(String path, byte[] fileContents)) defines different ways to upload a file (contained in the byte array), for example AmazonUploader which takes the content and the path string, and uploads it to Amazon S3 under the given key.

I have a class called LocalUploader which is used in QA, writes the given file array, as is, to the local disk.

The Uploader is used in two different cases:

  1. The web interface, ran by user web
  2. A command-line interface, ran by users logging into ssh, via user root.

The command-line interface is a different jar from the web interface, but they both have the Uploader bundled in. Also, the command-line executable is a bash script running java -jar .... at the end.

The idea is to save the files to a known location, and then serve them over a simple static http server.

The problem in short: Since both processes write to the same location, when a file is written by the command-line interface, it's no longer writable by the web interface (web can't access files made by root, obviously, no problems the other way around).

Now, I'm stuck with Java 6 for the Uploader, so no nio file package.

Workflow in a nutshell:

Workflow

Here's what I've tried:

  • Use java.io.File's .setWritable(). If I do it before writing the file, it fails (returns false), if I do it after, it returns true but doesn't set the writable flag.
  • Use su to run the jar as another user. But that messes with the parameter insertion
  • Use umask, was promptly ignored by Java. Probably because it's a different process.
  • Use the group id flag for linux permissions - was promptly ignored by Java. Probably because it's a different process.

What I didn't try:

  • Use an ACL - We can't afford to mess with the underlying partitions.
  • Return the file as output and have bash write the file - Not all commands need to write files, also, there may or may not be a need to write more than one file. This isn't logic I want to put in the bash script, that's the Uploader's job.

Things to note:

  • I am using Java 6 on the Uploader. No fancy stuff.
  • I am using Spring 3.2 for the Uploader. No boot.
  • I can probably use utility libraries in the Uploader.
  • I am using Java 8 for the command line executable.

Some relevant code:

Uploader.java

@Override
public String upload(String path, byte[] fileContents) {
    final File file = new File(path);
    try {
        FileUtils.writeByteArrayToFile(file, fileContents);
    } catch (IOException e) {
        throw new RuntimeException("Error writing file to path " + path, e);
    }
    return "";
}

init.sh

#!/bin/bash

CONFIGDIR=${spring.config.location}
CONFIGFILE=$CONFIGDIR/${app.name}.conf
# Loading a settings from CONFIGFILE
[ -f $CONFIGFILE ] && source $CONFIGFILE

# Setting JAVA_BIN
if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD="`which java`"
  fi
fi

# Starting the application
$JAVACMD $JAVA_OPTS -jar ${app.home}/bin/${build.finalName}.jar  "$@" --spring.config.location=$CONFIGDIR/

This whole thing smells like some trivial problem that shouldn't even be there in the first place, but I'm stumped. Would appreciate any help in the matter.

like image 892
Madara's Ghost Avatar asked Aug 24 '15 13:08

Madara's Ghost


1 Answers

Have you tried using sudo?

sudo -u web $JAVACMD $JAVA_OPTS -jar ${app.home}/bin/${build.finalName}.jar  "$@" --spring.config.location=$CONFIGDIR/

This should work, since the command-line interface is invoked by users logged in as root (which is not recommendable, but I take it as given).

like image 143
Lars Gendner Avatar answered Oct 31 '22 10:10

Lars Gendner