Re: How to get server user?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 02/18/2015 01:37 PM, Jeffry Killen wrote:

On Feb 18, 2015, at 7:03 AM, Jason Edgecombe wrote:

On 02/17/2015 01:28 PM, Jeffry Killen wrote:

On Feb 17, 2015, at 7:17 AM, Jason Edgecombe wrote:



I'm saying proceed, then check the result. For example, you might use this code if you want to write to a new file:
|<?php
$file = 'people.txt';
// The new person to add to the file
$person = "John Smith\n";
// Write the contents to the file,
// using the FILE_APPEND flag to append the content to the end of the file // and the LOCK_EX flag to prevent anyone else writing to the file at the same time
if (file_put_contents($file, $person, LOCK_EX)) {
echo "success\n";
} else {|
||  echo "failed\n";
|}
?>|

If you are replacing the contents of a file, it's usually better to copy/write to a new file, update the file, then rename() the new file to the old file's name. This is the same as 'mv' in Linux/unix, which makes things a little cleaner. I think that rename/mv is atomic, but I could be wrong.

Jason

This is pretty much what I am doing.
public static function getOwner($_target)
              {
               $_astat = stat($_target);
               $_owner = '';
foreach(posix_getpwuid ( $_astat['uid'] ) as $_sKey=>$_value)
                 {
                  if($_sKey == 'name')
                    {
                     $_owner = $_value;
                    }
                 }
               clearstatcache();
               return $_owner;
             }
And, as you suggest, write a file with code and run it through this to get the owner user name. I am trying to pre screen file related related function calls with this.

I am in the habit of using templates for flat file database files. They produced php code
files like
<?php
$_someVar = someVal;
// add ->
?>
So, if I want to add to this file, I just str_replace the target string '// add ->'
with the new content and another instance of the target string.

So now I have a small php script file that was generated by writing a file and using the above function (geOwner)
<?php
$_serName = "_www";
?>
And all I have to do is include this file wherever I want to find out if a user is the web server user.

The portability issue would be with the posix related functions, I presume.

Thanks again
JK


I don't think that we're on the same page. Why do you need to know the owner of the file and the server? Why are you duplicating the permissions checking of the filesytem?

Jason

It is just to determine if a file is editable by the server via php script and give the user some friendly indication of why it may not be and what could be done about it, instead of the user seeing error messages generated by the script. A la defensive programming.

I applaud your effort to program defensively. I suggest using something like the following code to determine if the file is writeable.
--------------------------------------------
<?php
$handle = @fopen("/tmp/foo", "c");
if ($handle) {
  print "writable\n";
  if(!flock($handle, LOCK_EX | LOCK_NB)) {
    echo 'Unable to obtain lock. file is in use';
  }
  fclose($handle);
} else {
  print "not writable\n";
}
?>
--------------------------------------------
In the above example, fopen will return false and an error if the file isn't writable by the server user. The 'c' mode is used instead of 'w' to avoid truncating the file, so the file is left intact. Note that the file pointer is positioned at the beginning of the file. The flock call uses the 'LOCK_NB' parameter to immediately return instead of waiting for a lock. Using locking is highly recommended to avoid concurrent access to the same file.

I'm not a fan of the '@' operator, but I can't find a way to avoid using it in this context, because we need to suppress the error and check it later.

Pros:
 * simple code
 * doesn't duplicate what the OS and file system already do.
 * should work properly with selinux and other weird scenarios.

Cons:
* might not be fast enough for checking lots of files at once. Be sure to benchmark it.
--

As an alternative, you may want to use the following code example:
<?php
if (is_writable('/tmp/foo')) {
  print "writable\n";
} else {
  print "not writable\n";
}
?>
The above code uses the access() system call, which doesn't call fopen() and checks the mode bits. I suspect that this is faster than my first example, but it might lie to you in some edge cases. This second example is probably the more commonly used code, but I manage a system where is_writable() and friends are wrong more often than normal, so I'm a little biased about this. ;)

--

If you're dead set on duplicating the OS and file system code by checking mode bits and owner id's in your code, then you'll need to use the posix_getuid() or posix_geteuid() functions.

Ref:
http://php.net/manual/en/function.posix-getuid.php
http://php.net/manual/en/function.posix-geteuid.php

I hope that this helps and that you take the 'DRY' principle to heart so that you don't repeat yourself or repeat work done by others.

P. S. I'm not infallible. If anyone has a better idea or wants to discuss the trade-offs, please speak up.

Sincerely,
Jason

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php





[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux