Приглашаем посетить
Database Manager
BASIC INFORMATION
Name: Selena Sol's Database Manager
Version: 5.0
Last Modified: 01-31-97
DESCRIPTION
This database manager script allows a database administrator (or anyone
who has been given password verified access) to manipulate a flatfile UNIX
database. The db admin can add to, modify and delete from the database
using a web-based interface. Further, the script supports multiple admins
because it incorporates lock file routines so that no-one can actually
manipulate the data file while someone else is manipulating it.
COPYRIGHT INFORMATION
This application was written by Selena Sol (selena@eff.org,
http://www.eff.org/~erict) and Gunther Birznieks
(birzniek@hlsun.redcross.org)having been inspired by countless other Perl
authors. Feel free to copy, cite, reference, sample, borrow, resell or
plagiarize the contents. However, if you don't mind, please let me know
where it goes so that I can at least watch and take part in the
development of the memes. Information wants to be free, support public
domain freware. Donations are appreciated and will be spent on further
upgrades and other public domain scripts.
Finally, PLEASE SEND WORKING URL's to selena@eff.org. I maintain a list
of implementations around the world.
SUPPORT
This script comes with no gaurentees or warranties. I am not a
programming professional. I am a web-hobbiest and my scripts are
continually evolving as I learn more. Don't expect the scripts to be
perfect.
Bug reports are greatly appreciated but installation support is
extremely discouraged. I have attempted to include as much information as
I could think of in this README and in the Customization and Installation
FAQ available at http://www.eff.org/~erict/Scripts/. And there is
always lively discussion in Selena Sol's Discussion Forum
(http://www.sidestreets.com/info/sssa/). Please try ALL available sources
of information BEFORE you email me. But if you must, make sure to include
the following bits of information (I may not respond to your email if you
do not answer ALL of the following questions):
1. What type of Web server are you running?
2. What type of Operating System is the Web server running on?
3. What is the "exact" error message from the Web?
4. What is the "exact" error message in your web server's error log?
5. What is the "exact" error message you receive when running the script
from the command line.
6. Are you running this script on an ISP? If so, what is the email
address of the Sysadmin there?
7. Are you using a virtual server setup? If so, what is the root path set
in your Web server's environment?
8. In which directory is the Perl interpreter located?
9. In which directory is sendmail located (if you are using a script which
demands use of sendmail)
Again, I MAY NOT ANSWER YOUR QUESTION unless you have answered all nine of
these questions.
BASIC INSTALLATION (DOWNLOADING THE SCRIPT)
It is recommended that you point your Web browser to "Selena Sol's Script
Archive" to get the latest version of this script. The Script Archive is
located at the following URL:
http://www.eff.org/~erict/Scripts/
From the "Script Archive" frontpage follow the hyperlinks to the detailed
page dedicated to this script. Then click on the hyperlink "Download the
scripts as a single tar file".
BASIC INSTALLATION (UNARCHIVING THE APPLICATION)
Tar is a UNIX command that allows you to create a single archive file
containing many files. Such archiving allows you to maintain directory
relationships and facilitates transferring complex programs with many
separate but integrated parts which must have their relationships
preserved. Tar has a motley of options which allow you to do archiving and
unarchiving in many ways. However, for the purpose of untarring this
application, the commands will be fairly simple.
Once you have downloaded the TAR file transfer it to an executable
directory on your web server and "untar" it. On UNIX systems, you may
type the following at the command line (in the same directory as the TAR
file itself):
tar xvfp web_store.tar
Tar will go through the archive file and separate out each individual
directory and file, expanding them into their appropriate places
underneath the current directory. The "xvfp" letters in the tar command
above are parameters that tell the program to extract the files and
directories out of the ".tar" file. Specifically, "x" tells tar to extract
the files. "v" tells tar to output information about the status of its
extraction while it is performing the work, "f" informs tar to use the
".tar" filename as the source of the files to be extracted, and "p" notes
that the original permissions hould be maintained. The reason the
"f" parameter has to be used is that tar, by default, archives files and
directories to a tape drive. Tar is actually short for "[T]ape [AR]chive".
(Note: If you are using a non-UNIX Operating System, you may
download a TAR/UNTAR program by pointing your Web browser
to http://www.shareware.com I suggest using "untar" as your
keyword when you search their inventory).
BASIC INSTALLATION (SETTING PERMISSIONS)
Untarring the files is only one part of the equation of installing the
application and getting it to actually run. Frequently, the Web
server needs to be given special permission to run your scripts and have
the scripts perform their job with the appropriate "rights".
The cardinal rule for setting up Web server software is that the server
should be given only minimal capabilities. This definitely rules out the
Web server running as the ROOT user (Super user on UNIX). More often than
not, it means the Web server is run as a user that has no rights to do
anything significant -- the user "nobody". By default, "nobody" usually
does not have permission to read any files in directories that you create.
However, when you download scripts, you need to make it so that the
scripts can be read and executed by the Web server software. In other
words, "nobody" has to be able to get to the files.
The magic command is
chmod [permission digit] filename
Thus, the following command gives everyone rights to read and execute, but
noone rights to write to the file hello.cgi.
chmod 555 hello.cgi
The actual value of the digit determines the permissions granted to that
area. Permissions consist of three numbers -- 4 for read, 2 for write, and
1 for execute access. By adding these numbers together, you form the
permissions that make up one digit. For example, 4 + 2 + 1 = 7 which
grants read, write, and execute permissions. 4 + 1 = 5 which only grants
read and execute permissions. Thus, 755 grants 7 (read, write, execute) to
the owner of the file, and 5 (read and execute) to the group the file is
in and the world. Below is a chart which will can be used as a quick
reference
PERMISSION COMMAND
U G W
rwx rwx rwx chmod 777 filename
rwx rwx r-x chmod 775 filename
rwx r-x r-x chmod 755 filename
rw- rw- r-- chmod 664 filename
rw- r-- r-- chmod 644 filename
U = User
G = Group
W = World
r = Readable
w = writable
x = executable
- = no permission
[WARNING] You may be tempted to simply use chmod 777 on all the files and
directories since that assures the Web server can do anything with the
files. However, it is strongly advised that you do not leave the files in
this state. It is considered a big security risk to leave your scripts
open to changes by the Web server instead of being read-only. Anyone on
the server could use another rogue CGI script to write over your scripts
and make them do something completely different. There is still a risk
involved in making the messages directory writable, but at least if
someone is going to be messing with your area, they will only destroy a
bit of data and not your main programs. It is "OK" to set the scripts to
777 if you are troubleshooting a problem and want to rule out permissions
entirely, but do not leave the scripts like this. On another security
note, if you are really concerned with the security of your data such as,
please do not use a shared server where other people can write CGI scripts
using the same Web server configuration. It is much better to use your
own server software or purchase space on a "virtual server" which may be
shared, but is set up in such a way that each user's scripts are shielded
from each other.
Note: Not setting your permissions correctly is the
NUMBER 1 reason why installations fail. Take time to
get this right.
The actual permissions required for the subdirectories and files used by
this application are listed in the next section.
BASIC INSTALLATION (FILES, DIRECTORIES, AND PERMISSIONS)
The TAR file will then expand into a root directory called
Database_manager. Database_manager will contain several sub-directories
and several files. The diagram below depicts the directory structure as
well as the permissions which must be applied to the files and
subdirectories used by the application.
Database_manager Root Directory (drwxr-xr-x)
|____Data_files Subdirectory(drwxrwxrwx)
| |____address_book.counter (-rw-rw-rw-)
| |____address_book.data (-rw-rw-rw-)
| |____address_book.log (-rw-rw-rw-)
|____Library Subdirectory (drwxr-xr-x)
| |____auth-extra-html.pl (-rw-r--r--)
| |____auth-extra-lib.pl (-rw-r--r--)
| |____auth-lib-fail-html.pl (-rw-r--r--)
| |____auth-lib.pl (-rw-r--r--)
| |____auth-server-lib.pl (-rw-r--r--)
| |____auth_fail_html.pl (-rw-r--r--)
| |____cgi-lib.pl (-rw-r--r--)
| |____db-lib.pl (-rw-r--r--)
| |____mail-lib.pl (-rw-r--r--)
|____Session_files Subdirectory (drwxrwxrwx)
|____Setup_files Subdirectory (drwxr-xr-x)
| |____address_book.log (-rw-rw-rw-)
|____Users Subdirectory (drwxrwxrwx)
| |____default.users (-rw-rw-rw-)
|____db_manager.cgi (-rwxr-xr-x)
Database_manager is the root directory of this application. It must have
its permissions set to be readable and executable by the web server.
Datafiles is a subdirectory containing all of the files relevant for the
management of data files. The directory itself must be readable,
writable, and executable and contains three types of files:
counters, datafiles, and log files. Each of these files must
be readable and writable to the web server. For the
distribution, we've included address_book example.
By default, the counter should begin at one and will be
automatically incremented by the application itself. The only
thing you may need to do is manually increment the counter if you
add rows directly to the datafile without using the script.
Every data file is simply a pipe (|) delimited database using a
newline to represent a new database row. For example, the first
line might read:
1234|Bic Ball Point Pen|1.45|1
As you can see, every database field is separated by the pipe
symbol (which means that the pipe symbol may not appear in your
data!). In this example, field one is the item number, field two
is the item name, field three is the price, and field four is the
unique database id number.
Every database row MUST have a unique database id number, so if
you want to add database rows manually, you must make sure to add
this final field carefully (as we just said above).
Comment lines are acceptable within the data file, but they must
be specified using the comment tag "COMMENT:" flush against the
left margin. The first line of video.data uses a comment line to
describe the database fields as follows:
COMMENT: Category|Item #|Name|Description|Size|Price|URL|Link...
Log files can be made to show anything you want. BY default they
tell you who added, modified and deleted and what changes they
made to the data file.
Library is a subdirectory containing various supporting files used by the
application. The directory must be redable and executable by the
web server and each library file within must be readable.
cgi-lib.pl is used to read and parse form input.
cgi-lib.sol is used to lock the data file when it is being
manipulated.
db-lib.pl is used to search through the datafile according to the
criteria entered by the user.
all libraries beginning with "auth" are used for authentication
mail-lib.pl is used with authentication to mail new registrants.
Session_files is a subdirectory used to hold authentication session files
created by the auth libraries. This directory must be readable,
writable and executable and will automatically fill up and prune
itself in the daily usage of the script.
Setup_files is a subdirectory containing the setup files which describe
server specific variables and database specific variables. The
subdirectory must be readable and executable by the web server and
the setup files within the directory must be readable by the web
server. By default, we have included one sample setup file called
address_book.setup. Below is a short description of the variables
and their meanings.
%db defines the the structure of your datafile. It is an
associative array which matches up the
variable names which you will use to access data files
with the actual numerical index of that field. Remember
that arrays start counting at zero.
$index_of_db_id_number is the numerical index of the unique
database id number so that the script will be able to figure out
which database rows are being modified.
$index_of_who_modified is the numerical index of the field in
which the session_username is stored while
$index_of_group_who_modified is the same for session_group. The
script needs to know this in order to pass the user through
authentication.
$index_of_modification_time is the numerical index of the field
in which the date of modificaiton is stored The script must know
this if it is to make date comparisons.
$index_for_email is the numberical index of email in case you want
to make it a hyperlink.
$index_of_field_to_be_sorted_by defines which field we should sort
the database by default. This index corresponds to %db and can be
overridden by a form variable called sort_by.
@db_user_definable_field_order is an array of the elements of %db
which the user will be able to submit info for on the add and
modify forms.
@db_display_fields are the headers of the fields that you wish to
display to the user when they receive the search results.
You do not have to display all the fields you defined in
%db, but you must have one element in @db_display_fields
for every element in @db_index_for_display
@db_index_for_display is the index into %db of the fields that you
want displayed when the user get a search results page.
This corresponds to @db_display_fields
@db_query_criteria defines how each database field will be
searched. The specifics of how to use @db_query_criteria
are discussed in db-lib.pl
The array contains pipe-delimited fields inside each
list item. The fields are the
1. form variable name
2. index into the database that this criteria applies to
3. operator for comparison
Possible values: >,<,>=,<=,=,!= (not equal)
The operator is compared the following way:
form_variable OPERATOR database_field_value
That is, (1) above is the left hand side of the
operator and (2) above is the right hand side of
the operator.
4. data type of the field (This is cool because it
determines how the operator in (3) gets
applied to the data.
The data type can be:
date
number
string
If the data type is a date, then the operator
for comparison is done after the form value
and the fields being compared in the database
are converted to DATES.
If the data type is a number, then the operator
for comparison is done based off of numerical
if operators (>,<,==, etc.)
If the data type is a string, then the operator
for comparison is done based off of string
if operators (gt, lt, eq, ne, etc.) with ONE
EXCEPTION.
If the datatype is a STRING *AND* the operator
is =, then the search that is done becomes a
more flexible search.
1. All the words in the form variable are split
apart and searched as seperate keywords in the
text of the fields.
2. By default, the search on string = string
is a pattern match search and is not case
sensitive.
3. If you want this special string,= combination
searching to be case sensitive and to match on
whole words only, you MUST set up two new form
variables: case_sensitive and exact_match
If exact_match is on (checkbox) then the
combination of string,= in the query criteria
array will match on WHOLE WORDS only.
If case_sensitive is on (checkbox) then the
combination of string,= in the query criteria
array must have matching case values (upper/lower).
There are three main cases that you generally want to set
up a query_criteria array for:
Case 1: General keyword search through the database.
(a) Set the first field equal to your keywords form variable
(eg keywords). You will need something like the follwoign in your
HTML page.
<INPUT TYPE = "text" NAME = "keywords" SIZE = "40"
MAXLENGTH = "40">
(b) Set the 2nd field equal to field numbers of the
database file you want to search. Since you are going to
do a keyword search through the whole database, you want
to comma-seperate these (eg 1,2,3,4,6 where database filed #5 is
not searched)
(c) operator is set to =, data type is set to string so
that the keyword search is done using pattern matching
and case insensitive.
@sc_db_query_criteria would be equal to
("keywords|1,2,3,4,6|=|string)
Case 2: Just want to do a search on a field like lname
and include that search term within URLs in a frontpage such
as web_store.cgi?lname=Smith.
(a) Set the form variable equal to the above (lname)
(b) set the 2nd field equal to the field in the database
corresponding to a lnamename (eg 1).
(c) set operator =, data type string to do a keyword
search that is case insensitive.
@sc_db_query_criteria would be equal to
("lname|1|=|string")
Case 3: You want to make a front page form where several
fields in the database are being searched.
You want to allow the user to search on an age
range, plus a keyword search on lname field.
Here is the setup:
@sc_db_query_criteria would be equal to
("age_low|9|<=|number",
"age_high|9|>=|number",
"lname|1|=|string");
Notice that we set up TWO form variables for allowing
the age range searching. This is because we allow the
user to enter the low range and the high range of the age
they want to search for (database field #9).
Note, also, that the "age_low|2|<=" means that
the database row returns a match if and only if the
value of "age_low" form field is <=- the value of
field #9 in the database row (remember counting starts at 0).
Then, we set the lname form variable to be a keyword
(=,string) search on database field #1.
The form itself would have these fields as HTML:
Lowest Age To Search For:
<INPUT TYPE=TEXT NAME=age_low VALUE="">
Highest Age To Search For:
<INPUT TYPE=TEXT NAME=age_high VALUE="">
Enter Last Name:
<INPUT TYPE=TEXT NAME=lname VALUE="">
SPECIAL NOTE: Only criteria that is entered on the form
is queried against. If the user leaves one or more fields blank
(or you neglect to place them on the form), then those fields
never get queried.
Of the criteria that IS entered on the form, all the criteria
must be satisfied for that row before the row will be considered
safe to display to the user.
The same goes for the string,= (special case for keywords).
When the string is split into keywords separated by whitespace,
all the keywords must be found in the database field before
the program will consider it a valid match.
This logic is there because we want to provide the capability
of letting the user narrow down the query as they enter more
data into the form.
$should_i_authenticate determines if you want authentication to be
used. If set to no, then anyone will be able to modify any row in the
database. If set to yes, only groupmembers, users or admins will
be able to mofify rows.
$auth_lib = location of the authentication library files. By
default, they are all located in the Library subdirectory and are
all prefixed with "auth" so that they are easily distinguishable
as a package.
$auth_server = are you using server based authentication with
access.conf type stuff? If so, set this to on in order to take
advantage of the excellent power of server-based authentication.
Typically though, you won't have server based authentication opn
because most people will not have access to those services on
their ISP. The benefit of using server based authentication is
that you can absolutely validate the user name against the server
authentication database.
$auth_cgi = If you are not using server based authentication, then
you must be using cgi based authentication with your own flatfile
user database. The distribution copy assumes this, so the
variable is set to "on".
$auth_user_file is the flatfile user database of validated admins.
By default, this file should be empty. When you are ready to add
yourself as an admin, you will do so and the script will
automatically add you as a validated admin to this file. You
should then expect to see something like the following line in
that file:
encrypted password|username|admin|fname|lname|you@yourdomain.com
$auth_alt_user_file is an extra security option. If alt_user_file
is defined, when a user registers, their information will be
stored in the alternate user file until the system admin (you)
copies them over. Normally, you will just let them register into
the main file however.
$auth_default_group - Since security for this type of script mainly
focusses on one user, I'd just leave this as admin and not worry
about it...I don't anticipate much need for groups and users. If
you did decide to incorporate different levels of security into
the script, you would have to write your own logic into the main
script anyway.
$auth_add_register gives the script the ability to add new users
"directly" to the database. $auth_allow_register determines
whether or not the authentication frontscreen shows a registration
button, or just a logon button.
We recommend that you set both of these OFF unless you are adding
validated users...If not, someone could theoretically, make a
mirror form somewhere else and add themselves to the
database...these options disable the add function entirely until
the time when you actually want to do it.
Thus, by default, we have set both these variables to "off".
Therefore, the first time you try to run the administrative
functions you will hit a deadend. There will not be any validated
admins in the user file AND there will be no way for you to
register yourself as an admin.
What you'll have to do is change these two variables in the setup
file to "on". Then, you will call up the script from the web
with a URL something like the following:
http://www.you.com/cgi/Mailing_list/mailing_list.cgi?action=admin
At that point, you should now get the login screen, but this time you
should see an extra button, "Register for an Account". You
should click this button. Then, you will get the login screen.
Fill out the information and submit the data to the script. The
script will then encrypt your password, add you as an admin and
tell you that you may now log in as an administrator.
At this point it is time for you to go back into the setuyp file
and change both the variables back to "no" so that noone else can
add themselves as an admin.
$auth_email_register determines if this script should mail the admin a
note when someone registers...I would leave this on so that you
have a double check that no one uninvited can use the admin
interface.
$auth_admin_from_address and $auth_admin_email_address help
mail-lib.pl send email notification on new registrations. If you
are having trouble with the mailing options, make sure you go into
mail-lib.pl and set the path to sendmail correctly. Also, if you
are using aliases, you need to remove the -t option.
$auth_session_length determines the number of days session files stay
around for. Session files are used to keep track of the
admin information while they are performing a mass mailing. The
script needs to be able to keep track of the admin from screen to
screen to make sure that she is validated. This info is kept in a
session file in the Session_files directroy. However, these files
are only needed "while" the admin is performing administratove
functions...which might only be 5 minutes. Thus, the scriopt
automatically deltes these files when they are no longer needed at
some time interval defined by you.
$auth_session_dir is the location of the session file directory.
$auth_register_message is the mesage that you will receive after
you have registered.
$auth_allow_search determines whether or not the search button will
appear on the registration screen...since you will have direct
access to the user file, you don't need this option at all.
Typically, it is used so that new registrants can search the user
file for usernames so that they will not pick one already in use.
$auth_generate_password if set to "on", directs the script
to generate a password for you. Leave it off if you want to
generate your own.
$auth_check_duplicates checks to make sure no one has already
used your username that you submit when creating a new validated
user. It is best to leave this "on", but there shouldn't be
so many valid users that you'd forget.
$auth_password_message is the message that is sent to the user
with their password if $auth_generate_password is set to on.
@auth_extra_fields and @auth_extra_desc are arrays used to keep track
of information in the user file besides username and password.
Leave this the way it is unless you really need to collect data on
admins.
$data_file_path is the location of the data file which will be
searched
$max_rows_returned is the maximum number of rows which will be
returned at one time. If the users search criteria turn
up more than that they will not be displayed
$current_century is the current century.
$this_script_url is the url of this script!
$location_of_counter_file, $location_of_log_file and
$location_of_lock_file are the locations of those files respectively.
SUBROUTINES IN THE SETUP FILE
Be aware that all of these subroutines take advantage of
the qq method of printing such that the print delimiter is
changed to a tilde (~) instead of a quoite ("). This is done so
that it is easier to display HTML tags which use quotes
themselves. Otherwise we would have to backslash all quote marks
the same way we backslash at signs (@). Of course, all tildes
must be escaped with backslashes aasd a result, but tildes are
less common in HTML code.
generic_header is responsible for printing out a basic HTML
header. It is called with one parameter as follows:
&generic_header("[TITLE TO USE]");
The parameter is the text you want to appear between the <TITLE>
and </TITLE> tags. Thus, the following call:
would produce the following HTML
<HTML>
<HEAD>
<TITLE>Example</TITLE>
<BODY BGCOLOR = "FFFFFF" TEXT = "000000">
You can of course change the value of the background by editing
the HTML code in the routine.
generic_form_footer takes no arguments and when called like
&generic_form_footer;
will produce the following HTML:
</FORM>
</BODY>
</HTML>
display_frontpage will simply display the frontpage that you want
users to get when they first pass through authentication. By
default, there are submit buttons for each of the types of db
manager functions.
add_modify_data_entry_form will output the form on which the user
can input data for adds or modifications. These fields MUST
correspond to the elements of @db_user_definable_field_order
modify_search_form displays the form which users can use to
specify the search parameters they will use to look for items to
modify. Most of the work is done by display_generic_search_form
which is discussed later. However, some modification specific
header and footer information is handled here.
delete_search_form and view_database_form do the same thing as
modify_search_form except for the delete and view cases of searching.
display_generic_search_form does most of the work for the above
three cases. This subroutine displays a generic form on which
the user can specify search criteria with which the database
should use to generate a list of hits. The user can then choose
one of the hits to modify. The NAME arguments in the input fields
must correspond to elements in @db_query_criteria
search_results_body does a few things. First, it checks to see if
the search criteria submitted by the user turned up too many hits (and
warns them if so). It also presents the search results as a table of
database rows. However, it needs to handle the casaes of modify,
delete and view differently because each have slightly different
displays. For example, display and modify forms must have a
checkbox so that the user can select items to modify from the list
whereas, views are simply straight views with no selection.
Similarly, the checkboxes must have the item_ids of the row
associated with them as well as the NAME argunments so that the
scriopt will be able to process the submissions. Also, the
subroutine must make sure that it translates all ~p~ and ~nl~
into pipes and newlines for display. (recall that we cannot store
those raw characters in our database). Finally, the subroutine
must handle special fields like email or URL's.
search_results_footer displays the footer for the search resutls
page. for the most part, this is just displaying submit buttons
so that the user can submit their selected row and the changes.
However, in the case of modification, the routine displays the
add/modify form so that the user can re-enter some data as well as
aselect an item to modify.
no_hits_message displays the message in the case that no hits were
found based on the user-defined criteria.
search_and_display_db_for_view, search_and_display_for_deletion, and
search_and_display_for_modification all handle the header displays
for the search and display functions.
add_form_header displays the header for the add form.
successful_addition_message, successful_deletion_message and
successful_modification_message provide notes upon successful
modifications.
unsuccessful_modification_message provides a note telling the user
that the modification was unsuccessful.
no_item_submitted_for_modification provides the user with a note
exmplaioning that they did not select a row to modify.
Users is the subdirectory cotaining the authentication user files. The
directory must be readable, writable and executable to the web
server if you are going to be adding users. But, when you are not
adding users, it shouod be reset to readable and executable. The
user files inside should be readable and writable when you are
adding users, but otherwise should be just readable.
db_manager.cgi is the main script for the application. It must be redable
and executable by the web server.
RUNNING THE SCRIPT
To run the default script, simply point your browser to the main script
with a URL like the following:
http://www.foobar.com/cgi-bin/Database_manager/db_manager.cgi?setup_file=address_book.setup