104

I'm trying to create a log file at the start of my program.

I need to check if a /log directory exists if it doesn't create the directory then move on to creating the log file.

Well I tried to use os.Mkdir (as well as os.MkdirAll), but no matter what value I put into the second parameter I get a locked out folder with no permissions. What value should this be in order to get a read / write for user folder? I thought it would be 0x700 but it doesn't seem to work.

Thanks!

Script and Compile
  • 1,286
  • 3
  • 10
  • 17

5 Answers5

166

You can use octal notation directly:

os.Mkdir("dirname", 0700)

**Permission Bits**

Permission bits are historically given in Octal, so the literal value must be prefixed by a 0. Otherwise it will be interpreted as decimal and give confusing results. This is consistent with the Linux command chmod.

+-----+---+--------------------------+
| rwx | 7 | Read, write and execute  |
| rw- | 6 | Read, write              |
| r-x | 5 | Read, and execute        |
| r-- | 4 | Read,                    |
| -wx | 3 | Write and execute        |
| -w- | 2 | Write                    |
| --x | 1 | Execute                  |
| --- | 0 | no permissions           |
+------------------------------------+

+------------+------+-------+
| Permission | Octal| Field |
+------------+------+-------+
| rwx------  | 0700 | User  |
| ---rwx---  | 0070 | Group |
| ------rwx  | 0007 | Other |
+------------+------+-------+

A Unix Permission Primer


Common Permission Usages

0755 Commonly used on web servers. The owner can read, write, execute. Everyone else can read and execute but not modify the file.

0777 Everyone can read write and execute. On a web server, it is not advisable to use ‘777’ permission for your files and folders, as it allows anyone to add malicious code to your server.

0644 Only the owner can read and write. Everyone else can only read. No one can execute the file.

0655 Only the owner can read and write, but not execute the file. Everyone else can read and execute, but cannot modify the file.

www.maketecheasier.com/file-permissions-what-does-chmod-777-means/


**Directory Permissions on Linux**

When applying permissions to directories on Linux, the permission bits have different meanings than on regular files. (source)

Read bit The user can read the file names contained in the directory.
Write bit The user can {add,rename,delete} files names IF the execute bit is set too.
Execute bit The user can enter the directory and access the files inside.

https://unix.stackexchange.com/a/21252

Permissions Calculator

permissions calculator

