basin
basin

Reputation: 4190

Beside umask what else affects permissions of new directories?

I noticed that if you interrup rsync, some new directories remain having permissions drwx------, although current umask is 0022.

I launched gdb and tried to explicitly call umask(0) right before calling mkdir(), but it had no effect: I expected new dirs to have drwxrwxrwx, but they still had drwx------.

(In newer versions of rsync they're no longer drwx------, but still unaffected by umask)

If I change the command to /bin/mkdir, calling umask() starts working. It seems that rsync is using some magic.

Here's a test script: (For some reason the breakpoint on mkdir() only works when copying from ssh)

(
rm -rf /tmp/3 && mkdir -p /tmp/3 && cd /tmp/3 &&
#gdb -q -nx --args /bin/mkdir foo <<EOF
gdb -q -nx --args rsync -r --include=/profile.d --exclude="*" localhost:/etc/ ./ <<'EOF'
set width 0
set height 0
set pagination no
set breakpoint pending on
b mkdir
b mkdirat
run
del
print (char*)$rdi
call umask(0)
call mkdir("test")
fin
shell ls -l
p/o umask(0)
k
EOF
)

_

Reading symbols from /usr/bin/rsync...Reading symbols from /usr/bin/rsync...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Missing separate debuginfos, use: debuginfo-install rsync-3.0.9-15.el7.x86_64
(gdb) (gdb) (gdb) (gdb) (gdb) Breakpoint 1 at 0x6c70
(gdb) Function "mkdirat" not defined.
Breakpoint 2 (mkdirat) pending.
(gdb) Starting program: /usr/bin/rsync -r --include=/profile.d --exclude=\* localhost:/etc/ ./
Detaching after fork from child process 15444.
Detaching after fork from child process 15464.

Breakpoint 1, 0x00007ffff76ee720 in mkdir () from /lib64/libc.so.6
(gdb) Delete all breakpoints? (y or n) [answered Y; input not from terminal]

mkdir argument:

(gdb) $1 = 0x7fffffff9330 "profile.d"

previous umask value:

(gdb) $2 = 0

result of mkdir("test")

(gdb) $3 = 0

_

(gdb) Run till exit from #0  0x00007ffff76ee720 in mkdir () from /lib64/libc.so.6
0x000055555556845f in recv_generator ()
(gdb) total 8
drwx------ 2 il il 4096 Jan 28 20:02 profile.d
drwx------ 2 il il 4096 Jan 28 20:02 test
(gdb) $4 = 0
(gdb) Kill the program being debugged? (y or n) [answered Y; input not from terminal]
rsync: connection unexpectedly closed (31 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
(gdb) quit
[il@basinsrv ~]$ rsync: connection unexpectedly closed (51 bytes received so far) [receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [receiver=3.0.9]

Upvotes: 1

Views: 267

Answers (1)

ash
ash

Reputation: 5165

The permissions requested when creating the directory are masked by the umask to obtain the final permissions.

Rsync is most likely using the permissions from the remote directory to apply to the local one. In addition, rsync may be setting the permissions after creating the directory using the chmod() system call which does not apply the umask at all.

The umask setting is designed to allow default permissions when creating directories or files without specifically setting the permissions on the file. Most simple utilities that create files simply request permission mode 666 (full perms for everybody) and let the umask trim that down.

NOTE too that using gdb may not work as desired. GDB can break on function calls in user space, but not on system calls. Try using strace (if this is Linux/Unix) - it shows all system calls as they are made (very, very handy for a case like this).

Upvotes: 2

Related Questions