Bug 592805 - SELinux is preventing vsftpd from writing files/dirs inside ~/public_html/
SELinux is preventing vsftpd from writing files/dirs inside ~/public_html/
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: selinux-policy (Show other bugs)
5.5
All Linux
low Severity medium
: rc
: ---
Assigned To: Miroslav Grepl
Milos Malik
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2010-05-16 22:45 EDT by Ahmed Medhat
Modified: 2012-09-24 09:46 EDT (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Due to an error in SELinux rules, the vsftpd daemon may have been unable to write to a file or create a directory inside ~/public_html/, reporting the following error message: 550 Create directory operation failed. This update fixes the SELinux rules, and vsftpd now works as expected.
Story Points: ---
Clone Of:
Environment:
Last Closed: 2011-01-13 16:49:41 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Ahmed Medhat 2010-05-16 22:45:58 EDT
Description of problem:

Summary
SELinux is preventing the ftp daemon from writing files outside the home directory (./public_html).
Detailed Description
SELinux has denied the ftp daemon write access to directories outside the home directory (./public_html). Someone has logged in via your ftp daemon and is trying to create or write a file. If you only setup ftp to allow anonymous ftp, this could signal a intrusion attempt.
Allowing Access
If you do not want SELinux preventing ftp from writing files anywhere on the system you need to turn on the allow_ftpd_full_access boolean: "setsebool -P allow_ftpd_full_access=1" 

The following command will allow this access:
setsebool -P allow_ftpd_full_access=1
Additional Information
Source Context:  	system_u:system_r:ftpd_t
Target Context:  	user_u:object_r:httpd_sys_content_t
Target Objects:  	./public_html [ dir ]
Source:  	vsftpd
Source Path:  	/usr/sbin/vsftpd
Port:  	<Unknown>
Host:  	<OMITTED>
Source RPM Packages:  	vsftpd-2.0.5-16.el5_4.1
Target RPM Packages:  	
Policy RPM:  	selinux-policy-2.4.6-279.el5
Selinux Enabled:  	True
Policy Type:  	targeted
MLS Enabled:  	True
Enforcing Mode:  	Enforcing
Plugin Name:  	allow_ftpd_full_access
Host Name:  	<OMITTED>
Platform:  	Linux <OMITTED> 2.6.18-194.3.1.el5xen #1 SMP Thu May 13 13:49:53 EDT 2010 x86_64 x86_64
Alert Count:  	1
First Seen:  	Sun May 16 10:00:11 2010
Last Seen:  	Sun May 16 10:00:11 2010
Local ID:  	4ecc680b-abc0-409d-8a20-80efe1ec6535
Line Numbers:  	
Raw Audit Messages :

host=<OMITTED> type=AVC msg=audit(1274029211.963:430): avc: denied { write } for pid=2627 comm="vsftpd" name="public_html" dev=dm-0 ino=2448226 scontext=system_u:system_r:ftpd_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=dir 
host=<OMITTED> type=SYSCALL msg=audit(1274029211.963:430): arch=c000003e syscall=2 success=no exit=-13 a0=2b80a7d1a230 a1=c41 a2=1b6 a3=0 items=0 ppid=2623 pid=2627 auid=4294967295 uid=1051 gid=1051 euid=1051 suid=1051 fsuid=1051 egid=1051 sgid=1051 fsgid=1051 tty=(none) ses=4294967295 comm="vsftpd" exe="/usr/sbin/vsftpd" subj=system_u:system_r:ftpd_t:s0 key=(null) 


Version-Release number of selected component (if applicable):
libselinux-1.33.4-5.5.el5
libselinux-python-1.33.4-5.5.el5
libselinux-utils-1.33.4-5.5.el5
selinux-policy-2.4.6-279.el5
selinux-policy-targeted-2.4.6-279.el5
vsftpd-2.0.5-16.el5_4.1

allow_ftpd_anon_write --> off
allow_ftpd_full_access --> off
allow_ftpd_use_cifs --> off
allow_ftpd_use_nfs --> off
allow_tftp_anon_write --> off
ftp_home_dir --> on
ftpd_connect_db --> off
ftpd_disable_trans --> off
ftpd_is_daemon --> on
httpd_enable_ftp_server --> off
tftpd_disable_trans --> off


How reproducible:
Always!


Steps to Reproduce:
1. Login using normal user account through FTP
2. Change directory to ~/public_html/
3. Try creating a new directory
  
Actual results:

## FROM FTP SESSION
550 Create directory operation failed.

## FROM PIPING audit.log TO audit2why
type=AVC msg=audit(1274063732.349:151): avc:  denied  { write } for  pid=2549 comm="vsftpd" name="mail" dev=dm-0 ino=2448684 scontext=system_u:system_r:ftpd_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=dir
	Was caused by:
		Missing or disabled TE allow rule.
		Allow rules may exist but be disabled by boolean settings; check boolean settings.
		You can see the necessary allow rules by running audit2allow with this audit message as input.


## FROM `ps auxwfZ | grep vsftpd`
system_u:system_r:ftpd_t         1477 ?        Ss     0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
system_u:system_r:ftpd_t         2545 ?        Ss     0:00  \_ /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
system_u:system_r:ftpd_t         2549 ?        S      0:00      \_ /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

## FROM /etc/vsftpd/vsftpd.conf
chroot_local_user=YES

## FROM `ls -laZ /home/user/ | grep public_html`
drwxr-xr-x  userid userid user_u:object_r:httpd_sys_content_t public_html

## FROM `ls -laZ /home/userid/public_html/ | grep normaldir`
drwxr-xr-x  userid userid user_u:object_r:httpd_sys_content_t normaldir

## AFTER ENABLING PERMISSIVE MODE THEN CREATING A NEW DIR INSIDE ~/public_html/, `ls -laZ /home/userid/public_html/ | grep dir`
drwxr-xr-x  userid userid system_u:object_r:httpd_sys_content_t testingdir1

## AFTER RUNNING `restorecon -F -R /home/userid/public_html/`
drwxr-xr-x  userid userid user_u:object_r:httpd_sys_content_t normaldir
drwxr-xr-x  userid userid user_u:object_r:httpd_sys_content_t testingdir1

Additional info:
I suspect this happening after upgrading to 5.5, before that it never occurred.
Comment 1 Daniel Walsh 2010-05-17 08:50:55 EDT
Misoslav this should be allowed with the ftp_home_dir boolean turned on.  It is in RHEL6 and the latest Fedora policies.  In RHEL5 this directory is labeled httpd_sys_content_t and in RHEL6 it is labeled httpd_user_content_t.  

I think you need to add 

apache_manage_sys_content(ftpd_t)

Within the ftp_home_dir tunable.

Ahmed, use audit2allow to add this as custom policy for now.

# grep ftp /var/log/audit/audit.log | audit2allow -M myftp
# semodule -i myftp.pp
Comment 2 Gabriel VLASIU 2010-05-17 09:07:44 EDT
(In reply to comment #1)
> Misoslav this should be allowed with the ftp_home_dir boolean turned on.

For me is ftp_home_dir on and still file upload does not work after upgrading to rhel 5.5 (proftpd server in my case).

# getsebool -a | grep ftp_home_dir
ftp_home_dir --> on

I had to write a custom policy:

module proftpdw 1.0;

require {
        type ftpd_t;
        type httpd_sys_content_t;
        class dir { rename write rmdir remove_name create add_name };
        class file { write rename create unlink setattr };
}

#============= ftpd_t ==============
allow ftpd_t httpd_sys_content_t:dir { rename write rmdir remove_name create add_name };
allow ftpd_t httpd_sys_content_t:file { write rename create unlink setattr };

I hate when I have to write a policy to fix something that went well before.
Comment 3 Ahmed Medhat 2010-05-17 10:23:39 EDT
Well,

That worked for me too, however one thing I am still curious about is why when restarting a service from command line takes a different security context than the one initd did gave it and how to fix this, or in another word how to properly restart a service from SELinux point of view so it starts in the proper context.
Comment 4 Ahmed Medhat 2010-05-17 10:27:02 EDT
Ah, now here's the context when I create a new dir through FTP..

drwxr-xr-x  userid userid system_u:object_r:httpd_sys_content_t testdir

And now after restorecon..

drwxr-xr-x  userid userid user_u:object_r:httpd_sys_content_t testdir

Why isn't the file already created with the proper context ? am I missing something :) ?
Comment 5 Daniel Walsh 2010-05-17 11:26:38 EDT
SELinux is based on transition rules written in policy.

unconfined_t @> initrc_file_t -> initrc_t @> ftpd_exec_t -> ftpd_t

But we like to keep unconfined unconfined.

unconfined_t @> ftpd_exec_t -> unconfined_t


You can ignore the user part.  system_u indicates that a process started at boot wrote a file label on a file.  user_u indicates a process started by a user created the file.  For the most part SELinux ignores the user component.
Comment 6 Miroslav Grepl 2010-09-09 09:14:06 EDT
(In reply to comment #1)
> Misoslav this should be allowed with the ftp_home_dir boolean turned on.  It is
> in RHEL6 and the latest Fedora policies.  In RHEL5 this directory is labeled
> httpd_sys_content_t and in RHEL6 it is labeled httpd_user_content_t.  
> 
> I think you need to add 
> 
> apache_manage_sys_content(ftpd_t)
> 
> Within the ftp_home_dir tunable.
> 
> Ahmed, use audit2allow to add this as custom policy for now.
> 
> # grep ftp /var/log/audit/audit.log | audit2allow -M myftp
> # semodule -i myftp.pp

Fixed in selinux-policy-2.4.6-283.el5.noarch
Comment 9 Jaromir Hradilek 2011-01-05 11:15:27 EST
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Due to an error in SELinux rules, the vsftpd daemon may have been unable to write to a file or create a directory inside ~/public_html/, reporting the following error message:

  550 Create directory operation failed.

This update fixes the SELinux rules, and vsftpd now works as expected.
Comment 11 errata-xmlrpc 2011-01-13 16:49:41 EST
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-0026.html

Note You need to log in before you can comment on or make changes to this bug.