I have a PHP application that makes changes to the active directory. Now i have a powershell script, look below ($username is passed through via php):
Disable-ADAccount -Identity $username
If I run that script via command prompt, boom it works fine. However if I run it through PHP (cgi), it does not work and the change is not made, also no errors in the browser.
So after alot of trial and error, i found that READING from the active directory works fine with php, such as this script:
Get-ADUser $username -Properties GivenName
However WRITTING to the active directory, such as the first script mentioned does not work.
I managed to look in the Apache logs and found this useful piece of information:
Disable-ADAccount : Insufficient access rights to perform the operation
At C:\scripts\lock.ps1:4 char:1
+ Disable-ADAccount -Identity $username
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (12PotterH:ADAccount) [Disable-ADA
ccount], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8344,Microsoft.ActiveDirec
tory.Management.Commands.DisableADAccount
How can I overcome this?
Things to note:
- I am running windows server 2012
I have given full permissions to php-cgi,powershell,cmd,xampp folder
I am using xampp (apache)
The actual active directory is on ANOTHER local server then the one running xampp
I have also tried adding the server parameter to the script like so:
Disable-ADAccount -Identity $username - Server SERVERNAME
If you don't specify credentials in the powershell cmdlets, then it is likely attempting to run the scripts as the application pool identity on the server hosting the php site.
The correct way to work around this would be to specify credentials in the powershell scripts. Most AD cmdlets have a -credential parameter you can use.
Here is an example:
$Username = 'domain\username'
$Password = 'Password123'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Get-ADUser $SamAccountName -Credential $Cred
Edit: version using credentials provided in plaintext
To add to what someone else said, if your application is going to be running these operations, you might consider using a credential file. It wouldn't be terribly secure, but I don't know how secure storing the credentials in the application would be, either. Credential objects that have been exported to a file are really useful.
One other option would be ensuring that the service / app. pool account has the appropriate access in Active Directory. If it's going to be doing things like this, I'd highly recommend making sure that it is a different account than the rest of the app pool identities, and is probably separated from other sites, too.
Related
I've tried to include as much info in this post as possible.
I'm using Postfix on an Amazon EC2 Ubuntu server and it seems that a PHP script I have aliased to an address isn't firing. Mailing works fine but the script just isn't firing. I've probably missed something easy and would appreciate any other ideas with this.
The code below is that of the script. At the moment it is just a basic script to write to a file the contents of php://stdin. I'm not sure if this is the best way to write this script but it seems to be ok for now as it's just a temporary one to use for troubleshooting this problem.
#!/usr/bin/php -q
<?php
$data = '';
$fileName = "parsedData.txt";
$stdin = fopen('php://stdin', 'r');
$fh = fopen($fileName, 'w');
while(!feof($stdin))
{
$data .= fgets($stdin, 8192);
}
fwrite($fh, $data);
fclose($stdin);
fclose($fh);
?>
I have verified this works by passing it a .txt file containing some text.
./test2.php < data.txt
Now that my PHP script seems to work fine locally, I need to make sure it is being called correctly. sudo chmod 777 has been run on the test2.php script. Here is the relevant /etc/aliases file entry.
test: "|/usr/bin/php -q /var/test/php/test2.php"
I run newaliases every time I change this. This seems to be the most correct syntax as it specifies the location of php fully. test#mydomain receives emails fine from both internal and external when it is not set to be aliased. According to syslog this is successfully delivered to the command rather than maildir.
postfix/local[2117]: 022AB407CC: to=<test#mydomain.com>, relay=local, delay=0.5, delays=0.43/0.02/0/0.05, dsn=2.0.0, status=sent **(delivered to command: /usr/bin/php -q /var/test/php/test2.php)**
The alias has also been written in the following ways without success (either because they go to maildir instead of the command due to wrong syntax or the script just isn't firing).
test: |"php -q /var/test/php/test2.php"
test: "|php -q /var/test/php/test2.php"
test: |"/usr/bin/php -q /var/test/php/test2.php"
test: "| php -q /var/test/php/test2.php"
test: "|/var/test/php/test2.php"
test: |"/var/test/php/test2.php"
The relevent part of my postfix main.cf files looks like this -
myhostname = domainnamehere.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = domainnamehere.com, internalawsiphere, localhostinternalaws, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command =
home_mailbox = Maildir/
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
I had error_log("script has started!"); at the beginning of test2.php so that it would appear in the php log file if the script was successfully being called. I made sure to go into the php.ini to turn on error_logging and specify a location for it to save to but I couldn't get this to work. It would help to be able to get this to work because I could tell if the script was failing when it go to the php://stdin function as there may be some problem with it handling emails rather than cat'ed .txt files.
My end goal is to get a service that will save emails on a certain addresss, with their attachments, to a MySQL database and then return a unique code for each file/email to the user. Is there an easier way to do something like this than use php scripts? does something like squirrelmail or dbmail do this?
I've completely exhausted my ideas with this one. Maybe I should just try another email service?
Oh wise people of StackOverflow, help me!
First things first, chmod 777 <foo> is almost always a gigantic mistake. I recognize that you're in a state of desperation -- as indicated by the fact that you ran this command. You want to configure your systems with the least amount of required privilege for each portion of the system to properly do its job. This helps prevent security breaches and reduces needless coupling. But executable files should not be writable by anyone except the executable owner -- and even then, I strongly recommend against it.
Now, onto your problem:
#!/usr/bin/php -q
<?php
$data = '';
$fileName = "parsedData.txt";
You're referring to a file using a relative pathname. This is fine, if you're always confident of the directory in which it starts, or if you want the user to be in control of the directory in which it starts, but it is usually a bad idea for automated tools. The /etc/aliases mechanism may run the aliased commands in the postfix home directory, it might pick an empty directory in /var created just for the purpose, and future releases are more or less free to change this behavior as they wish. Change this path name to an absolute pathname showing exactly where you would like this file to be created -- or insert an explicit chdir() call at the start of your script to change directories to exactly where you want your data to go.
Next:
$fh = fopen($fileName, 'w');
while(!feof($stdin))
{
$data .= fgets($stdin, 8192);
}
fwrite($fh, $data);
You did not ensure that the file was actually opened. Check those return values. They will report failure for you very quickly, helping you find bugs in your code or local misconfigurations. I do not know PHP well enough to tell you the equivalent of the perror(3) function that will tell you exectly what failed, but it surely can't be too difficult to get a human-readable error code out of the interpreter. Do not neglect the error codes -- knowing the difference between Permission Denied vs File or directory not found can save hours once your code is deployed.
And, as Michael points out, a mandatory access control tool can prevent an application from writing in specific locations. The "default" MAC tool on Ubuntu is AppArmor, but SELinux, TOMOYO, or SMACK are all excellent choices. Run dmesg and look in /var/log/audit/audit.log to see if there are any policy violations. If there are, the steps to take to fix the problem vary based on which MAC system you're using. Since you're on Ubuntu, AppArmor is most likely; run aa-status to get a quick overview of the services that are confined on your system, and aa-logprof should prompt you to modify policy as necessary. (Don't blindly say "Allow", either -- perhaps active exploit attempts have been denied.)
(If you aren't using a MAC system already, please consider doing so. I've worked on the AppArmor project for twelve years and wouldn't consider not confining all applications that communicate over the network -- but that's my own security needs. More paranoid people may wish to confine more of their systems, less paranoid people may wish to confine less of their systems.)
I'm using php 5.2 with IIS7.5.
I have a network share on a NAS that is username and password protected. I cannot disable or change authentication info on the NAS. I need to be able to access that network share via php.
I've done the following:
Created new user in windows whose username and password matches those on the NAS.
Created IIS application pool that uses this same auth info.
Created a web.config file inside of the php app directory with an impersonation turned on, using the same auth info.
identity impersonate="true" password="ThePass" userName="TheUser" />
Turned on ASP.NET impersonation in the application authentication in IIS.
None of this seemed to work with this simple line of code in php:
$dir = opendir("\\someservername\somesharename");
Warning: opendir(\someservername\somesharename) [function.opendir]: failed to open dir: No error in C:\websites\site\forum\testing.php on line 7
So, I decided to test the configuration with ASP.NET.
string[] diretories = System.IO.Directory.GetDirectories("\\someservername\somesharename");
The asp.net test worked perfectly.
Going further down the rabbit hole, I ran phpinfo() and checked the username info in it. Down in the "Environment" section of phpinfo, I found the "USERNAME" item. Its value was "TheUser," as was what I expected.
Everything points to the system being configured correctly until I tried:
echo get_current_user();
Which returned, "IUSR." That surely isn't what I expected.
So, how in the world do I get php + IIS7.5 to read from a foreign network share?
Update:
Thanks to a few of the answers, I've added
$result = shell_exec("net use o: \\\\pathToServer\\27301 /persistent:yes 2>&1");
Which returns a success. I'm still getting the error on opendir. I tried another test and used is_dir. This returned false on my newly created mapped drive.
var_dump(is_dir("o:\\"));
// Prints: bool(false)
UPDATE
I ran the script from the command line when logged in as the user that created. The scripts executes correctly. Could this take us back to get_current_user() which returns IUSR? I tryied getmypid() which returned a process ID. I cross referred that process id with the task manager and found that it was for php-cgi.exe, running under the custom user account that I made.
The recommended way to access a network share in PHP is to "mount" it. Try to connect your share as a network drive.
Btw. your command is wrong
$dir = opendir("\\someservername\somesharename");
You have to use 4 "\" because it's the escape character
$dir = opendir("\\\\someservername\somesharename");
NOTE: get_current_user() returns the owner of the process on IIS
You can try a test by mapping it like
$command = "net use $drive \"\\\\$ip\\$share\" $smb_password /user:$domain\\$smb_username";
$result = shell_exec($command);
on opendir you need to have \\\\$server_name\\$share try with 4 '\' and if mapping like that works and 4 '\' is failing on opendir. You may have credentials not matching.
If you map it this way new user you created in windows whose username and password matches those on the NAS will have rights on mapped drive that way you do not need to worry about the scope.
Had the same problem on a similar system. Solved this by going to web site > Authentication > Anonymous Authentication > Change IUSR to whatever your username is or use Application Pool user if correctly configured.
This is my first time using Capistrano and I am getting server authentication errors right at the start of my deploy:setup stage. I am a PHP user using rvm on a mac.
I noticed my deploy.rb file does not contain the password to my server. It only contains the password to my private git repo. Is there an attribute available for setting the server password so my connection could authenticate?
Do deploy.rb files list server credentials?
I'd like to refer you to a related discussion. Point in case: It's better to setup publickey authentication for your servers, it saves you from having your credentials stored in plain text and it is safer to begin with.
If you use github for your git hosting, you can use your publickey there as well. Be sure to use ssh_options[:forward_agent] = true to forward your publickey to the server when deploying.
If you really want to set your user and password, I believe you can do it as follows:
set :user, "sshuser"
set :password, "sshpassword"
set :scm_passphrase, "gitpassword"
More info can be found at github help/capistrano
The previous answer covers good info about deploy and i agree it is better to setup public keys.
But if you have password issues, try to add this line:
default_run_options[:pty] = true
to your deploy.rb file, so you allow Capistrano to prompt for passwords.
#Amit Erandole (in reply to [ip_address_omitted] (Net::SSH::AuthenticationFailed: root), app_name_ommitted (Errno::ETIMEDOUT: Operation timed out - connect(2)):
Looks like root access over ssh is not allowed on the server (and generally not recommended). Try it again with a valid user or turn root access on in sshd_config (PermitRootLogin yes).
But as was already mentioned by HectorMalot, create an ssh-key and forget about the passwords. ;)
$tmpUploadFolder = "C:\\www\\intranet\\uploads";
//$finalUploadFolder = "file:////server//photos//overwrite";
$finalUploadFolder = "file://server/photos/overwrite";
//$finalUploadFolder = "\\\\server\\photos\\overwrite";
//$finalUploadFolder = "\\server\photos\overwrite";
//$finalUploadFolder = "P:\\overwrite";
//$finalUploadFolder = "P:/overwrite";
$from = $tmpUploadFolder . "\\" . $_REQUEST['ext'];
$to = $finalUploadFolder. "\\" . $_REQUEST['ext'];
copy($from, $to);
I am trying to do a PHP upload using a jquery tool. The Jquery tool nicely places the file onto the PHP upload dir before the page submit. So i want to (upon post of the form) quickly move the file from it's tmp folder location (it'll already be there you see) to it's final destination on an image store server (I use the _REQUEST['ext'] variable to hold the filename jquery held.
Rest assured these paths are good they work lovely in dos. As you can see I have tried every known unc syntax I know.
I cannot for the life of me get php to work I have written a VBS "copy . file" and tried to trigger it under whost.exe via system() in php, i've downloaded the oldeskool runas.exe and tried to get it to copy via system(), I have used unc paths and network shares, and mapped network drives, I have made apache service "log on as " administraor and even a custom adhoc new user made just for this and given it full permissions
It works fine if I change P:\ to C:\
I KNOW IT'S EFECTIVE PERMISSONS RE: APACHE - BUT WE DO NOT RUN ACTIVE DIRECTORY AND I CAN'T GET IT TO WORK
it simply will not let me copy this file onto a network and this is a major major MAJOR problem child for me.
Is there a solution? If you are going to help me with things like "it's file permissions" then I am going to need a break down of exact and careful instructions because I am pulling my hair out because I know it's file permissions rights but I just can't get it to work
I am tired now.. please help?
ok I figured it out so for the benefit of those going after me here is the solution THAT WORKS
1.make sure php windows "apache2.2" service is running as a administrator user (I made a user called apacheusr and gave it a password and popped it into local administrators) you do this by right clicking properties on the "apache2.2" service in administrative tools->services and going to the logon tab->this account and picking the apacheusr
2.because I don't run active directory I made this apacheusr user on BOTH machines (phpserver/ imageserver) as a local administrator user and gave them BOTH the same username password and tick password never expires.
3.I then log in/out at least once onto windows with both these accounts. (don't ask me why but it seemed to help, it stopped the runasexe --that I gave up with-- moaning in dos)
4.finally on the php server right click share the destination folder on imageserver and make damn well sure this apacheusr can log in to that folder. The simplest way to do this is when you log/in/out as apacheusr on your php server and try to go to your image server folder - you then need to be on the imagesever and tick everything correctly in the share/permissions bit
THEN the final bit is (where _REQUEST['ext'] is a file name EG: "pic.jpg")
$tmpUploadFolder = "C:\\www\\intranet\\uploads";
$finalUploadFolder = "\\\\server\\photos\\overwrite";
$from = $tmpUploadFolder . "\\" . $_REQUEST['ext'];
$to = $finalUploadFolder. "\\" . $_REQUEST['ext'];
copy($from, $to);
The above code works!
In what environment do you run php? Apache? IIS? These run most of the time as a service with System Credentials and cannot access Network shares...
Change the Webserver Account to a User that can write and it should work (with one of those URLs at least)
within PHP (XAMPP) installed on a Windows XP Computer Im trying to read a dir which exists on a local network server. Im using is_dir() to check whether it is a dir that I can read.
In Windows Explorer I type \\\server\dir and that dir is being shown.
When I map a network drive a can access it with z:\dir as well.
In PHP I have that script:
<?php if( is_dir($dir){ echo 'success' } ) ?>
For $dir I tried:
/server/dir
//server/dir
\server\dir
\\server\dir
\\\\server\\dir
and
z:\dir
z:\\dir
z:/dir
z://dir
But I never get success?
Any idea?
thx
I solved it by changing some stuff in the registry of the server as explained in the last answer of this discussion:
http://bugs.php.net/bug.php?id=25805
Thanks to VolkerK and Gumbo anyway!
I love stackoverflow and their great people who help you so incredibly fast!!
EDIT (taken from php.net):
The service has limited access to network resources, such as shares
and pipes, because it has no credentials and must connect using a null
session. The following registry key contains the NullSessionPipes and
NullSessionShares values, which are used to specify the pipes and
shares to which null sessions may connect:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Alternatively, you could add the REG_DWORD value
RestrictNullSessAccess to the key and set it to 0 to allow all null
sessions to access all pipes and shares created on that machine.`
add RestrictNullSessAccess=0 to your registery.
You probably let xampp install apache as service and run the php scripts trough this apache. And the apache service (running as localsystem) is not allowed to access the network the way your user account is.
A service that runs in the context of the LocalSystem account inherits the security context of the SCM. The user SID is created from the SECURITY_LOCAL_SYSTEM_RID value. The account is not associated with any logged-on user account.
This has several implications:
...
* The service presents the computer's credentials to remote servers.
...
You can test this by starting the apache as console application (apache_start.bat in the xampp directory should do that) and run the script again. You can use both forward and backward slashes in the unc path. I'd suggest using //server/share since php doesn't care about / in string literals.
<?php
$uncpath = '//server/dir';
$dh = opendir($uncpath);
echo "<pre>\n";
var_dump($dh, error_get_last());
echo "\n</pre>";
Try the file: URI scheme:
file://server/dir
file:///Z:/dir
The begin is always file://. The next path segment is the server. If it’s on your local machine, leave it blank (see second example). See also File URIs in Windows.
Yes, I know this is an old post, but I still found it, and if anyone else does...
On Windows, with newer servers, verify the SMB is installed and enabled on the target machine.