6

I have a PHP script running which makes symlinks.

To confirm which user it is:

file_put_contents("testFile", "test");
$user = fileowner("testFile");
unlink("testFile");
echo "running as user '" . $user . "'";
var_dump( exec('whoami'));

running like this ...

$ php script.php

runs correct all symlinks are made and output is:

running as user '999'string(5) "admin"

Running through a shell script:

#!/bin/sh
php /path/to/script.php

gives the following output and doesn't work:

PHP Warning: symlink(): Permission denied in /path/to/script.php on line 8 running as user '999'string(5) "admin"

I'm not sure what the difference between the two is, as the users they are running as are identical.

Any suggestions on how to make them both have the correct permissions for symlinking?


cat /proc/version

gives:

Linux version 2.6.39 (root@cross-builder) (gcc version 4.6.3 (x86 32-bit toolchain - ASUSTOR Inc.) ) #1 SMP PREEMPT Thu Oct 31 21:27:37 CST 2013

That's the only output I can generate for any sort of release information.


All of the code:

$files = scandir('/volume1/dir1');
$base = "/volume1/";
foreach($files as $file) {
        $f_letter = $file{0};
        $new_path = $base . "ByLetter/" . strtoupper($f_letter) . "/" . $file;
        if(ctype_alpha ($f_letter) && !is_link($new_path)) {
                var_dump($base. "TV/" . $file);
                var_dump($new_path);
                symlink ($base . "TV/" . $file , $new_path);
        }


}

gives the same output for the var dumps both methods.

  • AFAIK unlink() deletes file. Is that exactly what you want? – dchirikov Jun 3 '14 at 21:42
  • Yes in that case, to check the owner of testfile. Symlink works in the first and fails in the second, yet both are run by the same user – exussum Jun 3 '14 at 21:43
  • Ok, see. Then try to check selinux and pwd, may be. – dchirikov Jun 3 '14 at 21:50
  • the command setenforce doesnt exist so im fairly sure its not there – exussum Jun 3 '14 at 21:57
  • 1
    can you show us the code that actually creates the symlink? I reckon this is probably a lack of absolute paths issue or similar. This is why I always write code paths relative paths to __DIR__. If you are trying to always create the symlink in the cwd, then it will fail whenever executing user is currently in a directory he cannot write to. – Programster Jun 23 '14 at 23:02
1

Try using an absolute path. The code unlink("testFile"); looks for a file at present working directory. The pwd changes according to the current working directory. So use unlink("/path/to/testFile");

  • The script works its supposed to make it in cwd. Its the symlink when which fails at times – exussum Jun 21 '14 at 5:58
0

I took the code you posted, thought it was the beginning of a useful function, tweaked it, and couldn't get it to fail (probably because my user has write access to both paths). I made sure to add lots of checks to let you know if something is going wrong. Let me know if you still get the same issue. Make sure to remember that if you execute the script through the CLI, the script has the permissions as you, however if executed through a webserver, it has the permissions of the webserver user (e.g. www-data)

<?php

/**
 * Creates an index of the files in the specified directory, by creating symlinks to them, which
 * are separated into folders having the first letter.
 * WARNING - this will only index files that start with alphabetical characters.
 * @param $directory_to_index - the directory we wish to index.
 * @param $index_location - where to stick the index.
 * @return void
 */
function create_file_index($directory_to_index, $index_location)
{
    # Don't let the user place the index in the same folder being indexed, otherwise the directory
    # cannot be re-indexed later, otherwise we will be indexing the index.
    if ($directory_to_index == $index_location)
    {
        throw new Exception('Cannot place index in same folder being indexed!');
    }

    # delete the old index if one already exists.
    if (file_exists($index_location))
    {
        deleteNonEmptyDir($index_location);
    }

    if (!mkdir($index_location))
    {
        throw new Exception('Failed to create index directory, check write permissions');
    }

    $files = scandir($directory_to_index);

    foreach ($files as $filename) 
    {
        $first_letter = $filename[0];
        $placement_dir = $index_location . "/" . strtoupper($first_letter);

        if (ctype_alpha($first_letter))
        {
            # create the placement directory if it doesn't exist already
            mkdir($placement_dir);

            $new_path = $placement_dir . "/" . $filename;

            if (!is_link($new_path)) 
            {
                symlink($directory_to_index . '/' . $filename, $new_path);
            }
        }
    }
}

/**
 * Deletes a directory even if it is not already empty. This resolves the issue with
 * trying to use unlink on a non-empty dir.
 * @param String $dir - the path to the directory you wish to delete
 * @return void - changes your filesystem
 */
function deleteNonEmptyDir($dir) 
{
    if (is_dir($dir)) 
    {
        $objects = scandir($dir);

        foreach ($objects as $object) 
        {
            if ($object != "." && $object != "..") 
            {
                if (filetype($dir . "/" . $object) == "dir")
                {
                    deleteNonEmptyDir($dir . "/" . $object); 
                }
                else
                {
                    unlink($dir . "/" . $object);
                }
            }
        }

        reset($objects);
        rmdir($dir);
    }
}

create_file_index('/volume1/dir1', '/volume1/dir1/ByLetter');
0

The PHP function fileowner returns a numeric uid and not a username. The uid 999 probably corresponds to your admin user; you can check this with the command id:

id admin

The output should begin with the uid of that account.

  • It does - also confirmed by the whoami command. both places output the same so its defo the same user. Though 1 place runs successfully and the other fails – exussum Jun 25 '14 at 7:05
  • Then your issue is probably unrelated to the user. I'd look into the relative paths as totti suggested. – Martin von Wittich Jun 25 '14 at 7:56
  • its not a relative pat. That code was there to prove it was running as the same user .. – exussum Jun 25 '14 at 8:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.