CentOS 5中通过JSP表单创建Unix用户及脚本执行问题求助
Hey there! Let's break down your problem step by step—you already nailed the database part, so we just need to fix the script execution and figure out the Unix user creation flow.
command.sh Execution Since your data makes it to the database but the script bombs, let's start with the most common culprits:
- Permission Issues: The user running your JSP container (usually
tomcatorwww-dataon Unix) probably doesn't have the right permissions to executecommand.shor run the actions inside it. For example, creating Unix users requires root-level access. Try:- Checking if the script has execute permissions:
chmod +x /full/path/to/command.sh - Configuring
sudoto let your JSP user run the script without a password (more on this in the security section below)
- Checking if the script has execute permissions:
- Relative Path Pitfalls: If you're calling
command.shwithout a full path, your JSP container's working directory might not be where the script lives. Always use absolute paths like/opt/your-app/scripts/command.shinstead. - Capture Error Output: By default, Java's
Runtime.exec()orProcessBuildermight not show you the script's error messages. Modify your code to capture both stdout and stderr to see exactly what's breaking. For example:ProcessBuilder pb = new ProcessBuilder("/full/path/to/command.sh"); pb.redirectErrorStream(true); // Merge stderr into stdout Process p = pb.start(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = reader.readLine()) != null) { // Log this line to your server's logs (e.g., Tomcat's catalina.out) System.err.println("Script output: " + line); } int exitCode = p.waitFor(); if (exitCode != 0) { System.err.println("Script failed with exit code: " + exitCode); } - Test the Script Manually: Run
command.shdirectly as the JSP user (e.g.,sudo -u tomcat /full/path/to/command.sh) to see if it works outside of JSP. If it fails here, the problem is in the script itself, not the JSP code.
Once your script is executing correctly, here's how to use the form data to create a user:
Step 1: Safely Retrieve Form Data in JSP
First, grab the data from your POST request and validate it to avoid command injection attacks:
<% // Get form fields String username = request.getParameter("username"); String password = request.getParameter("password"); // Validate username (only allow alphanumeric, underscores; 3-16 chars) if (username == null || !username.matches("^[a-z0-9_]{3,16}$")) { out.println("Invalid username: must be 3-16 chars, only lowercase letters, numbers, and underscores"); return; } // Validate password (add your own rules here) if (password == null || password.length() < 8) { out.println("Password must be at least 8 characters long"); return; } %>
Step 2: Pass Data to Your Script
Modify your command.sh to accept the username and password as arguments, then call it from JSP with those values:
Updated command.sh:
#!/bin/bash set -e # Exit on any error USERNAME="$1" PASSWORD="$2" # Create user with home directory and bash shell useradd -m -s /bin/bash "$USERNAME" # Set password securely (avoids exposing password in process lists) echo "$USERNAME:$PASSWORD" | chpasswd # Optional: Add user to a specific group # usermod -aG your-group "$USERNAME" echo "User $USERNAME created successfully"
JSP Code to Call the Script:
<% // Build the process with arguments ProcessBuilder pb = new ProcessBuilder("/full/path/to/command.sh", username, password); pb.redirectErrorStream(true); Process p = pb.start(); // Read output and log BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; StringBuilder output = new StringBuilder(); while ((line = reader.readLine()) != null) { output.append(line).append("\n"); System.out.println(line); } int exitCode = p.waitFor(); if (exitCode == 0) { out.println("User created successfully!"); } else { out.println("Failed to create user. Error: " + output.toString()); } %>
Executing system commands from JSP is risky—don't skip these steps:
- Restrict Sudo Access: Instead of running your JSP container as root, add a sudo rule to let it run only your script. Edit
/etc/sudoers(usevisudoto avoid syntax errors) and add:
Then call the script withtomcat ALL=(ALL) NOPASSWD: /full/path/to/command.shsudoin your JSP:new ProcessBuilder("sudo", "/full/path/to/command.sh", username, password) - Sanitize Input: We added basic validation, but you can go further—reject any characters that aren't allowed in Unix usernames (no spaces, special chars like
;,|,&). - Avoid Plaintext Passwords: If possible, use a more secure method to set passwords (e.g., generate a hash instead of passing plaintext, or use
passwd --stdinif your system supports it).
内容的提问来源于stack exchange,提问作者Marcelo Marcillo Mieles

