Category Archives: at-job

Execute AT command from browser when someone access my page

I need to execute AT command from browser. My /etc/at.deny is empty and /etc/at.allow does not exists. I could execute "php page.php" on command line with any user and works fine.

Here is my page (page.php):

<?php
exec('at -f job.txt now + 1 minutes'); 
?>

My job.txt:

/bin/php /var/www/html/my_job.php 

So now I wan't to execute page.php when someone access my page.php from their browser:

https://mywebpage.com/page.php

I got this error "PAM failure: System error" from /var/log/httpd/error_log when someone access my page. I guess that this error is caused by permission issue, could someone please tell me how fix it or give me some suggestion. I can't found any answer or example online.

UPDATE

Thanks to Barmar reminded me that I should use full path. And now this is my new page.php, but I still getting same error "PAM failure". Any suggestion please?

<?php
exec('at -f /var/www/html/job.txt now + 1 minutes');
>?

I think that the main problem is AT command. If I remove the AT command and using 'sh' command it will work.

exec('sh /var/www/html/job.txt'); 

UPDATE:

So finally I found the problem, the SELinux block the apache to use atd command. Now I don't get "PAM failure" in error_log anymore after I set my SELinux to Permissive. However, I still getting some error, my /var/log/httpd/error_log appear 'job 47 at Sat May 26 22:38:00 2018', everything seem okay but my_job.php didn't works. Why? Did I miss something?

How can I allow PHP to use the at command in exec() calls when SELinux is enabled?

I have a PHP script that takes a long time to load. We have moved our sites to a new server which lives behind a cloud load balancer. The maximum time limit for the load balancer is 120 seconds, but the script takes well over 5 minutes. Splitting the script up is not an option.

I rewrote the script so it would run on the command line, and I can successfully call this:

php -f /path/to/long_php.php > /path/to/log_file.php

I can then call this from PHP by doing this:

exec('php -f /path/to/long_php.php > /path/to/log_file.php');

Of course, because this script takes a long time to load, I don't want the PHP page to wait. Back on the command line I successfully used the at command like so:

echo "php -f /path/to/long_php.php > /path/to/log_file.php" | at now

So, I expected when running a similar thing in PHP it would work:

exec('echo "php -f /path/to/long_php.php > /path/to/log_file.php" | at now');

However this doesn't work. Unlike all the previou tries, the final command here give me SELinux errors:

----
type=SYSCALL msg=audit(07/25/2014 21:12:50.027:793672) : arch=x86_64 syscall=open success=no exit=-13(Permission denied) a0=7fd6fc2186bb a1=80000 a2=1b6 a3=0 items=0 ppid=55040 pid=55041 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=unix_chkpwd exe=/sbin/unix_chkpwd subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.027:793672) : avc:  denied  { read } for  pid=55041 comm=unix_chkpwd name=shadow dev=md2 ino=11797556 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:shadow_t:s0 tclass=file
----
type=SYSCALL msg=audit(07/25/2014 21:12:50.028:793673) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=10 a1=3 a2=9 a3=7fff46547e40 items=0 ppid=55038 pid=55040 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=at exe=/usr/bin/at subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.028:793673) : avc:  denied  { create } for  pid=55040 comm=at scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=netlink_audit_socket
----
type=SYSCALL msg=audit(07/25/2014 21:12:50.028:793674) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=10 a1=3 a2=9 a3=1 items=0 ppid=55038 pid=55040 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=at exe=/usr/bin/at subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.028:793674) : avc:  denied  { create } for  pid=55040 comm=at scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=netlink_audit_socket
----
type=SYSCALL msg=audit(07/25/2014 21:12:50.028:793675) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=10 a1=3 a2=9 a3=7fff46547eb0 items=0 ppid=55038 pid=55040 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=at exe=/usr/bin/at subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.028:793675) : avc:  denied  { create } for  pid=55040 comm=at scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=netlink_audit_socket

Note: the above is from /var/log/audit/audit.log piped through ausearch -i

After this I piped those in to audit2allow -w to see why, and the first error was regarding allow_httpd_mod_auth_pam not being enabled. I then enabled this and got some other errors. Running them through audit2allow -M tmpat produced me tmpat.pp, with an associated tmpat.te:

module tmpat 1.0;

require {
        type initrc_var_run_t;
        type httpd_t;
        class capability audit_control;
        class file read;
}

#============= httpd_t ==============
allow httpd_t initrc_var_run_t:file read;
allow httpd_t self:capability audit_control;

Unfortunately, when I run semodule -i tmpat.pp it still doesn't work. Repeating the process of using audit2allow -w above gives me more of the same Missing type enforcement (TE) allow rule. errors. So with that in mind, I'm hoping someone can tell me what changes I need to make to the generated tmpat.te to make this work?

Note: I'm on CentOS 6.5, with Apache 2.2, PHP 5.4

Update:

After looking in to policies, albeit it being something new to me, and I came up with the following:

module tmpat 1.1;
  require {
  type tmp_t;
  type httpd_t;
  class file { create getattr open read rename unlink write };
  class dir { add_name getattr open read remove_name search write };
}

#============= httpd_t ==============
allow httpd_t tmp_t:file { create getattr open read rename unlink write };
allow httpd_t tmp_t:dir { add_name getattr open read remove_name search write };

Currently this compiles but won't install, giving me this:

[[email protected] tmp]# semodule -i tmpat
semodule:  Failed on tmpat!

...but hopefully this might give some insight in to what I'm trying to do.