Permissões de arquivo

6

Eu tenho um script PHP em execução que faz links simbólicos.

Para confirmar qual usuário é:

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

funcionando assim ...

$ php script.php

executa corretamente todos os links simbólicos são criados e a saída é:

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

Executando um script de shell:

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

fornece a seguinte saída e não funciona:

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

Não sei qual é a diferença entre os dois, pois os usuários que estão executando são idênticos.

Alguma sugestão sobre como fazer com que ambos tenham as permissões corretas para o symlinking?

cat /proc/version

dá:

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

Essa é a única saída que posso gerar para qualquer tipo de informação de lançamento.

Todo o código:

$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);
        }


}

fornece a mesma saída para os dois métodos de dump.

    
por exussum 03.06.2014 / 23:28

3 respostas

1

Tente usar um caminho absoluto. O código unlink("testFile"); procura por um arquivo no diretório de trabalho atual. O pwd muda de acordo com o diretório de trabalho atual. Então use unlink("/path/to/testFile");

    
por 21.06.2014 / 07:02
0

Eu peguei o código que você postou, achei que era o começo de uma função útil, ajustei-a e não consegui fazer com que ela falhasse (provavelmente porque meu usuário tem acesso de gravação aos dois caminhos). Certifiquei-me de adicionar muitos cheques para que você saiba se algo está errado. Deixe-me saber se você ainda tem o mesmo problema. Lembre-se de que, se você executar o script por meio da CLI, o script terá as permissões necessárias, mas, se executado por meio de um servidor da Web, terá as permissões do usuário do servidor da Web (por exemplo, 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');
    
por 25.06.2014 / 00:31
0

A função PHP fileowner retorna um numérico uid e não um nome de usuário. O uid 999 provavelmente corresponde ao seu usuário admin ; você pode verificar isso com o comando id :

id admin

A saída deve começar com o uid dessa conta.

    
por 25.06.2014 / 00:46