A handy permissions calculator.

Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
Shannon Matthews
  • 9,649
  • 7
  • 44
  • 75
  • 10
    I don't understand how you obviously seem to understand unix permissions, given an explanation for them, yet still say that "in some cases, you will need to set the 777 permissions before you can upload any file to the server (For example, uploading images in WordPress)" NO! You NEVER need in except in very few cases (like `/tmp`, but that has the `sticky` bit set so it's not the same). If you need to upload things, then set the user of the directory to the user running the webserver or PHP. That's enough. No need to have random users or the MTA or whatever to be able to write to this dir – Martin Tournoij Mar 13 '16 at 05:16
  • @Carpetsmoker thanks for the extra info. I copied the contents of this answer from several places. (see the source links.) Do you know of any blog posts or documentation that explains the ins and outs of using unix permissions? – Shannon Matthews Mar 29 '16 at 01:40
  • 1
    I wrote a [brief introduction here](http://stackoverflow.com/a/35895436/660921) which should cover most of the basics (I'm working on a more expanded version)... In the Wordpress example, you'll want to set the upload directory to the user that needs to write to it (that is, the user running `php` or the webserver), and set it to `755`, so that *only* that user can write to it. – Martin Tournoij Mar 29 '16 at 02:13
  • That looks pretty good. I've updated the the 777 permissions text above. – Shannon Matthews Mar 29 '16 at 02:35
  • 2
    This answer turns a blind eye to the requirement of the extra `0` that precedes the permission values. Can someone speak to that and add it to the answer? – Shadoninja Feb 08 '18 at 16:09
  • 2
    Also worth noting that directories need the *execute* permission. It's a weird Unix thing. – Timmmm Mar 29 '18 at 10:31
  • @Timmmm I've updated the post with some extra info. Thanks for the tip. :) – Shannon Matthews Mar 30 '18 at 11:58
  • 2
    @Timmmm directory need execute permission so you can _cd_ into it. – yusufmalikul Oct 31 '19 at 03:51
  • @Shadoninja I edited the answer to give the reason for the `0` prefix. – Mark Lakata Aug 24 '23 at 22:50
26

@Daniel's statement in his answer is not really correct, and also it talks about a decimal number and then uses an octal one, as @SashaCrofter correctly pointed out in his comment.

In reality, it doesn't matter what form your permission value is in as long as it represents sensible Unix permissions.

Since permission bits on POSIX file systems come in triples of bits — three bits for owner, group and others access, plus three bits of modifiers (such as sticky bits), — it's customary to use octal numbers to represent permissions as each digit in an octal number represents a three-bit value.

Hence, when you use 0700 in Go code, the leading 0 is stripped and is only there to tell the parser it sees an octal number literal, and the following three letters stand for the owner, group and others permissions, in this order. Should you, say, want to also set the group sticky bit as well as making the file system object group-readable and executable, you'd specify 02750 and so on.

Note that the actual permissions the file system object acquires is further modulated by the active umask of the process which creates the object.

To get more grip on these topics, it's best to read the chmod manual pages and general literature on Unix-like operating systems.

kostix
  • 51,517
  • 14
  • 93
  • 176
21

You can reset the umask to 0. I would call this as the first thing in my main file

syscall.Umask(0)

Example

_ = os.MkdirAll("/tmp/dirs/1", 0664)
syscall.Umask(0)
_ = os.MkdirAll("/tmp/dirs/2", 0664)

Result

/tmp/dirs$ stat -c '%A %a %n' *
drw-r--r-- 644 1
drw-rw-r-- 664 2
Jossef Harush Kadouri
  • 32,361
  • 10
  • 130
  • 129
13

Besides the other answers, remember that on Unix and Linux style operating systems, all programs run with a umask setting. The umask, which in many cases defaults to 022 or sometimes 002, is the set of permissions that the system will automatically remove from file and directory creation requests.

What this means is that most programs–there are several exceptions to this rule—should use mode 0666 for creating files and mode 0777 for creating directories. The user's configuration, recorded in the running process, says which of these permissions to take away. If the user's setting is 022, and we create a file with mode 0666, the actual setting we get is rw-r--r--: read and write for the user, read-only for the group, and read-only for others.

If a user wishes to extend writability to their group, they need only set their umask to 2: now they take away write permission for others, but leave it for their group. New files are now created with mode rw-rw-r--. The program does not change: it still uses 0666 for its mode. But the files are created with mode 0664.

Similarly, if you call os.Mkdir or os.MkdirAll with 0777, the umask will take away the unwanted permissions, leaving you with the right permissions.

But I mentioned that there are exceptions. These include programs that make copies of sensitive information meant only for the user: these should generally use mode 0700 for directories and 0600 for files. They may include long-running servers that act as a system user rather than any one individual ... although those servers could be run with a correct umask, in which case, 0777 or 0666 is fine.

You must apply some judgment here. Programs that are especially security-conscious, such as ssh or similar, may wish to use limited permissions, and may even want to check (with os.Lstat or similar) that permissions are appropriately tight on important directories.

(Note that the umask does not apply to os.Chmod calls. Here you choose the mode directly.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • Great explanation. If you could add some sources to this info where they write the ideas in such simple way as yours, I'll appreciate it. – Mike Sep 14 '20 at 19:35
  • 1
    @Mike: I'm really not sure where to find *simple* descriptions. [The Wikipedia umask page](https://en.wikipedia.org/wiki/Umask) has good information, though. I learned this stuff the hard way back in the early 1980s... – torek Sep 14 '20 at 22:26
4

One way to make sure that you're setting the kind of permissions you want, without figuring out the complex calculations in octal, is to use the very convenient FileMode constants in package os:

https://golang.org/pkg/os/#FileMode

I usually use os.ModePerm (which is actually coded as 0777) for fully permissive directories, such as those required for caches or temporary files, but your mileage may vary. To set the additional bits (sticky, etc.), which, as @kostix has noted, has to deal with the issue of octal representation of flags in Go, you can always use something like:

if err := os.MkdirAll("my/tmp/dir", os.ModeSticky|os.ModePerm); err != nil {
  ... handle error ...
}

Go playground

As always, it's worth mentioning again that these permissions are 'filtered' by whatever umask has been set.

nishanthshanmugham
  • 2,967
  • 1
  • 25
  • 29
Gwyneth Llewelyn
  • 796
  • 1
  • 11
  • 27