Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Objective-C for CGI Question

Objective-C for CGI Question
Thread Tools
SSebeny
Junior Member
Join Date: Aug 1999
Location: Cuyahoga Falls, Ohio, USA
Status: Offline
Reply With Quote
Apr 8, 2006, 05:00 AM
 
Hi,

I'm competent in the basics of Objective-C & Cocoa, but I don't know anything about CGI or how those kind of dynamic web page generation programs work. So I thought I'd try making a little CGI tool using Objective-C.

For my first attempt I made a Foundation tool that gets the user's address book [ABAddressBook sharedAddressBook] and prints some data out like the count of people in the address book. When I run this tool from Xcode, or directly from the command line it works fine. But then when I move the tool to the /Library/WebServer/CGI-Executables/ directory and try and run it from the web browser it doesn't work. It prints out 0 people in address book, but thats just because its not actually getting the address book back from the call to sharedAddressBook.

Does anyone know why it works if I run it from the Terminal, but not if it is envoked through the web browser? Is there some type of security that prevents CGI programs from accessing data like the address book or something?!

Since that didn't work I tried a different approach. I took the example code from the Apple "Low-Level Core Data Tutorial" and modified it. Instead of having it store the persistent object store in the ~/Library I had it store it in /Library/Application Support/. Then I changed all the NSLog statements to printf statements and added the necessary "Content-Type:text/html;charset=iso-8859-1" at the beginning of the output. So after my modifications the program still ran fine from Xcode, or from the Terminal, but when moved to the cgi-bin directory and executed from a web browser it didn't work the same. At the point where it tried to write to the persistent store located in /Library it fails and produces this error: "The file could not be saved because the file name is invalid." Now the file name isn't really invalid, its the same file name because its the exact same executable running. The only difference is that it is evoked from the web browser.

Is this typical for cgi programming? Is it a security precaution, or am I doing something wrong? What is the work around to all of this? I mean, what would the correct techniques be? Do you have to put the repository some place different for the cgi program to access it, or what?

Any help is appreciated. Thanks!
( Last edited by SSebeny; Apr 8, 2006 at 05:15 AM. )
     
Amorya
Mac Elite
Join Date: Mar 2001
Location: England
Status: Offline
Reply With Quote
Apr 8, 2006, 08:52 AM
 
Originally Posted by SSebeny
Does anyone know why it works if I run it from the Terminal, but not if it is envoked through the web browser? Is there some type of security that prevents CGI programs from accessing data like the address book or something?!
At a guess, it's because the CGI is run as a different user (www or nobody or something) and as such that user does not have an address book.
What the nerd community most often fail to realize is that all features aren't equal. A well implemented and well integrated feature in a convenient interface is worth way more than the same feature implemented crappy, or accessed through a annoying interface.
     
Mithras
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status: Offline
Reply With Quote
Apr 8, 2006, 09:30 AM
 
Exactly. Change /etc/httpd/httpd.conf (or make a new copy) to have Apache run on a port > 1024 and as your user.
     
SSebeny  (op)
Junior Member
Join Date: Aug 1999
Location: Cuyahoga Falls, Ohio, USA
Status: Offline
Reply With Quote
Apr 8, 2006, 04:26 PM
 
Originally Posted by Mithras
Exactly. Change /etc/httpd/httpd.conf (or make a new copy) to have Apache run on a port > 1024 and as your user.
I just want to be sure that if I do that I'm not causing a big security hole or something. Am I? When any website has a dynamic CGI program that writes to a file like this do they all change the user that apache runs as? It would really surprize me if that was the case. If not, what do they do? Is there some other approach used? Do they just only write to files inside the webserver directory? That doesn't seem likely either because I'm sure I've seen examples of stuff in the past where it referred to a database or something and the database was outside the webserer directory. Or is maybe the approach used to create two programs - one that does the work and is outside the webserver directory, and another that is in the CGI directory and just calls the other. Would that work? When the CGI program calls out to run the other program would it still be running as the apache user? Or could I make it run as a different user that could actually do what I want to do. If so, would that be any better/safer than changing the user Apache runs as?
     
Mithras
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status: Offline
Reply With Quote
Apr 10, 2006, 11:09 PM
 
There are ways to work around the issues. The name of your problem is in general called interprocess communication. Popular tactics include:
* run Apache as the user you need to. In multi-user settings, this takes the form of suexec, which you can Google and read about.
* run a second instance of Apache (this was my suggestion of making a new copy of httpd.conf) that runs as SSebeny, but has a very limited DocumentRoot and capabilities. You can run another copy of Apache with a custom httpd.conf with httpd -f /path/to/custom/httpd.conf
* as you suggest, have one program that runs as SSebeny and does the work, and have it write to a file that is writeable by SSebeny and readable by the Apache user (www). Have Apache issue instructions to that program by writing to a file that is writeable by www and readable by SSebeny. For performance reasons, these files are usually FIFOs. (man fifo or man mkfifo to read about them).
* Or, run two programs, and have them communicate over a TCP socket. This is straightforward if you know your way around network programming, and a bit of a hassle if not.

Good luck!
     
   
Thread Tools
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 10:06 PM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,