Есть ли функция для нахождения полного разрешения файла? - PullRequest
2 голосов
/ 26 февраля 2020

Мне нужно использовать Go, чтобы получить права доступа к файлу для данного файла (в частности, бит SUID). Вот разрешения файла примера.

$ touch example_file.test
$ chmod 7777 example_file.test
$ ls -ltra example_file.test
    -rwsrwsrwt 1 luke users 0 Feb 25 21:53 example_file.test

$ stat -c "%a %n" example_file.test
     7777 example_file.test

Вот небольшая программа, иллюстрирующая проблему.

func main() {
    info, _ := os.Stat("example_file.test")
        fmt.Println(info.Mode().String())                        // ugtrwxrwxrwx
        fmt.Println(info.Mode().Perm().String())                 // -rwxrwxrwx
        fmt.Printf("permissions: %#o\n", info.Mode().Perm())     // permissions: 0777
}

Результаты Go противоречивы, поскольку ugtrwxrwxrwx != 0777.

Следующая цитата из документации указывает, что это может быть проблемой кросс-платформенной совместимости.

FileMode представляет режим файла и биты прав доступа. Биты имеют одинаковое определение во всех системах, так что информация о файлах может переноситься из одной системы в другую переносимым образом. Не все биты относятся ко всем системам. Единственный требуемый бит - это ModeDir для каталогов.

type FileMode uint32 Определенные биты режима файла являются наиболее значимыми битами FileMode. Девять младших битов - это стандартные права доступа Unix rwxrwxrwx. Значения этих битов следует считать частью API publi c и могут использоваться в проводных протоколах или представлениях дисков: их нельзя изменять, хотя могут быть добавлены новые биты.

Is это ограничение Go?

Ответы [ 2 ]

1 голос
/ 26 февраля 2020

Стоит отметить, что в дополнение к восьмеричным восьмеричным представлениям не соответствуют строковые представления:

"-rwsrwsrwt" != "ugtrwxrwxrwx"`

Это не связано с ограничением реализации Go, а является следствием c.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 100 * * * * * * * *

* * * *1011* FileMode представляет файл биты режима и разрешения. Биты имеют одинаковое определение во всех системах, так что информация о файлах может переноситься из одной системы в другую переносимым образом. Не все биты применяются ко всем системам.

Поскольку реализация не предназначена для имитации c поведения определенной системы c, выходные данные не гарантированно соответствует родным инструментам в данной среде. Тем не менее, все соответствующие данные доступны для работы.

Если вы хотите имитировать c вывод stat, вы можете просто написать несколько logi c для этого.

Вот небольшой пример восьмеричного представления:

package main

import (
    "fmt"
    "os"
)

func UnixPerm(m os.FileMode) (p uint32) {
    p = uint32(m.Perm())
    if m & os.ModeSetuid != 0 {
        p |= 04000
    }
    if m & os.ModeSetgid != 0 {
        p |= 02000
    }
    if m & os.ModeSticky != 0 {
        p |= 01000
    }
    return p
}

func main() {
    info, _ := os.Stat("example_file")
    fmt.Printf("FileMode.Perm(): %04o\n", info.Mode().Perm())
    fmt.Printf("UnixPerm(): %04o\n", UnixPerm(info.Mode()))
}

Вывод:

$ go run fileperm.go
FileMode.Perm(): 0777
UnixPerm(): 7777

$ stat --printf "Permissions: %a\n" example_file
Permissions: 7777
0 голосов
/ 26 февраля 2020

Мне нужно использовать golang, чтобы получить права доступа к файлу для данного файла (в частности, бит SUID)

Хорошо, добавьте: fmt.Printf("File has SUID bit set: %t\n", info.Mode()&os.ModeSetuid != 0)

Результаты golang противоречивы, потому что ugtrwxrwxrwx! = 0777

info.Mode() и info.Mode().Perm() - разные вещи, хотя и связаны между собой.

info.Mode().Perm() содержит подмножество info.Mode(). info.Mode().Perm() - это просто небольшая удобная функция для создания побитового И с постоянной маской 0777.

Это ограничение go?

Нет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...