2

Using php-fpm, nginx, CentOS 6.4 File being called = register.php I cannot create a file in my directory /.../wingd/profiles

Goal: Generate user profiles by creating files when a user registers for my website.

Error:

Warning: fopen(profiles/test.txt): failed to open stream: Permission denied in /usr/share/nginx/wingd/register.php on line 150

In my register.php I have:

$file = fopen("profiles/test.txt", "w") or die("Unable to open file!");

Things I have tried:

  1. chmod 777 for all files and folders associated (/usr/share/nginx/wingd/profiles all directories listed to the left all are 777 at the moment including 'register.php' (I understand 777 is a security concern and will worry about security later on once I understand the current issue and how to fix)

  2. Have used:

echo 'Current script owner: ' . get_current_user() . "<br>";
                    echo 'posix: '.posix_getuid()."<br>";
                    echo getcwd()."<br>";
                    $last_line = system('whoami', $retval);
                    echo $last_line . " " . $retval;

which has shown me that the script owner and the runner of the script is the nginx user.

  1. Have made nginx the owner for all files/dir mentioned above in #1.
  2. Have looked at /etc/php-fpm.d/www.conf and see that 'user = nginx' and 'group = nginx' currently
  3. I do not have a /var/www folder and I see a lot of these forum posts about similar issue referring to /var/www (is this an apache thing only?)
  4. Installed strace but am unsure how to use it or read its output of strace php register.php
  5. Was able to su nginx and then use touch command to touch /profiles/test.txt. It did create the file without error
  6. Was advised that I need to find out what php-fpm is using for a username and what its permissions are set to, not sure how to do this. I saw on another stackoverflow topic that php may be using a username of apache and I tried giving that user ownership of files and got no where.

I am not sure what else I can try.

Code:

<?php

include ("config.php");

?>
<html>
<body>

<a href="index.php">Index</a><br>
    <form name="registrationForm" method="post" onsubmit="return validateForm()">
        <input type="text" class="form-control" placeholder="Enter username" name="username"><font color="red">*</font>
        <input type="text" class="form-control" placeholder="Enter email address" name="email"><font color="red">*</font>
        <input type="password" class="form-control" placeholder="Enter password" name="password"><font color="red">*</font>
        <input type="text" class="form-control" placeholder="Enter first name" name="first"><font color="red">*</font>
        <input type="text" class="form-control" placeholder="Enter last name" name="last"><font color="red">*</font>
        <input type="text" class="form-control" placeholder="Enter zip code" name="zip"><font color="red">*</font>
        <input class="btn btn-default" type="submit" name="submit" value="Submit">
    </form>

    <?php
    ini_set('display_errors',1);
    error_reporting(E_ALL);

    if (isset($_POST['submit'])){
    //if($_SERVER["REQUEST_METHOD"] == "POST"){
        $username = $_POST["username"];
        $email = $_POST["email"];
        $password = $_POST["password"];
        $first = $_POST["first"];
        $last = $_POST["last"];
        $zip = $_POST["zip"];

        // Check connection
        if ($db->connect_error) {
            die("Connection failed: ".$db->connect_error);
        }

        //flag to detect if the username exists in db
        $flag = 0;
        $sql = "SELECT username FROM users WHERE username = '".$username."';";
        $result = $db->query($sql);
        if ($result->num_rows > 0) {
            $flag = 1;
        }

        //If the username already exists then alert the user, else insert the record to the db and send user to login.php
        if ($flag == 1){
            echo "<script>alert(\"Sorry, that username is already taken. Please choose another.\");</script>";
        }
        else {
            $sql = "INSERT INTO users (first, last, username, email, password, zip) VALUES ('".$first."', '".$last."', '".$username."', '".$email."', '".$password."', '".$zip."')";
            if ($db->query($sql) === TRUE) {
                //echo "Registration successful";
                //$filename = "/profiles/".$username.".php";
                //chmod($filename,0777);
                echo 'Current script owner: ' . get_current_user() . "<br>";
                echo 'posix: '.posix_getuid()."<br>";
                echo getcwd()."<br>";
                $last_line = system('whoami', $retval);
                echo $last_line . " " . $retval;
                $file = fopen("profiles/test.txt", "w") or die("Unable to open file!");
                //$txt = "This is a user profile for ".$username;
                //fwrite($file, $txt);
                fclose($file);
                //header('Location: login.php');
            } else {
                echo "Registration error, please try again later.";
            }
        }
    }
    $db->close();
    ?>
</body>

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Retro
  • 113
  • 13
  • `/var/www` is a common choice for the default DocumentRoot with many web servers. See http://unix.stackexchange.com/questions/47436/why-is-the-root-directory-on-a-web-server-put-by-default-in-var-www. If it's not your DocumentRoot (or whatever nginx calls it), then substitute the path your system uses. (Sorry IDK the answer, just saw this question while reviewing edits.) – Peter Cordes Nov 02 '16 at 05:46
  • Couldn't the profile be part of the database? Did you mean to exclude the leading slash on the fopen? (/profiles/test.txt vs profiles.txt). phpinfo() may be helpful, check for open_basedir or safe_mode entries. – strobelight Nov 02 '16 at 12:26
  • Thank you both. Peter, I am not sure what to do with DocumentRoot even if I knew where nginx put it however I think it is /usr/share/nginx/wingd is the doc root but dont know what the means. The wingd folder is what is being displayed on the website though and contains my index.php and other associated files. Strobelight, yes the user profiles will be populated from the database. The idea was a user would sign up for the website and profile page would be generated. If I use /profiles/test.txt then that would be coming from root and seen as an absolute path correct? – Retro Nov 02 '16 at 15:39
  • [continued] When I do that, I do not get a permission error but the error then says that it could not locate the file, well, the path is /usr/share/nginx/wingd/profiles/.. and I have tried the absolute path as well and that did not work either. I get a permission error when I try absolute path. I will look into open_basedir. Have already verified that safe_mode is turned off. THANKS! – Retro Nov 02 '16 at 15:41

1 Answers1

0

So I am no longer going to try to implement my idea by creating potentially hundreds, thousands, etc.. of user profile files on my server but rather follow what seems to be convention now to just have one profile page that is then populated with data based on parameters. That parameter (like user id or username) could then be used in a pull from the database and voila, you dont have TONS of files and is much better also for security concerns. Thanks for all who took the time to read, and/or respond to this to help me. Hope this post will help other users with my same tech stack and initial design thoughts in the future.. Takeaway: Ask how to best solve the problem/idea rather than asking how to best fix the issue you are dealing with, with your current design/implementation idea.

See the following for a better explanation and code snippet: Generate Profile Page Upon Registration - PHP

Community
  • 1
  • 1
Retro
  • 113
  • 13