Forum How do I...?

msg|wrn||failed to load external entity

MattD
Hi there,

I am having trouble getting prince to read from a network share on our test servers which have the same setup and code that works on our production servers. However they were created a year or two apart so there could well be subtle differences that we have missed.

The error PrinceXML gives us is:

:evil: msg|wrn||failed to load external entity

We are using:

:arrow: Windows Server 2003
:arrow: IIS 6.0
:arrow: PHP 5.2.6
:arrow: ZendCore 2.5.2
:arrow: PrinceXML 5.1


on all environments, the only real difference is that the production servers have PrinceXML licences and the test servers are using the default demo licence with the watermaked page.

In our setup PHP generates the prince command line string with all the necessary parameters, input and output files to generate a PDF using the prince php class. Using this PrinceXML reads the specified files from a windows network share, processes and creates the specified PDF which is written back to the same network share.

We can run this setup without issue and the PDF is created successfully on our production environment and with PrinceXML directly, logged in as the named IIS User (a domain account), with the string generated by the PHP code. However when we use the PHP Prince class (which uses proc_open) we get the message saying that it "failed to load external entity" on the first source file and no PDF is generated.

The Windows network share is setup with the same permissions as our production environment and the named IIS user has permissions on CMD.exe and prince.exe on the local machine, prince.exe is also in the path on that machine.

Does anyone have any ideas what could be causing this issue on our test environment but not our production environment?

Thanks in advance.

Matt.
mikeday
Are there any other error or warning messages being reported? Are the path names different on the failing server, eg. containing spaces or unusual characters that are not present on the working server?
MattD
Hi Michael,

The path names are different but only the IP address, and if I take the execution string that fails from PHP and run it direct on the command line it successfully creates a PDF with no errors.

The string being generated by PHP is:

prince.exe -i html --server -s "\\192.168.1.1\templates\genericpdf.css" -s "\\192.168.1.1\templates\main.css" -s "\\192.168.1.1\templates\print.css" "\\192.168.1.1\Documents\123456_document_0001.html" "\\192.168.1.1\Documents\123456_document_0001.pdf"


The Full Error returned is:

msg|wrn||failed to load external entity "\\192.168.1.1\Documents\123456_document_0001.html" msg|err|\\192.168.1.1\Documents\123456_document_0001.html|could not load input file fin|failure


PHP is being run as a domain user with full access to that network share, I have also tried setting the network share to be fully open to the everyone user with no change in result.

Many Thanks,

Matt
mikeday
That's perplexing, if the exact same version of Prince with the exact same command line arguments is working when invoked from the console and failing when invoked from PHP. Even stranger if it works on the other server. Does it work if you try converting a local document, rather than one on a network share?
MattD
Hi Michael,

Perplexing indeed (infact a few of us have been tearing the whole system apart for a couple of weeks now trying to find anything.)

Yes, I forgot to mention that we did do a test and move the whole lot onto a local drive and all worked fine.

Also interestingly in my investigations I have swapped out the generated prince command in PHP for a
whois

command, that informed me that the user that prince is actually running as is the Network Service user. This was unexpected, as I had thought that when using proc_open the command run would assume the identity of the user running the website in IIS. The same Network Service user is reported on the production environment also.

Thanks,

Matt.
mikeday
Is it possible to use RunAs or login as the Network Service user and then try running Prince from the command line? That would demonstrate whether this user does or doesn't have permissions to grab files from the network share.
MattD
Hi,

Just trying to test that, having trouble currently as I am not able to log in or run as that user - I will investigate this user further.

also I have just run (from proc_open through PHP):

dir \\192.168.1.1\Documents\ 


and got an

Access is denied


Which is interesting, as our fileshare is currently still set to allow everybody full access. And when logged in to the command line (not as the "Network Service" user) it executes correctly.

Regards,

Matt.
mikeday
That's definitely the issue then, but the question is how to set appropriate permissions. If the share is already wide open, perhaps the problem is on the client; could there be something about the Network Service user on that machine that stops it accessing the network?
MattD
Hi,

So, I have been continuing my investigations and have found out the following:

For some reason when PHP calls proc_open the process that it creates assumes the identity of the IIS application pool user (see below) instead of the one the user specifies in their website configuration.

Where to find the application pool user:

Internet Information Services (IIS) Manager -> "Your Server" -> Application Pools -> "Your Application Pool" -> Properties -> Identity -> Select a security account for this application pool


This defaults to the Network Service user, I have changed my test environment so that it uses the "Configurable" option to specify the same domain user as in my website configuration, this now allows PHP to run Prince under the desired account, PDFs are now being created.

You will also need to add the specified user to the "IIS_WPG" Group on the local machine if it is not already.

I am yet to find where the security rules are that govern the access granted to the Network Service user, but I think I may just apply the configurable identity setting to my production environment instead, as I then know I have absolute control over the account.

There is no obvious reason that I can think of why PHP does not call proc_open with the identity that PHP itself is using, maybe its a bug?

Thanks for your help Michael,

Regards,

Matt.

Edited by MattD

mikeday
Sounds like a good solution! Thanks for the detailed write-up, it's very helpful if anyone else runs into a similar issue.