This commit was manufactured by cvs2svn to create tag 'lam_0_4_7'.

This commit is contained in:
Roland Gruber 2004-12-18 15:17:28 +00:00
parent 87c5333b3b
commit 83dae838de
176 changed files with 0 additions and 51336 deletions

View File

@ -1,13 +0,0 @@
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
# [<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'

View File

@ -1,15 +0,0 @@
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list
# of files to check. A non-zero exit of the filter program will
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

View File

@ -1,14 +0,0 @@
# Set this to "no" if pserver shouldn't check system users/passwords
#SystemAuth=no
# Put CVS lock files in this directory rather than directly in the repository.
#LockDir=/var/lock/cvs
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no
# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
# history file, or a subset as needed (ie `TMAR' logs all write operations)
#LogHistory=TOFEWGCMAR

View File

@ -1,23 +0,0 @@
# This file affects handling of files based on their names.
#
# The -t/-f options allow one to treat directories of files
# as a single file, or to transform a file in other ways on
# its way in and out of CVS.
#
# The -m option specifies whether CVS attempts to merge files.
#
# The -k option specifies keyword expansion (e.g. -kb for binary).
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
# wildcard [option value][option value]...
#
# where option is one of
# -f from cvs filter value: path to filter
# -t to cvs filter value: path to filter
# -m update methodology value: MERGE or COPY
# -k expansion mode value: b, o, kkv, &c
#
# and value is a single-quote delimited value.
# For example:
#*.gif -k 'b'

View File

@ -1,21 +0,0 @@
# The "editinfo" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

View File

@ -1,29 +0,0 @@
# The "loginfo" file controls where "cvs commit" log information
# is sent. The first entry on a line is a regular expression which must match
# the directory that the change is being made to, relative to the
# $CVSROOT. If a match is found, then the remainder of the line is a filter
# program that should expect log information on its standard input.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name ALL appears as a regular expression it is always used
# in addition to the first matching regex or DEFAULT.
#
# You may specify a format string as part of the
# filter. The string is composed of a `%' followed
# by a single format character, or followed by a set of format
# characters surrounded by `{' and `}' as separators. The format
# characters are:
#
# s = file name
# V = old version number (pre-checkin)
# v = new version number (post-checkin)
#
# For example:
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
# or
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
#
# commit messages for lam-cvs
DEFAULT /cvsroot/sitedocs/CVSROOT/cvstools/syncmail %{sVv} lam-cvs@lists.sourceforge.net

View File

@ -1,26 +0,0 @@
# Three different line formats are valid:
# key -a aliases...
# key [options] directory
# key [options] directory files...
#
# Where "options" are composed of:
# -i prog Run "prog" on "cvs commit" from top-level of module.
# -o prog Run "prog" on "cvs checkout" of module.
# -e prog Run "prog" on "cvs export" of module.
# -t prog Run "prog" on "cvs rtag" of module.
# -u prog Run "prog" on "cvs update" of module.
# -d dir Place module in directory "dir" instead of module name.
# -l Top-level directory only -- do not recurse.
#
# NOTE: If you change any of the "Run" options above, you'll have to
# release and re-checkout any working directories of these modules.
#
# And "directory" is a path to a directory relative to $CVSROOT.
#
# The "-a" option specifies an alias. An alias is interpreted as if
# everything on the right of the "-a" had been typed on the command line.
#
# You can encode a module within a module by using the special '&'
# character to interpose another module into the current module. This
# can be useful for creating a module that consists of many directories
# spread out over the entire source repository.

View File

@ -1,12 +0,0 @@
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT. If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"

View File

@ -1,13 +0,0 @@
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

View File

@ -1,20 +0,0 @@
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4-> file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

View File

@ -1,21 +0,0 @@
# The "verifymsg" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

View File

@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,108 +0,0 @@
??? 0.5-alpha1
- new modular architecture
-> possibility to create Unix-only accounts
-> plugins for more objectClasses planned
-> enhanced PDF output
-> enhanced file upload
-> enhanced editor for account profiles
-> dynamic configuration options (based on modules)
- all pages in UTF-8
- added developer documentation
- PHPDoc formated comments
- fixed bugs:
fixed doctype of main frame
removed syntax check for LDAP suffixes
fixed IE bug at login
26.05.2004 0.4.6
- fixed bugs:
password hashes were not disabled correctly
street was copied to postal code on modify (938502)
underscore was not allowed for host names (934445)
deleting postal address or facsimile number failed (948616)
TLS error handling (958497)
smaller fixes on personal settings page
21.03.2004 0.4.5
- added French translation
- fixed bugs:
StatusMessages with additional variables did not work
Samba hosts had unnecessary objectClass shadowAccount (910084)
Samba host passwords were still wrong
LAM had problems with non-standard spelled object classes (907636)
Perl scripts did not work if Perl is not installed in /usr/bin/perl (913554)
problems when cn!=uid (915041)
home directories were not deleted by lamdaemon.pl (913552)
29.02.2004 0.4.4 (stable)
- fixed bugs:
plain posix groups could not be used as Samba 3 primary group
if magic_quotes_gpc in php.ini is was set to "Off", several pages did not work
some smaller bugs in mass upload
Samba hash values for hosts were not correct
Unix passwords could be disabled but not reenabled
fixed problem with eval() in status.inc (894433)
08.02.2004 0.4.3
- new login layout
- added Hungarian and Japanese translations
- fixed bugs:
Samba paswords were sometimes empty for new users (892272)
links in list views may not work with web servers other than Apache
21.01.2004 0.4.2
- added config wizard
- MHash is only needed for PHP < 4.3
- use Blowfish for encryption instead of MCrypt
29.12.2003 0.4.1
- better error handling at login
- support spaces in DNs
- PDF text for users
- create missing OUs recursivly
- fixed bugs:
SMD5 passwords were wrong
primaryGroupSID wrong if SID has no relation to Algorithmic RID Base
Samba 2 accounts could not be created
29.10.2003 0.4 (Beta1)
- improved design
- improved documentation
- Fixed possible error which could delete entries if objectclass didn't fit
- Fixed many samba 3.0 related bugs, most related to SIDs
- edit group members directly
- support for several password hashes (CRYPT/SHA/SSHA/MD5/SMD5/PLAIN)
- PDF output for groups and hosts
31.08.2003 0.3 (Alpha 3)
- Samba 3 support
- manage Samba 3 domains
- multiple configuration files
- PDF output
- better mass creation
04.07.2003 0.2 (Alpha 2)
- support for multiple OUs + OU-Editor
- account creation via file upload
- profile editor
- experimental Samba 3 support
- fixed a lot of bugs
23.05.2003 0.1 (Alpha 1)
Initial release

View File

@ -1,52 +0,0 @@
Installation Instructions for LAM
---------------------------------
1. Requirements
- Apache webserver (SSL optional) with installed PHP-Module (PHP-Module with
ldap, gettext, mcrypt+mhash optional)
- Perl (optional, needed only for lamdaemon)
- OpenLDAP (>2.0)
- A web browser :-)
MHash is only needed if you use PHP < 4.3 and want to use SHA or SSHA
for password hashes.
MCrypt will be used if available, otherwise Blowfish will be used
to store your LDAP password in the session file.
Getting mcrypt and mhash for Suse/RedHat:
Either you compile PHP4 yourself or you use some unofficial packages:
- Suse: ftp://ftp.suse.com/pub/people/poeml/mod_php4
- RedHat: http://ftp.horde.org/pub/RPMS
2. Installation
* Extract package with:
tar xzf ldap-account-manager_<version>.tar.gz
* Copy files into the html-file scope of the webserver. For example
/apache/htdocs.
* Set appropriate file permissions:
- lam/sess: write permission for apache user
- lam/tmp: write permission for apache user
- lam/config (with subdirectories): write permission for apache user
- lam/lib: lamdaemon.pl must be set executable (See also
docs/readme.lamdeamon.txt)
* Configure config.cfg and create a configuration profile.
Copy config.cfg_sample to config.cfg and set the master password and default
profile.
- With web browser:
Follow the link "Configuration Login" from the start page (lam/index.html).
(The default password to edit the options is "lam")
- Manually:
A default config file can be found in /lam/config/lam.conf_sample.
Change the necessary entries and rename it to /lam/config/lam.conf.

View File

@ -1,81 +0,0 @@
LAM - Readme
============
A set of PHP-scripts to administrate Unix and Samba accounts in a LDAP server.
LAM runs on any webserver with PHP4 support and connects to your LDAP server
unencrypted or via SSL.
The application manages accounts for users, groups and Samba hosts in
multiple organizational units. LAM supports the Samba 2.x schema and the
Samba 3 schema.
http://sourceforge.net/projects/lam/
Copyright (C) 2003 - 2004 Michael Duergner <michael@duergner.com>
Roland Gruber <post@rolandgruber.de>
Tilo Lutz <tilolutz@gmx.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Requirements:
PHP4
Openldap (2.0 or greater)
A web-browser that supports CSS (Netscape 4.x is not recommended)
Summary:
With LAM you can easily manage user, group and machine accounts stored in
a LDAP server over a web interface. At the moment it supports:
- displaying the user/group/host/domain entries
- deleting entries
- adding new entries
- editing entries
- filtering and sorting
- account profiles
- access management
- multiple configuration profiles
- OU Editor
- account creation via file upload
- Samba 2 and 3 schema support
Important:
The standard password to edit the configuration options is "lam".
Download:
You can get the newest version at http://sourceforge.net/projects/lam/
Installation:
Please see the INSTALL file.
Documentation:
Basic documentation is available in the directory "docs".
Internationalization:
If you want to use a translated version of LAM be sure to install the
needed locales. See locale/ for a list of supported locales and languages.
Debian users can add locales with "dpkg-reconfigure locales".
Security:
It is strongly recommended to use a SSL connection to your web server.
LAM needs to store your LDAP username + password in the session. The session
files are saved in sess/ and are accessible only by the web server. To increase
security username and password are encrypted with MCrypt/AES or Blowfish.
The key and IV are generated at random when you log in. They are stored in two
cookies.
Have fun!
The LAM devel team

View File

@ -1,9 +0,0 @@
stable
???
0.5
- check security
- module structure

View File

@ -1,4 +0,0 @@
<Files ~ *>
Order allow,deny
Deny from all
</Files>

View File

@ -1,5 +0,0 @@
# password to add/delete/rename configuration profiles
password: lam
# default profile, without ".conf"
default: lam

View File

@ -1,76 +0,0 @@
# LDAP Account Manager configuration
# server address (e.g. ldap://localhost:389 or ldaps://localhost:636)
serverURL: ldap://localhost:389
# list of users who are allowed to use LDAP Account Manager
# names have to be seperated by semicolons
# e.g. admins: cn=admin,dc=yourdomain,dc=org;cn=root,dc=yourdomain,dc=org
admins: cn=Manager,dc=my-domain,dc=com
# password to change these preferences via webfrontend
passwd: lam
# suffix of users
# e.g. ou=People,dc=yourdomain,dc=org
usersuffix: ou=people,dc=my-domain,dc=com
# suffix of groups
# e.g. ou=Groups,dc=yourdomain,dc=org
groupsuffix: ou=groups,dc=my-domain,dc=com
# suffix of Samba hosts
# e.g. ou=machines,dc=yourdomain,dc=org
hostsuffix: ou=machines,dc=my-domain,dc=com
# suffix of Samba 3 domains
# e.g. ou=domains,dc=yourdomain,dc=org
domainsuffix: ou=domains,dc=my-domain,dc=com
# list of attributes to show in user list
# entries can either be predefined values (e.g. '#cn' or '#uid')
# or individual ones (e.g. 'uid:User ID' or 'host:Host Name')
# values have to be seperated by semicolons
userlistAttributes: #uid;#givenName;#sn;#uidNumber;#gidNumber
# list of attributes to show in group list
# entries can either be predefined values (e.g. '#cn' or '#gidNumber')
# or individual ones (e.g. 'cn:Group Name')
# values have to be seperated by semicolons
grouplistAttributes: #cn;#gidNumber;#memberUID;#description
# list of attributes to show in host list
# entries can either be predefined values (e.g. '#cn' or '#uid')
# or individual ones (e.g. 'cn:Host Name')
# values have to be seperated by semicolons
hostlistAttributes: #cn;#description;#uidNumber;#gidNumber
# maximum number of rows to show in user/group/host lists
maxlistentries: 30
# default language (a line from config/language)
defaultLanguage: en_GB:UTF-8:English (Britain)
# Path to external Script
scriptPath:
# Server of external Script
scriptServer:
# Number of minutes LAM caches LDAP searches.
cachetimeout: 5
# Password hash algorithm (CRYPT/MD5/SMD5/SHA/SSHA/PLAIN).
pwdhash: SSHA
# Module settings
modules: posixAccount_minUID: 10000
modules: posixAccount_maxUID: 30000
modules: posixAccount_minMachine: 50000
modules: posixAccount_maxMachine: 60000
modules: posixGroup_minGID: 10000
modules: posixGroup_maxGID: 20000
modules: posixGroup_pwdHash: SSHA
modules: posixAccount_pwdHash: SSHA

View File

@ -1,24 +0,0 @@
# LDAP Account Manager language configuration file
#
# Do not modify!
# Each line consists of a ":"-seperated entry. The first part is the locale name,
# the second is the character encoding and the third the language name.
# English
en_GB.utf8:UTF-8:English (Great Britain)
# Spanish
es_ES.utf8:UTF-8:Spanish (Spain)
# French
fr_FR.utf8:UTF-8:Français (France)
# German
de_DE.utf8:UTF-8:Deutsch (Deutschland)
# Hungarian
hu_HU.utf8:UTF-8:Magyar (Magyarorszag)
# Japanese
ja_JP.utf8:UTF-8:日本語 (日本)

View File

@ -1,57 +0,0 @@
<settings type="pdf">
<pdf type="user">
<text name="user" />
<section name="Personal User Infos">
<entry name="inetOrgPerson_title" />
<entry name="inetOrgPerson_givenName" />
<entry name="inetOrgPerson_sn" />
<entry name="inetOrgPerson_street" />
<entry name="inetOrgPerson_postalCode" />
<entry name="inetOrgPerson_postalAddress" />
<entry name="inetOrgPerson_mail" />
<entry name="inetOrgPerson_telephoneNumber" />
<entry name="inetOrgPerson_mobileTelephoneNumber" />
<entry name="inetOrgPerson_facsimileTelephoneNumber" />
</section>
<section name="Unix User Settings">
<entry name="posixAccount_uid" />
<entry name="posixAccount_userPassword" />
<entry name="posixAccount_primaryGroup" />
<entry name="posixAccount_additionalGroups" />
<entry name="posixAccount_homeDirectory" />
<entry name="posixAccount_loginShell" />
<entry name="shadowAccount_shadowExpire" />
<entry name="inetOrgPerson_host" />
</section>
<section name="Windows User Settings">
<entry name="sambaAccount_uid" />
<entry name="sambaAccount_password" />
<entry name="sambaAccount_homeDrive" />
<entry name="sambaAccount_scriptPath" />
<entry name="sambaAccount_smbHome" />
<entry name="sambaAccount_userWorkstations" />
<entry name="sambaAccount_homePath" />
<entry name="sambaAccount_domain" />
</section>
<section name="Quota Settings">
<entry name="quota_quotas" />
</section>
</pdf>
<pdf type="group">
<section name="_posixGroup_cn">
<entry name="posixGroup_description" />
<entry name="posixGroup_gidNumber" />
<entry name="main_dn" />
<entry name="posixGroup_memberUid" />
</section>
</pdf>
<pdf type="host">
<section name="_posixAccount_uid">
<entry name="posixAccount_description" />
<entry name="posixAccount_uidNumber" />
<entry name="posixAccount_primaryGroup" />
<entry name="sambaAccount_domain" />
<entry name="main_dn" />
</section>
</pdf>
</settings>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1 +0,0 @@

View File

@ -1,15 +0,0 @@
general_homedir: /home/$user
general_shell: /bin/bash
unix_password_no: 0
unix_pwdwarn: 10
unix_pwdallowlogin: 10
unix_pwdminage: 1
unix_pwdmaxage: 365
unix_pwdexpire: 1893452400
unix_deactivated: 0
smb_password_no: 0
smb_useunixpwd: 1
smb_flagsD: 0
smb_flagsX: 1
smb_homedrive: U:
smb_smbhome: \\server\$user

View File

@ -1,17 +0,0 @@
/bin/ash
/bin/bash
/bin/bash1
/bin/csh
/bin/false
/bin/ksh
/bin/sh
/bin/tcsh
/bin/true
/bin/zsh
/usr/bin/csh
/usr/bin/ksh
/usr/bin/passwd
/usr/bin/bash
/usr/bin/rbash
/usr/bin/tcsh
/usr/bin/zsh

View File

@ -1,52 +0,0 @@
This software is copyright (c) 2003 - 2004 by Tilo Lutz, Roland Gruber
and Michael Duergner.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The complete license can be found in the file COPYING.
Some parts of this package have other, compatible licences. These are:
A: GNU Lesser General Public License
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The complete license can be found in the file docs/LGPL-license.txt.
B: Freeware
You may use, modify and redistribute this software as you wish.
Programs and licenses with other licenses and/or authors than the
main license and authors:
lib/blowfish.inc A 2002-2003 Mike Cochrane
lib/fpdf.php B 2003 Olivier Plathey

View File

@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,286 +0,0 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<TITLE>FAQ</TITLE>
<LINK TYPE="text/css" REL="stylesheet" HREF="fpdf.css">
</HEAD>
<BODY>
<H2>FAQ</H2>
<B>1.</B> <A HREF='#1'>What's exactly the license of FPDF? Are there any usage restrictions?</A><BR>
<B>2.</B> <A HREF='#2'>When I try to create a PDF, a lot of weird characters show on the screen. Why?</A><BR>
<B>3.</B> <A HREF='#3'>I try to generate a PDF and IE displays a blank page. What happens?</A><BR>
<B>4.</B> <A HREF='#4'>I send parameters using the POST method and the values don't appear in the PDF.</A><BR>
<B>5.</B> <A HREF='#5'>When I use a PHP session, IE doesn't display my PDF any more but asks me to download it.</A><BR>
<B>6.</B> <A HREF='#6'>When I'm on SSL, IE can't open the PDF.</A><BR>
<B>7.</B> <A HREF='#7'>When I execute a script I get the message "FPDF error: Don't alter the locale before including class file".</A><BR>
<B>8.</B> <A HREF='#8'>I try to put a PNG and Acrobat says "There was an error processing a page. A drawing error occurred".</A><BR>
<B>9.</B> <A HREF='#9'>I encounter the following error when I try to generate a PDF: Warning: Cannot add header information - headers already sent by (output started at script.php:X)</A><BR>
<B>10.</B> <A HREF='#10'>I try to display a variable in the Header method but nothing prints.</A><BR>
<B>11.</B> <A HREF='#11'>I defined the Header and Footer methods in my PDF class but nothing appears.</A><BR>
<B>12.</B> <A HREF='#12'>I can't make line breaks work. I put \n in the string printed by MultiCell but it doesn't work.</A><BR>
<B>13.</B> <A HREF='#13'>I try to put the euro symbol but it doesn't work.</A><BR>
<B>14.</B> <A HREF='#14'>I draw a frame with very precise dimensions, but when printed I notice some differences.</A><BR>
<B>15.</B> <A HREF='#15'>I'd like to use the whole surface of the page, but when printed I always have some margins. How can I get rid of them?</A><BR>
<B>16.</B> <A HREF='#16'>What's the limit of the file sizes I can generate with FPDF?</A><BR>
<B>17.</B> <A HREF='#17'>Can I modify a PDF with FPDF?</A><BR>
<B>18.</B> <A HREF='#18'>I'd like to make a search engine in PHP and index PDF files. Can I do it with FPDF?</A><BR>
<B>19.</B> <A HREF='#19'>Can I convert an HTML page to PDF with FPDF?</A><BR>
<B>20.</B> <A HREF='#20'>Can I concatenate PDF files with FPDF?</A><BR>
<BR><BR>
<P><A NAME='1'></A><B>1.</B> <FONT CLASS='st'>What's exactly the license of FPDF? Are there any usage restrictions?</FONT></P>
FPDF is Freeware (it is stated at the beginning of the source file). There is no usage
restriction. You may embed it freely in your application (commercial or not), with or
without modification. You may redistribute it, too.
<P><A NAME='2'></A><B>2.</B> <FONT CLASS='st'>When I try to create a PDF, a lot of weird characters show on the screen. Why?</FONT></P>
These "weird" characters are in fact the actual content of your PDF. This behaviour is a bug of
IE. When it first receives an HTML page, then a PDF from the same URL, it displays it directly
without launching Acrobat. This happens frequently during the development stage: on the least
script error, an HTML page is sent, and after correction, the PDF arrives.
<BR>
To solve the problem, simply quit and restart IE. You can also go to another URL and come
back.
<BR>
To avoid this kind of inconvenience during the development, you can generate the PDF directly
to a file and open it through the explorer.
<P><A NAME='3'></A><B>3.</B> <FONT CLASS='st'>I try to generate a PDF and IE displays a blank page. What happens?</FONT></P>
First of all, check that you send nothing to the browser after the PDF (not even a space or a
carriage return). You can put an exit statement just after the call to the Output() method to
be sure.
<BR>
If it still doesn't work, it means you're a victim of the "blank page syndrome". IE used in
conjunction with the Acrobat plug-in suffers from numerous bugs, in all versions. You should
test your application with as many IE versions as possible (at least if you're on the Internet).
The problem occurs mostly with the POST method, so it is strongly advised to avoid it (all the
more that it causes other problems, see the next question). The GET works better but may fail
when the URL becomes too long: don't use a query string with more than 45 characters. However, a
tip exists to exceed this limit: end the URL with .pdf, which tricks IE. If you use a form, you
can add a hidden field at the last position:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
&lt;INPUT TYPE=&quot;HIDDEN&quot; NAME=&quot;ext&quot; VALUE=&quot;.pdf&quot;&gt;
</TT>
</TD></TR></TABLE><BR>
The usage of PHP sessions also often causes trouble (avoid using HTTP headers preventing caching).
See question 5 for a workaround.
<BR>
<BR>
To avoid all these problems in a reliable manner, two main techniques exist:
<BR>
<BR>
- Disable the plug-in and use Acrobat as a helper application. To do this, launch Acrobat; in
the File menu, Preferences, General, uncheck the option "Web Browser Integration" (for Acrobat
5: Edit, Preferences, Options, "Display PDF in Browser"). Then, the next time you load a PDF in
IE, it displays the dialog box "Open it" or "Save it to disk". Uncheck the option "Always ask
before opening this type of file" and choose Open. From now on, PDF files will open
automatically in an external Acrobat window.
<BR>
The drawback of the method is that you need to alter the client configuration, which you can do
in an intranet environment but not for the Internet.
<BR>
<BR>
- Use a redirection technique. It consists in generating the PDF in a temporary file on the
server and redirect the client on it (by using JavaScript, not the Location HTTP header which
also causes trouble). For instance, at the end of the script, you can put the following:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
//Determine a temporary file name in the current directory<BR>
$file=basename(tempnam(getcwd(),'tmp'));<BR>
//Save PDF to file<BR>
$pdf-&gt;Output($file);<BR>
//JavaScript redirection<BR>
echo &quot;&lt;HTML&gt;&lt;SCRIPT&gt;document.location='getpdf.php?f=$file';&lt;/SCRIPT&gt;&lt;/HTML&gt;&quot;;
</TT>
</TD></TR></TABLE><BR>
Then create the getpdf.php file with this:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
&lt;?php<BR>
$f=$HTTP_GET_VARS['f'];<BR>
//Check file (don't skip it!)<BR>
if(substr($f,0,3)!='tmp' or strpos($f,'/') or strpos($f,'\\'))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;die('Incorrect file name');<BR>
if(!file_exists($f))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;die('File does not exist');<BR>
//Handle special IE request if needed<BR>
if($HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype')<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;Header('Content-Type: application/pdf');<BR>
&nbsp;&nbsp;&nbsp;&nbsp;exit;<BR>
}<BR>
//Output PDF<BR>
Header('Content-Type: application/pdf');<BR>
Header('Content-Length: '.filesize($f));<BR>
readfile($f);<BR>
//Remove file<BR>
unlink($f);<BR>
exit;<BR>
?&gt;
</TT>
</TD></TR></TABLE><BR>
This method works in most cases but IE6 can still experience trouble. The "ultimate" method
consists in redirecting directly to the temporary file. The file name must therefore end with .pdf:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
//Determine a temporary file name in the current directory<BR>
$file=basename(tempnam(getcwd(),'tmp'));<BR>
rename($file,$file.'.pdf');<BR>
$file.='.pdf';<BR>
//Save PDF to file<BR>
$pdf-&gt;Output($file);<BR>
//JavaScript redirection<BR>
echo &quot;&lt;HTML&gt;&lt;SCRIPT&gt;document.location='$file';&lt;/SCRIPT&gt;&lt;/HTML&gt;&quot;;
</TT>
</TD></TR></TABLE><BR>
This method turns the dynamic PDF into a static one and avoids all troubles. But you have to do
some cleaning in order to delete the temporary files. For instance:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
function CleanFiles($dir)<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;//Delete temporary files<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$t=time();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$h=opendir($dir);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;while($file=readdir($h))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(substr($file,0,3)=='tmp' and substr($file,-4)=='.pdf')<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$path=$dir.'/'.$file;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($t-filemtime($path)&gt;3600)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@unlink($path);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;closedir($h);<BR>
}
</TT>
</TD></TR></TABLE><BR>
This function deletes all files of the form tmp*.pdf older than an hour in the specified
directory. You may call it where you want, for instance in the script which generates the PDF.
<BR>
<BR>
Remark: it is necessary to open the PDF in a new window, as you can't go backwards due to the
redirection.
<P><A NAME='4'></A><B>4.</B> <FONT CLASS='st'>I send parameters using the POST method and the values don't appear in the PDF.</FONT></P>
It's a problem affecting some versions of IE (especially the first 5.5). See the previous
question for the ways to work around it.
<P><A NAME='5'></A><B>5.</B> <FONT CLASS='st'>When I use a PHP session, IE doesn't display my PDF any more but asks me to download it.</FONT></P>
It's a problem affecting some versions of IE. To work around it, add the following line before
session_start():
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
session_cache_limiter('private');
</TT>
</TD></TR></TABLE><BR>
or do a redirection as explained in question 3.
<P><A NAME='6'></A><B>6.</B> <FONT CLASS='st'>When I'm on SSL, IE can't open the PDF.</FONT></P>
The problem may be fixed by adding this line:<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
Header('Pragma: public');
</TT>
</TD></TR></TABLE><BR>
<P><A NAME='7'></A><B>7.</B> <FONT CLASS='st'>When I execute a script I get the message "FPDF error: Don't alter the locale before including class file".</FONT></P>
When the decimal separator is configured as a comma before including a file, there is a
<A HREF="http://bugs.php.net/bug.php?id=17105" TARGET="_blank">bug</A> in some PHP versions and decimal
numbers get truncated. Therefore you shouldn't make a call to setlocale() before including the class.
On Unix, you shouldn't set the LC_ALL environment variable neither, for it is equivalent to a
setlocale() call.
<P><A NAME='8'></A><B>8.</B> <FONT CLASS='st'>I try to put a PNG and Acrobat says "There was an error processing a page. A drawing error occurred".</FONT></P>
Acrobat 5 has a bug and is unable to display transparent monochrome images (i.e. with 1 bit per
pixel). Remove transparency or save your image in 16 colors (4 bits per pixel) or more.
<P><A NAME='9'></A><B>9.</B> <FONT CLASS='st'>I encounter the following error when I try to generate a PDF: Warning: Cannot add header information - headers already sent by (output started at script.php:X)</FONT></P>
You must send nothing to the browser except the PDF itself: no HTML, no space, no carriage return,
neither before nor after. The script outputs something at line X.
<P><A NAME='10'></A><B>10.</B> <FONT CLASS='st'>I try to display a variable in the Header method but nothing prints.</FONT></P>
You have to use the <TT>global</TT> keyword, for instance:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
function Header()<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;global $title;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;SetFont('Arial','B',15);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;Cell(0,10,$title,1,1,'C');<BR>
}
</TT>
</TD></TR></TABLE><BR>
<P><A NAME='11'></A><B>11.</B> <FONT CLASS='st'>I defined the Header and Footer methods in my PDF class but nothing appears.</FONT></P>
You have to create an object from the PDF class, not FPDF:<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
$pdf=new PDF();
</TT>
</TD></TR></TABLE><BR>
<P><A NAME='12'></A><B>12.</B> <FONT CLASS='st'>I can't make line breaks work. I put \n in the string printed by MultiCell but it doesn't work.</FONT></P>
You have to enclose your string with double quotes, not single ones.
<P><A NAME='13'></A><B>13.</B> <FONT CLASS='st'>I try to put the euro symbol but it doesn't work.</FONT></P>
The standard fonts have the euro character at position 128. You can define a constant like this
for convenience:
<BR>
<BR>
<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD>
<TT>
define('EURO',chr(128));
</TT>
</TD></TR></TABLE><BR>
Note: Acrobat 4 or higher is required to display euro.
<P><A NAME='14'></A><B>14.</B> <FONT CLASS='st'>I draw a frame with very precise dimensions, but when printed I notice some differences.</FONT></P>
To respect dimensions, you have to uncheck the option "Fit to page" in the print dialog box.
<P><A NAME='15'></A><B>15.</B> <FONT CLASS='st'>I'd like to use the whole surface of the page, but when printed I always have some margins. How can I get rid of them?</FONT></P>
All printers have physical margins (different depending on the model), it is therefore impossible
to remove them and print on the totality of the paper.
<P><A NAME='16'></A><B>16.</B> <FONT CLASS='st'>What's the limit of the file sizes I can generate with FPDF?</FONT></P>
There is no particular limit. There are some constraints however:
<BR>
<BR>
- The maximum memory size allocated to PHP scripts defaults to 8MB. For very big documents,
especially with images, this limit may be reached (the file being built into memory). The
parameter is configured in the php.ini file.
<BR>
<BR>
- The maximum execution time allocated defaults to 30 seconds. This limit can of course be easily
reached. It is configured in php.ini and may be altered dynamically with set_time_limit().
<BR>
<BR>
- Browsers generally have a 5 minute time-out. If you send the PDF directly to the browser and
reach the limit, it will be lost. It is therefore advised for very big documents to
generate them in a file, and to send some data to the browser from time to time (for instance
page 1, page 2... with flush() to force the output). When the document is finished, you can send
a redirection on it with JavaScript or create a link.
<BR>
Remark: even when the browser goes in time-out, the script may continue to run on the server.
<P><A NAME='17'></A><B>17.</B> <FONT CLASS='st'>Can I modify a PDF with FPDF?</FONT></P>
No.
<P><A NAME='18'></A><B>18.</B> <FONT CLASS='st'>I'd like to make a search engine in PHP and index PDF files. Can I do it with FPDF?</FONT></P>
No. But a GPL C utility does exist, pdftotext, which is able to extract the textual content from
a PDF. It is provided with the Xpdf package:<BR>
<BR>
<A HREF="http://www.foolabs.com/xpdf/" TARGET="_blank">http://www.foolabs.com/xpdf/</A>
<P><A NAME='19'></A><B>19.</B> <FONT CLASS='st'>Can I convert an HTML page to PDF with FPDF?</FONT></P>
No. But a GPL C utility does exist, htmldoc, which allows to do it and gives good results:<BR>
<BR>
<A HREF="http://www.easysw.com/htmldoc/" TARGET="_blank">http://www.easysw.com/htmldoc/</A>
<P><A NAME='20'></A><B>20.</B> <FONT CLASS='st'>Can I concatenate PDF files with FPDF?</FONT></P>
No. But a free C utility exists to perform this task:<BR>
<BR>
<A HREF="http://thierry.schmit.free.fr/dev/mbtPdfAsm/enMbtPdfAsm2.html" TARGET="_blank">http://thierry.schmit.free.fr/dev/mbtPdfAsm/enMbtPdfAsm2.html</A>
</BODY>
</HTML>

View File

@ -1,28 +0,0 @@
The attribute "host" is only in objectclass account.
Unfortunatly "account" conflicts with
"inetorgperson". so there's no perfect way to use
both.
In order to get attribute host working you have to
modify schema/inetorgperson and include host:
# inetOrgPerson
# The inetOrgPerson represents people who are associated with an
# organization in some way. It is a structural class and is derived
# from the organizationalPerson which is defined in X.521 [X521].
objectclass ( 2.16.840.1.113730.3.2.2
NAME 'inetOrgPerson'
DESC 'RFC2798: Internet Organizational Person'
SUP organizationalPerson
STRUCTURAL
MAY (
audio $ businessCategory $ carLicense $ departmentNumber $
displayName $ employeeNumber $ employeeType $ givenName $
homePhone $ homePostalAddress $ initials $ jpegPhoto $
labeledURI $ mail $ manager $ mobile $ o $ pager $
photo $ roomNumber $ secretary $ uid $ userCertificate $
x500uniqueIdentifier $ preferredLanguage $
userSMIMECertificate $ userPKCS12 $ host )
)

View File

@ -1,77 +0,0 @@
lamdaemon.pl is used to modify quota and homedirs
on a remote or local host via ssh.
If you want wo use it you have to set up some
things to get it to work:
1. Setup values in LDAP Account Manager
* Set the remote or local host in the configuration
(e.g. 127.0.0.1)
* Path to lamdaemon.pl, e.g. /srv/www/htdocs/lam/lib/lamdaemon.pl
2. Set up sudo
The perl script has to run as root. Therefore we need
a wrapper, sudo.
Edit /etc/sudoers on host where homedirs or quotas should be used
and add the following line:
$admin All= NOPASSWD: $path
$admin is the adminuser from LAM and $path
is the path to lamdaemon.pl e.g. "$admin All= NOPASSWD: /srv/www/htdocs/lam/lib/lamdaemon.pl"
At the moment the password is a paramteter of lamdaemon.pl
therefore you should disable logging so the password does not
appear in any logfile.
This can be done by adding the following line to /etc/sudoers:
Defaults:$admin !syslog
3. Set up Perl
We need some external Perl modules, Quota and Net::SSH::Perl
To install them, run:
perl -MCPAN -e shell
install Quota
install Net::SSH::Perl
If your Perl executable is not located in /usr/bin/perl you will have to edit
the path in the first line of lamdaemon.pl.
Debian users can install Net::SSH:Perl with dh-make-perl:
apt-get install dh-make-perl
dh-make-perl --build --cpan Net::SSH::Perl
dpkg -i install libnet-ssh-perl_1.25-1_all.deb
4. Test lamdaemon.pl
There is a test-function in lamdaemon.pl. Please run lamdaemon.pl
with the following parameters to test it:
lamdaemon.pl $ssh-server $lam_path_on_host $admin-username $admin-password *test
$ssh-server is the remote host lamdaemon.pl should be run on
$lam_path_on_host is the path to lamdaemon.pl on remote host
$admin-username is the name of the user which is allowed to run lamdaemon.pl
as root. It is the same user as in /etc/sudoers
$admin-password is the password of the admin user
*test is the command which tells lamdaemon.pl to test settings
You have to run the command as the user your webserver is running, e.g.
wwwrun@tilo:/srv/www/htdocs/lam/lib> /srv/www/htdocs/lam/lib/lamdaemon.pl \
127.0.0.1 /srv/www/htdocs/lam/lib/lamdaemon.pl root secret *test
You should get the following response:
Net::SSH::Perl successfully installed.
Perl quota module successfully installed.
If you have not seen any error lamdaemon.pl should be set up successfully.
!!! Attention !!!
Your password in LDAP has to be hashed with CRYPT. If you use something like SSHA
you will probably get "Access denied.".
Now everything should work fine.
Please send a mail to TiloLutz@gmx.de if you have any suggestions.

View File

@ -1,21 +0,0 @@
Some basic hints to configure the OpenLDAP server:
SIZELIMIT: OpenLDAP allows by default 500 return values per search, if you have more users/groups/hosts
change this in slapd.conf: e.g. "sizelimit 10000" or "sizelimit -1" for unlimited return values.
INDICES: Indices will improve the performance when searching for entries in the LDAP directory.
The following indices are recommended:
index objectClass eq
index default sub
index uidNumber eq
index gidNumber eq
index memberUid eq
index cn,sn,uid,displayName pres,sub,eq
# Samba 2.x
index rid eq
index primaryGroupID eq
# Samba 3.x
index sambaSID eq
index sambaPrimaryGroupSID eq
index sambaDomainName eq

View File

@ -1,36 +0,0 @@
1. Use of SSL
The data which is transfered between you and LAM is very sensitive.
Please always use SSL encrypted connections between LAM and your browser to
protect yourself against network sniffers.
2. LDAP+SSL and TLS
LAM should start TLS automatically if possible. LDAP+SSL will be used if you use
ldaps://servername in your configuration profile.
3. Chrooted servers
If your server is chrooted and you have no access to /dev/random or /dev/urandom
this can be a security risk. LAM stores your LDAP password encrypted in the session.
LAM uses rand() to generate the key if /dev/random and /dev/urandom are not accessible.
Therefore the key can be easily guessed.
An attaker needs read access to the session file (e.g. by another Apache instance) to
exploit this.
4. LDAP password protection
Your LDAP password is stored encrypted in the session file. The key and IV to decrypt
it are stored in two cookies. We use MCrypt/AES or Blowfish to encrypt the password.
5. Protection of new user passwords
These passwords are, if stored in the session file, encrypted with the same key and IV
as your LDAP password.

View File

@ -1,49 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Account modules</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Account modules<br>
</h1>
<div style="text-align: center;"><img alt="base module"
src="images/lam_baseModule.png" style="width: 531px; height: 207px;"><br>
</div>
<div style="text-align: center;"><br>
<div style="text-align: left;">The account modules control all the
functionality which is specific for LDAP accounts or parts of them.
E.g. they define the account detail pages where the user can edit
accounts, the profile editor sections and much more. They are the core
of LAM.<br>
<br>
All account modules are saved in <span style="font-weight: bold;">lib/modules/</span>.<br>
If your module needs any include files etc. please save it in <span
style="font-weight: bold;">lib/modules/&lt;name of your module&gt;.</span><br>
<br>
Please take a look at the <a href="mod_index.htm">module HowTo</a> for
an example to write your own modules.<br>
The complete specification for the module interface can be found <a
href="../modules-specification.htm">here</a>.<br>
<br>
<h2>Superclass</h2>
All <span style="font-weight: bold;">account modules</span> should be
subclasses of the <a href="base_module.htm">baseModule</a>.<br>
This allows them to benefit from the meta data in the baseModule and
reduces very much the code since not the complete module interface has
to be implemented.<br>
<br>
<br>
<h2>Module detection</h2>
New modules can simply be copied to <span style="font-weight: bold;">lib/modules</span>.
LAM will check what files are inside the directory and provide the user
new modules automtically.<br>
There is no extra configuration file.<br>
<br>
<br>
</div>
</div>
</body>
</html>

View File

@ -1,74 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Base module</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Base module<br>
</h1>
<div style="text-align: center;"><img alt="base module"
src="images/lam_baseModule.png" style="width: 531px; height: 207px;"><br>
</div>
<div style="text-align: center;"><br>
<div style="text-align: left;">The <span style="font-weight: bold;">baseModule</span>
is the parent class of all account modules. <br>
It implements most functions of the <a
href="../modules-specification.htm">module interface</a> and provides
the possibility to use <span style="font-style: italic;">meta data</span>
for the module functions.<br>
There are also some class variables which are useful for the child
classes.<br>
<br>
<br>
<h2>Meta data</h2>
The <span style="font-weight: bold;">baseModule</span> allows you to
not implement the <a href="../modules-specification.htm">module
interface</a> directly but to provide <span style="font-style: italic;">meta
data</span> which is interpreted by the <span
style="font-weight: bold;">baseModule</span>.<br>
If you do not use certain functions of the interface the <span
style="font-weight: bold;">baseModule</span> also provides dummy
functions. E.g. if your module needs no configuration option you can
just skip this function in your code and the <span
style="font-weight: bold;">baseModule</span> will tell the
configuration part that there is no option.<br>
<br>
To <span style="font-style: italic;">define meta</span> data you have
to implement the function <span
style="font-weight: bold; font-style: italic;">get_metaData()</span>.
This function must return a hash array with the meta options as array
keys.<br>
Please refer to the <a href="../modules-specification.htm">module
interface</a> for details about the format of <span
style="font-style: italic;">meta data</span>.<br>
<br>
<br>
<h2>Functions<br>
</h2>
<span style="font-weight: bold;">get_scope():</span> This function
returns the account type ("user", "group", ...) of the module.<br>
<br>
For a list of <span style="font-style: italic;">meta data</span>
functions please refer to the <a href="../modules-specification.htm">module
interface</a>.<br>
<br>
<br>
<h2>Class variables</h2>
<span style="font-weight: bold;">$moduleSettings:</span> This variable
contains the configuration settings of all modules.<br>
<span style="font-weight: bold;">$base:</span> This is the name of the
parent <span style="font-style: italic;">accountContainer</span>
($_SESSION[$base]).<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
</div>
</body>
</html>

View File

@ -1,61 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>config.inc</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">config.inc</h1>
<br>
<br>
This file includes all functions needed to manage configuration
profiles. It includes classes for the profiles itself and the master
configuration (default profile, master password, etc.).<br>
<br>
There are also two global functions for general use: <span
style="font-style: italic;">setlanguage</span> and <span
style="font-style: italic;">metarefresh</span><br>
<br>
<h2>Meta refresh</h2>
The global function <span
style="font-weight: bold; font-style: italic;">metaRefresh()</span>
takes an URL as argument and prints all HTML code needed for a meta
refresh to this URL.<br>
<br>
<h2>Language</h2>
LAM uses <span style="font-style: italic;">gettext</span> to translate
the HTML pages to the different languages. Therefore some preferences
need to be set on every page load. This is done by <span
style="font-style: italic; font-weight: bold;">setlanguage()</span>.<br>
The function should be called directly after starting the session.<br>
<br>
The list of possible languages is stored in <span
style="font-style: italic;">config/language</span>. It includes the
locale name, the character encoding an the language name.<br>
All languages use UTF-8 as encoding because LDAP also stores values in
this format.<br>
<br>
<h2>Configuration profiles</h2>
Each configuration profile is saved in a single file in <span
style="font-weight: bold;">config/</span>.<br>
<br>
There are two types of configuration options:<br>
<ul>
<li>Static options (LDAP server settings, etc.)<br>
</li>
<li>Module options (UID/GID ranges)<br>
</li>
</ul>
All static options have a describing comment in the configuration file
to make it easier for the user to modify the values. The dynamic
options provided by the modules do not include a comment.<br>
<br>
<h2>Master configuration file</h2>
LAM stores the default configuartion profile and a master password in <span
style="font-style: italic;">config/config.cfg</span>.<br>
The master password is verified when the user wants to create/delete
configuration profiles.<br>
</body>
</html>

View File

@ -1,44 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Configuration profiles</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Configuration profiles</h1>
<br>
LAM allows the user to store the configuration settings in <span
style="font-weight: bold;">profiles</span>. This makes it easy to
manage different LDAP servers. All profile files ae stored in <span
style="font-weight: bold;">config/</span> and are named <span
style="font-weight: bold;"><span style="font-style: italic;">&lt;name&gt;</span>.conf</span>.<br>
The <span style="font-weight: bold;">master configuration</span> file <span
style="font-style: italic;">config/config.cfg</span> only stores the
default profile and master password. It has the same file format as the
profiles.<br>
<br>
<h2>File format</h2>
LAM allows to store values and comments in the configuration files.
Only one type per line is allowed, it is not possible to mix comments
and values in the same line.<br>
<br>
<h3>Settings<br>
</h3>
<span style="font-weight: bold;">&lt;identifier&gt;: &lt;value&gt;<br>
<br>
</span>The first word in the line is taken as identifier for the
setting. It must be followed by a <span style="font-weight: bold;">":"</span>
and a space.<br>
The rest of the line is taken as the value for this setting.<br>
<br>
<h3>Comments</h3>
<span style="font-weight: bold;"># Comment</span><br
style="font-weight: bold;">
<br>
Comments always start with a <span style="font-weight: bold;">"#"</span>
as first character and end at the line end. LAM will ignore all lines
starting with a <span style="font-style: italic;">"#"</span>.<br>
</body>
</html>

View File

@ -1,77 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>LAM - Configuration pages</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Configuration pages</h1>
</div>
<br>
<div style="text-align: center;"><img
style="width: 620px; height: 319px;" alt="configuration"
src="images/lam_config.png"><br>
<div style="text-align: left;">
<h2>Configuration - Login (conflogin.php):</h2>
This is the start page of the configuration editor. The user can select
a profile for editing or go to the profile management page.<br>
Each account profile is protected with a password which is stored in
the profile.<br>
The list of possible profiles is returned by <span
style="font-style: italic; font-weight: bold;">getConfigProfiles()</span>
in config.inc, the default profile is returned by an object of class <span
style="font-weight: bold; font-style: italic;">CfgMain</span> from
config.inc.<br>
<br>
<br>
<h2>Configuration - Profile management (profmanage.php):</h2>
Here the user can add and modify configuration profiles or change the
configuration master password. <br>
The configuration master password prevents unauthorised users from
changing the profiles. The password is saved in config/config.cfg and
managed via the <span style="font-style: italic; font-weight: bold;">CfgMain</span>
class.<br>
<br>
<br>
<h2>Configuration - Main page (confmain.php):</h2>
This page presents all configuration settings for editing.<br>
Some of the settings are module independent (e.g. server settings,
language, ...) and displayed always.<br>
The others are set up by the account modules. Only settings of
currently selected modules are displayed.<br>
Users may also change the profile password on this page.<br>
<br>
<br>
<h2>Configuration - Module selection (confmodules.php):<br>
</h2>
On this page the user can select which account modules LAM should use.<br>
The list of possible modules is returned by <span
style="font-style: italic; font-weight: bold;">getAvailableModules()</span>
in modules.inc and checked for dependencies/conflicts with <span
style="font-weight: bold; font-style: italic;">check_module_depends()</span>
and <span style="font-weight: bold; font-style: italic;">check_module_conflicts()</span>.<br>
<br>
Each account type needs a <span style="font-style: italic;">base module</span>
which provides the base of a senseful account. It also provides the
LDAP search filter for the account lists.<br>
<br>
<br>
<h2>Configuration - Save settings (confsave.php):<br>
</h2>
This script checks the input and displays possible error messages or an
overview of the saved settings.<br>
The static settings are set and checked with an object of class <span
style="font-style: italic; font-weight: bold;">Config</span> from
config.inc.<br>
The account modules manage the input validation for their fields and
are also able to return error messages. This is done with <span
style="font-weight: bold; font-style: italic;">checkConfigOptions()</span>
from modules.inc.<br>
<br>
</div>
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -1,97 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>LAM development documentation</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>LDAP Account Manager - Code overview</h1>
These documents are supposed to give developers who want to modify LAM
an overview of the codebase. It focuses mainly on what is done to
generate the HTML output and the most important functions provided by
the library files.<br>
<img src="images/lam_overview.png" alt="overview" align="middle"
border="0" height="620" width="877"><br>
<br>
<div style="text-align: left;">
<table style="text-align: left; width: 100%;" border="0" cellpadding="2"
cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top; width: 33%;">
<h2>Web pages:</h2>
<ul>
<li>Login<br>
</li>
<li><a href="file:///daten/cvs/lam/docs/devel/config_pages.htm">Configuration</a></li>
<li><a href="file:///daten/cvs/lam/docs/devel/lists.htm">Account
lists</a><br>
</li>
<li>Account pages</li>
<li>Tools</li>
<ul>
<li><a href="profile_editor.htm">Profile editor</a></li>
<li>Samba 3 domains</li>
<li><a href="upload.htm">File upload</a></li>
<li>OU editor</li>
<li>PDF editor<br>
</li>
</ul>
</ul>
</td>
<td style="vertical-align: top; width: 33%;">
<h2>Libraries:</h2>
<ul>
<li>Account modules (modules.inc)<br>
</li>
<li>PDF (pdf.inc)<br>
</li>
<li><a href="profiles.htm">Account profiles (profiles.inc)</a><br>
</li>
<li><a href="config.htm">Configuration (config inc)</a><br>
</li>
<li><a href="file:///daten/cvs/lam/docs/devel/ldap.htm">LDAP
(ldap.inc)</a><br>
</li>
<li><a href="other_libs.htm">other libraries</a></li>
<ul>
<li><a href="other_libs.htm#lamdaemon">Lamdaemon</a><br>
</li>
</ul>
<ul>
<li><a href="other_libs.htm#blowfish">Blowfish</a></li>
<li><a href="other_libs.htm#cache">LADP cache</a></li>
<li><a href="other_libs.htm#lists">Account lists</a></li>
<li><a href="other_libs.htm#status">Status messages</a><br>
</li>
</ul>
</ul>
</td>
<td style="vertical-align: top; width: 33%;">
<h2>Configuration files:</h2>
<ul>
<li><a href="base_module.htm">Base module</a><br>
</li>
<li><a href="account_modules.htm">Account modules</a></li>
<li>PDF templates</li>
<li><a href="profile_files.htm">Account profiles</a></li>
<li><a href="config_files.htm">Configuration profiles</a><br>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>Howtos</h2>
<ul>
<li><a href="mod_index.htm">Writing account modules</a><br>
</li>
</ul>
<br>
</div>
</div>
</body>
</html>

View File

@ -1,55 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>ldap.inc</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">ldap.inc</h1>
<br>
<br>
This library provides the access to the LDAP server and its content.<br>
The <span style="font-weight: bold; font-style: italic;">$_SESSION['ldap']</span>
object reconnects automatically to the LDAP server on every page load.<br>
<br>
<br>
<h2>1. Server handle</h2>
All PHP functions which access LDAP require a server handle as
parameter. This is managed by ldap.inc.<br>
You can access it with <span
style="font-weight: bold; font-style: italic;">$_SESSION['ldap']-&gt;server</span>.<br>
<br>
<br>
<h2>2. Object classes</h2>
Account modules may want to check if the current LDAP server supports
all required object classes.<br>
<span style="font-weight: bold; font-style: italic;">$_SESSION['ldap']-&gt;objectClasses
</span>contains a list of object classes and their attributes which is
read from the LDAP server.<br>
<br>
<br>
<h2>3. En-/Decryption</h2>
For security reasons sensitive data like user passwords should be
encrypted before storing in session.<br>
<span style="font-weight: bold; font-style: italic;">$_SESSION['ldap']-&gt;encrypt(&lt;string&gt;)</span>
encrypts a string and returns a binary object. This can be decrypted
with <span style="font-weight: bold; font-style: italic;">$_SESSION['ldap']-&gt;decrypt(&lt;object&gt;)</span><br>
<br>
Ldap.inc will take care for the crypotographic key and if Blowfish or
MCrypt/AES is used.<br>
<br>
<br>
<h2>4. Random values</h2>
Ldap.inc contains a random integer value which is much more secure than
calling <span style="font-style: italic;">mt_rand()</span>. The value
changes on every page load and is accessible in <span
style="font-weight: bold; font-style: italic;">$_SESSION['ldap']-&gt;rand</span><span
style="font-style: italic;">.</span><br>
If you need multiple values you can get a new value by calling <span
style="font-weight: bold; font-style: italic;">$_SESSION['ldap']-&gt;new_rand()</span><span
style="font-style: italic;">.</span><br>
<br>
</body>
</html>

View File

@ -1,103 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>LAM - Account lists</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Account lists</h1>
<br>
<div style="text-align: center;"><img
style="width: 496px; height: 177px;" alt="Account lists"
src="images/lam_lists.png"><br>
</div>
<br>
<br>
<br>
The account lists are all built after the same schema. They provide a
list of found accounts which can be restricted by LDAP filters and the
LDAP OU (Organizational Unit).<br>
<br>
The list of LDAP attributes and thus table columns is taken from the
configuration profile (<span
style="font-weight: bold; font-style: italic;">get_...listAttributes()</span>
in config.inc). Each account list has a separate list of attributes.<br>
Only these attributes are given the LDAP search as attribute parameter.<br>
There is also a predefined description list for the attributes in
lists.inc. The user may use other values by setting them in the
configuration profile.<br>
<br>
The number of accounts per page is limited in the configuration profile
(<span style="font-weight: bold; font-style: italic;">get_MaxListEntries()</span>
in config.inc). There will be links at the beginning and end of the
list if more accounts were found.<br>
<br>
Several common helper functions for sorting and some page elements
reside in lists.inc.<br>
<br>
<h2>1. Getting accounts from LDAP</h2>
Each account list has its own LDAP suffix which is saved in the
configuration profile. This is used as search base.<br>
The account modules provide an LDAP filter (<span
style="font-weight: bold; font-style: italic;">get_ldap_filter()</span>
in modules.inc) to get only accounts of a special type.<br>
<br>
This list can be further reduced if the user provides an additional
LDAP filter with the filter boxes or selects another LDAP OU with the
drop-down-box.<br>
<br>
<h2>2. Caching LDAP accounts</h2>
The lists usually do not ask the LDAP server for an account list every
time the user changes the page. The accounts are cached in the session.<br>
<br>
A new LDAP search is done if the user:<br>
<ul>
<li>changes to another account list or tool</li>
<li>adds/modifies an account</li>
<li>selects the "refresh" button</li>
<li>adds additional LDAP filters or changes the LDAP OU<br>
</li>
</ul>
<br>
It is <span style="font-style: italic;">not</span> done if the user:<br>
<ul>
<li>changes the list pages if there are more accounts than what can
be shown</li>
<li>sorts the list</li>
</ul>
<br>
<h2>3. Adding/Editing accounts</h2>
There are buttons at the end of the page to add/delete accounts. Adding
accounts is done by account/edit.php and deleting by delete.php.<br>
<br>
The user can use the link in each account row to modify (in
accounts/edit.php) the account. This can also be done by double
clicking the row if Java Script is enabled.<br>
<br>
<br>
<h2>4. Export to PDF</h2>
The user can generate PDF files for the accounts. This is done by the <span
style="font-style: italic; font-weight: bold;">createModulePDF()</span>
function from pdf.inc.<br>
<br>
<br>
<h2>5. Special abilities of some lists</h2>
<h3>5.1. The user list</h3>
If the attribute <span style="font-style: italic;">gidNumber</span> is
shown as table column then there will be an additional checkbox to
translate the GID to the group name.<br>
This checkbox is hidden if <span style="font-style: italic;">gidNumber</span>
is not part of the attribute list.<br>
<br>
<h3>5.2. The group list</h3>
If the attribute memberUID is shown as table column then all values of
this attribute are shown as links.<br>
These links redirect to userlink.php which tries to find the given user
and redirects to account/edit.php for account modifying.<br>
<br>
<br>
<br>
</body>
</html>

View File

@ -1,420 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Account pages</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Account pages<br>
</h1>
<br>
<br>
<div style="text-align: left;"><br>
<h2>1. Loading the LDAP attributes<br>
</h2>
Every time the user selects an existing account to modify LAM will load
the complete LDAP entry of it. Your module then should select the
attributes which are useful for it.<br>
There are two variables in <span style="font-style: italic;">baseModule</span>
which should be used to store the attributes. The <span
style="font-weight: bold;">$attributes</span> variable stores the
current attributes including changes the user made. The <span
style="font-weight: bold;">$orig</span> variable stores the attributes
as they were originally when the account was loaded. This allows you to
see what changes were made.<br>
<br>
The <span style="font-weight: bold;">load_attributes()</span> function
in your module gets the complete attribute list from LDAP.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span> uses an
object class and the <span style="font-style: italic;">'macAddress'</span>
attribute. Therefore we will save this two values.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * This function loads all needed attributes into the
object.<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @param array $attr an array as it is retured from
ldap_get_attributes<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">load_attributes</span>($attr) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['objectClass'] = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['macAddress'] = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;orig['objectClass'] =
array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;orig['macAddress'] =
array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (isset($attr['objectClass'])) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
unset($attr['objectClass']['count']);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['objectClass'] = $attr['objectClass'];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;orig['objectClass'] = $attr['objectClass'];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (isset($attr['macAddress'])) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
unset($attr['macAddress']['count']);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['macAddress'] = $attr['macAddress'];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;orig['macAddress'] = $attr['macAddress'];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>2. Defining pages<br>
</h2>
You can define multiple subpages for your account page. Usually one
page is enough but you may display certain attribute settings on an
extra page (e.g. Unix group memberships are on a second page).<br>
<br>
The page names are set by <span style="font-weight: bold;">pages() </span>which
returns an array of names.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The
<span style="font-style: italic;">ieee802Device</span>
module needs only one page which is called <span
style="font-style: italic;">'attributes'</span>.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * This function returns a list of all account pages
in this module.<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">pages</span>() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return array('attributes');<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>3. Page display</h2>
Now that you have defined your subpages you will need one function for
each page to display it. The function must return <span
style="font-style: italic;">meta HTML code</span> as defined in the <span
style="font-style: italic;">modules specification</span>.<br>
This function is called <span style="font-weight: bold;">display_html_&lt;page
name&gt;()</span> where <span style="font-style: italic;">&lt;page
name&gt;</span> is the name of your subpage.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The
<span style="font-style: italic;">ieee802Device</span>
module has only one subpage called <span style="font-style: italic;">'attributes'</span>.<br>
<br>
The first half of the code displays the existing MAC addresses and the
second an input field for new values.<br>
The variable <span style="font-style: italic;">$this-&gt;attributes</span>
contains the LDAP attributes which are useful for this module.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * This function will create the meta HTML code to
show a page with all attributes.<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @param array $post HTTP-POST values<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">display_html_attributes</span>($post) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // list current MACs<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for ($i = 0; $i &lt;
sizeof($this-&gt;attributes['macAddress']); $i++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return[] =
array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 0 =&gt; array('kind' =&gt; 'text', 'text' =&gt;
_('MAC address')),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 1 =&gt; array('kind' =&gt; 'input', 'name' =&gt;
'macAddress' . $i, 'type' =&gt; 'text', 'size' =&gt; '17', 'maxlength'
=&gt; '17', 'value' =&gt; $this-&gt;attributes['macAddress'][$i]),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 2 =&gt; array('kind' =&gt; 'input', 'type' =&gt;
'submit', 'name' =&gt; 'delMAC' . $i, 'value' =&gt; _("Remove")),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 3 =&gt; array('kind' =&gt; 'help', 'value' =&gt;
'mac'));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // input box for new MAC<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return[] = array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 =&gt;
array('kind' =&gt; 'text', 'text' =&gt; _('New MAC address')),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1 =&gt;
array('kind' =&gt; 'input', 'name' =&gt; 'macAddress', 'type' =&gt;
'text', 'size' =&gt; '17', 'maxlength' =&gt; '17', 'value' =&gt; ''),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 2 =&gt;
array('kind' =&gt; 'input', 'type' =&gt; 'submit', 'name' =&gt;
'addMAC', 'value' =&gt; _("Add")),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 3 =&gt;
array('kind' =&gt; 'help', 'value' =&gt; 'mac'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 4 =&gt;
array('kind' =&gt; 'input', 'type' =&gt; 'hidden', 'value' =&gt;
sizeof($this-&gt;attributes['macAddress']), 'name' =&gt; 'mac_number'));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>4. Processing input data<br>
</h2>
Every time the user clicks on a submit button while your page is
displayed LAM will call a function in your module.<br>
This function is called <span style="font-weight: bold;">process_&lt;page
name&gt;()</span> where <span style="font-style: italic;">&lt;page
name&gt;</span> is the name of your subpage.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The
<span style="font-style: italic;">ieee802Device</span>
module has only one subpage called <span style="font-style: italic;">'attributes'</span>
and therefore only <span style="font-style: italic;">process_attributes()</span>.<br>
<br>
The function checks the input fields and fills the LDAP attributes. If
all is ok it will enable the user to move to another module page.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Write variables into object and do some regex
checks<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @param array $post HTTP-POST values<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">proccess_attributes</span>($post) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;triggered_messages =
array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['macAddress'] = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // check old MACs<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (isset($post['mac_number'])) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for ($i = 0;
$i &lt; $post['mac_number']; $i++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if (isset($post['delMAC' . $i])) continue;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if (isset($post['macAddress' . $i]) &amp;&amp;
($post['macAddress' . $i] != "")) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // check if address has correct
format<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!get_preg($post['macAddress'
. $i], 'macAddress')) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $message =
$this-&gt;messages['mac'][0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $message[] =
$post['macAddress' . $i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;triggered_messages[] = array($message);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['macAddress'][] = $post['macAddress' . $i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // check new MAC<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (isset($post['macAddress'])
&amp;&amp; ($post['macAddress'] != "")) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // check if
address has correct format<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(get_preg($post['macAddress'], 'macAddress')) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; $this-&gt;attributes['macAddress'][] =
$post['macAddress'];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $message =
$this-&gt;messages['mac'][0];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $message[] = $post['macAddress'];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;triggered_messages[] =
array($message);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;attributes['macAddress'] =
array_unique($this-&gt;attributes['macAddress']);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(sizeof($this-&gt;triggered_messages) &gt; 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;inputCorrect = false;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return
$this-&gt;triggered_messages;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$this-&gt;inputCorrect = true;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>5. Defining that your module is ready for LDAP add/modify</h2>
Before a new account can be created or modified all modules are asked
if they are ready.<br>
There are two functions which control the module status. The <span
style="font-weight: bold;">module_ready()</span> function has to
return <span style="font-style: italic;">true</span> if the user may
move to another module page. If it is <span style="font-style: italic;">false</span>
the user will be redirected to your module page. The second function is
<span style="font-weight: bold;">module_complete()</span>. The user
cannot do the LDAP operation if one or modules return <span
style="font-style: italic;">false</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The
<span style="font-style: italic;">ieee802Device</span>
module uses a global variable to store the status: <span
style="font-style: italic;">$this-&gt;inputCorrect</span>. It is set
in <span style="font-style: italic;">process_attributes()</span>. The
variable can be preset to <span style="font-style: italic;">true</span>
because the MAC address is optional.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /** used for
account pages, true if input data is correct */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">var</span>
$inputCorrect = true;<br>
<br>
&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * This function returns true if all needed settings
are done.<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">module_complete</span>() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $this-&gt;inputCorrect;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns true if all settings on module page are
correct.<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">module_ready</span>() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $this-&gt;inputCorrect;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>6. Saving the LDAP attributes<br>
</h2>
When all modules report that they are ready for LDAP add/modify and the
user clicks on the add/modify button your module will be asked what
changes have to be made.<br>
This is done in the function <span style="font-weight: bold;">save_attributes()</span>
which must be implemented by your module.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span>
module saves the attribute states in <span style="font-style: italic;">$attributes</span>
and <span style="font-style: italic;">$orig</span> and there are no
other DNs which may be modified. Therefore we can use the <span
style="font-weight: bold;">save_module_attributes()</span> function in
<span style="font-weight: bold;">accountContainer</span>. You can
always access the current <span style="font-weight: bold;">accountContainer</span>
with <span style="font-weight: bold;">$_SESSION[$this-&gt;base]</span>.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns a list of modifications which have to be
made to the LDAP account.<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array list of modifications<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;This function returns an array with 3
entries:<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;array( DN1 ('add' =&gt; array($attr),
'remove' =&gt; array($attr), 'modify' =&gt; array($attr)), DN2 .... )<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;DN is the DN to change. It may be
possible to change several DNs (e.g. create a new user and add him to
some groups via attribute memberUid)<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;"add" are attributes which have to be
added to LDAP entry<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;"remove" are attributes which have to be
removed from LDAP entry<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;"modify" are attributes which have to
been modified in LDAP entry<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">save_attributes</span>() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return
$_SESSION[$this-&gt;base]-&gt;save_module_attributes($this-&gt;attributes,
$this-&gt;orig);<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,109 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Basic concepts</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Basic concepts<br>
</h1>
<br>
<br>
<div style="text-align: left;"><br>
<h2>1. Licensing</h2>
LAM is licensed under the <a href="http://www.gnu.org/licenses/gpl.txt">GNU
General Public License</a>. This means your plugins need a compatible
license.<br>
LAM is distributed with a copy of the GPL license.<br>
<br>
<h2>2. Naming and position in directory structure</h2>
<br>
Module names are usually named after the object class they manage.
However, you can use any name you want, it should be short and
containing only a-z and 0-9. The module name is only shown in the
configuration dialog, on all other pages LAM will show a provided <span
style="font-style: italic;">alias</span> name.<br>
All account modules are stored in <span style="font-weight: bold;">lib/modules</span>.
The filename must end with <span style="font-weight: bold;">.inc</span>
and the file must have the same name as its inside class.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span>
Our example module will provide the <span style="font-weight: bold;">class
ieee802Devic</span><span style="font-style: italic; font-weight: bold;">e</span>,
therefore the file will be called <span style="font-weight: bold;">lib/modules/ieee802Devic</span><span
style="font-style: italic; font-weight: bold;">e.inc</span>.<span
style="font-style: italic;"></span><br>
<br>
<br>
<h2>3. Defining the class</h2>
All module classes have <span style="font-weight: bold;">baeModule</span>
as parent class. This provides common functionality and dummy functions
for all required class functions.<br>
<br>
<span style="font-weight: bold;">Example:</span><br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">/**<br>
* Provides MAC addresses for hosts.<br>
*<br>
* @package modules<br>
*/<span style="font-weight: bold;"><br>
class</span> <span style="color: rgb(255, 0, 0);">ieee802Device</span>
<span style="font-style: italic;">extends </span><span
style="font-weight: bold;">baseModule</span> {<br>
<br>
}<br>
</td>
</tr>
</tbody>
</table>
<br>
<h2>4. Meta data</h2>
The module interface inludes a lot of required and optional functions.
Many of these functions do not need to be implemented directly in the
module, you can define <span style="font-weight: bold;">meta data</span>
for them and the <span style="font-weight: bold;">baseModule</span>
will do the rest.<br>
Providing <span style="font-weight: bold;">meta data</span> is
optional, you can implement the required functions in your class, too.<br>
<br>
The <span style="font-weight: bold;">baseModule</span> reads the <span
style="font-weight: bold;">meta data</span> by calling <span
style="font-weight: bold;">get_metaData()</span> in your class.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">get_metaData</span>() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // manages host accounts<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return["account_types"] =
array("host");<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
You will see this functions several times in the next parts of this
HowTo.<br>
<br>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,253 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Configuration options</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Configuration options<br>
</h1>
<div style="text-align: left;"><br>
There might be situations where you want to give the user the
possibility to make general settings which are not useful to place on
the account detail pages or profile editor.<br>
Therefore LAM allows the modules to define their own configuration
options. E.g. the <span style="font-style: italic;">posixAccount</span>
module uses this to define the ranges for the UIDs.<br>
LAM will display your configuration options only if the user also
selected your module.<br>
</div>
<div style="text-align: left;"><br>
<h2>1. Defining configuration options<br>
</h2>
First you have to define what options you want to offer the user. LAM
will display all options in one fieldset for each module. Please notice
that there will be no separation on account types if you module is
suitable for different account types.<br>
<br>
The configuration options are specified with <span
style="font-weight: bold;">get_configOptions()</span>
or <span style="font-weight: bold;">meta['config_options']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">posixGroup</span> module offers
three configuration options. The min/maximum values for GIDs and the
password hash type.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;"> function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; // configuration options<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'config_options'</span>][<span
style="color: rgb(255, 0, 0);">'group'</span>] = array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;0 =&gt; array('kind' =&gt; 'text', 'text' =&gt; '&lt;b&gt;' .
_('Minimum GID number') . " *: &lt;/b&gt;"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;1 =&gt; array('kind' =&gt; 'input', 'name' =&gt;
'posixGroup_minGID', 'type' =&gt; 'text', 'size' =&gt; '10',
'maxlength' =&gt; '255'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;2 =&gt; array('kind' =&gt; 'text', 'value' =&gt; '&amp;nbsp;'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;3 =&gt; array('kind' =&gt; 'text', 'text' =&gt; '&lt;b&gt;' .
_('Maximum GID number') . " *: &lt;/b&gt;"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;4 =&gt; array('kind' =&gt; 'input', 'name' =&gt;
'posixGroup_maxGID', 'type' =&gt; 'text', 'size' =&gt; '10',
'maxlength' =&gt; '255'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;5 =&gt; array('kind' =&gt; 'help', 'value' =&gt; 'minMaxGID')),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;0 =&gt; array('kind' =&gt; 'text', 'text' =&gt; '&lt;b&gt;' .
_("Password hash type") . ': &amp;nbsp;&lt;/b&gt;'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;1 =&gt; array('kind' =&gt; 'select', 'name' =&gt;
'posixGroup_pwdHash', 'size' =&gt; '1',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'options' =&gt; array("CRYPT", "SHA", "SSHA", "MD5", "SMD5",
"PLAIN"), 'options_selected' =&gt; array('SSHA')),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;2 =&gt; array('kind' =&gt; 'text', 'value' =&gt; '&amp;nbsp;'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;3 =&gt; array('kind' =&gt; 'text', 'value' =&gt; '&amp;nbsp;'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;4 =&gt; array('kind' =&gt; 'text', 'value' =&gt; '&amp;nbsp;'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;5 =&gt; array('kind' =&gt; 'help', 'value' =&gt; 'pwdHash'))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
The min/maximum GID numbers are defined with simple text boxes. The
password hash is selected with a drop down box and SSHA as default
value.<br>
You should make sure that the column count (here: 6) is the same for
each row. Otherwise the configuration page might be badly rendered by
the browser.<br>
<br>
<h2>2. Checking user input</h2>
Probably you also want to check if the input data is syntactically
correct.<br>
The <span style="font-style: italic;">baseModule</span> already
provides different checks which can be activated with <span
style="font-style: italic;">meta data</span>. However you can also do
the checking in the module.<br>
Implementing the function <span style="font-weight: bold;">check_configOptions()</span>
in your module will allow you to do the checks yourself. Basic checks
can be defined with <span style="font-weight: bold;">meta['config_checks']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">posixGroup</span> module only
needs to check if the GID numbers are correct. The password hash type
needs not to be checked as it is a selection.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp; &nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;"> function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // configuration checks<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'config_checks'</span>][<span
style="color: rgb(255, 0, 0);">'group'</span>]['posixGroup_minGID'] =
array (<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'type' =&gt;
'ext_preg',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'regex' =&gt;
'digit',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'required'
=&gt; true,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'required_message' =&gt; $this-&gt;messages['gidNumber'][5],<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'error_message' =&gt; $this-&gt;messages['gidNumber'][5]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'config_checks'</span>][<span
style="color: rgb(255, 0, 0);">'group'</span>]['posixGroup_maxGID'] =
array (<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'type' =&gt;
'ext_preg',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'regex' =&gt;
'digit',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'required'
=&gt; true,<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'required_message' =&gt; $this-&gt;messages['gidNumber'][6],<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'error_message' =&gt; $this-&gt;messages['gidNumber'][6]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'config_checks'</span>][<span
style="color: rgb(255, 0, 0);">'group'</span>]['cmpGID'] = array (<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'type' =&gt;
'int_greater',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'cmp_name1'
=&gt; 'posixGroup_maxGID',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'cmp_name2'
=&gt; 'posixGroup_minGID',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'error_message' =&gt; $this-&gt;messages['gidNumber'][7]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
The type <span style="font-weight: bold;">"ext_preg"</span> means that
the <span style="font-style: italic;">baseModule</span> will use the <span
style="font-style: italic;">get_preg()</span> function in <span
style="font-style: italic;">lib/account.inc</span> for the syntax
check. This function already contains regular expressions for the most
common cases.<br>
To check if the minimum GID is smaller than the maximum GID we define a
check for the nonexistant option "cmpGID" and define it as optional.
This will do the comparison check.<br>
<br>
<br>
<h2>3. Descriptions</h2>
What is still missing is a descriptive title for the fieldset in the
configuration editor and a description for each configuration option
which is displayed when the user saves the settings.<br>
<br>
These descriptions are defined with <span style="font-weight: bold;">get_configDescriptions()</span>
or <span style="font-weight: bold;">meta['config_descriptions']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">posixGroup</span> module will
set a title for the fieldset and a description for the three
configuration options.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp; &nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;"> function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; // configuration descriptions<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'config_descriptions'</span>] = array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'legend' =&gt;
_("GID ranges for Unix groups"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'descriptions'
=&gt; array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'posixGroup_minGID' =&gt; _("Minimum GID number for Unix groups"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'posixGroup_maxGID' =&gt; _("Maximum GID number for Unix groups"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'posixGroup_pwdHash' =&gt; _("Password hash type for Unix
groups"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
This will set the fieldset title to "GID ranges for Unix groups" and
the descriptions for the settings list.<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,198 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - General module options</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - General module options<br>
</h1>
<br>
<br>
<div style="text-align: left;"><br>
<h2>1. Account types<br>
</h2>
LAM currently provides three account types: <span
style="font-weight: bold;">users, groups, hosts<br>
</span>A module can manage one or more account types.<br>
<br>
The types are specified with <span style="font-weight: bold;">can_manage()</span>
or <span style="font-weight: bold;">meta['account_types']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
Our <span style="font-style: italic;">ieee802Device</span>
module will be used only for host accounts.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // manages host accounts<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; $return["account_types"] = array("host");</span><br
style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>2. Alias name</h2>
The module name is very limited, therefore every module has an <span
style="font-style: italic;">alias name</span>. This <span
style="font-style: italic;">alias name</span> has no limitations and
can be translated. It may contain special characters but make sure that
it does not contain HTML special characters like "&lt;".<br>
The <span style="font-style: italic;">alias name </span>can be the
same for all managed <span style="font-style: italic;">account types</span>
or differ for each type.<br>
<br>
The <span style="font-style: italic;">alias name</span> is specified
with <span style="font-weight: bold;">get_alias()</span>
or <span style="font-weight: bold;">meta['alias']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
Our <span style="font-style: italic;">ieee802Device</span>
module will get the alias MAC address.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // manages host accounts<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; </span>$return["account_types"] = array("host");<br
style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // alias name<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;$return["alias"] = _("MAC address");</span><br
style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>3. Dependencies</h2>
Modules can depend on eachother. This is useful if you need to access
attributes from other modules or the managed object classes of your
module are not structural.<br>
<br>
The dependencies are specified with <span style="font-weight: bold;">get_dependencies()</span>
or <span style="font-weight: bold;">meta['dependencies']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
Our <span style="font-style: italic;">ieee802Device</span>
module depends on the account module (because it is the only structural
module at this time).<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // manages host accounts<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; </span>$return["account_types"] = array("host");<br
style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // alias name<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return["alias"] = _("MAC
address");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // module dependencies<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;$return['dependencies'] = array('depends' =&gt;
array('account'), 'conflicts' =&gt; array());</span><br
style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>4. Messages</h2>
There are many situations where you will display messages to the user.
The modules should define such messages at a common place to make it
easier to modify them without searching the complete file.<br>
The <span style="font-style: italic;">baseModule</span> offers the $<span
style="font-weight: bold;">messages</span> variable for this. It
should be filled by a function called <span style="font-weight: bold;">load_Messages()</span>.<br>
The <span style="font-style: italic;">baseModule</span> will
automatically check if you have implemented this function and call it
at construction time.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
Now let our <span style="font-style: italic;">ieee802Device</span>
module define a message.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * This function fills the error message array with
messages<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">load_Messages</span>() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;messages['mac'][0] =
array('ERROR', 'MAC address is invalid!');&nbsp; // third array value
is set dynamically<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2><br>
</h2>
<h2></h2>
<br>
<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,88 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Help entries</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Help entries<br>
</h1>
<br>
<br>
<div style="text-align: left;"><br>
<h2>1. Defining help entries<br>
</h2>
Your module should provide help for all input fields and other
important things.<br>
The LAM help system defines an extra ID range for each module. So you
are free in defining your own IDs.<br>
<br>
The help entries are specified with <span style="font-weight: bold;">get_help()</span>
or <span style="font-weight: bold;">meta['help']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span>
module needs help entries for the MAC address.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; $return = array();<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp; // help Entries</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;$return['help'] = array(</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'mac' =&gt; array(</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;"Headline"
=&gt; _("MAC address"),</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;"Text" =&gt;
_("This is the MAC address of the network card of the device (e.g.
00:01:02:DE:EF:18).")</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;),</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'macList' =&gt; array(</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;"Headline"
=&gt; _("MAC address list"),</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;"Text" =&gt;
_("This is a comma separated list of MAC addresses.")</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;));</span><br
style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,58 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>LAM module HowTo</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo</h1>
<br>
<br>
<div style="text-align: left;">
<h2>Basic functions</h2>
<br>
</div>
<div style="text-align: left;">LAM can be easily extended to support
additional LDAP object classes and attributes.<br>
This document provides a step-by-step description to build an account
module. The <span style="font-style: italic;">ieee802Device</span>
module which provides MAC addresses for hosts is used as example.<br>
<br>
<h3><a href="mod_basics.htm">1. Basic concepts</a><br>
</h3>
<br>
<h3><a href="mod_general.htm">2. General module options</a></h3>
<br>
<h3><a href="mod_accountPages.htm">3. Account pages</a></h3>
<br>
<h3><a href="mod_help.htm">4. Help entries<br>
</a></h3>
<br>
<h3><a href="mod_pdf.htm">5. PDF output<br>
</a></h3>
<br>
<h3><a href="mod_upload.htm">6. File upload</a></h3>
<br>
<br>
<br>
<hr style="width: 100%; height: 2px;"><br>
<br>
<h2>Advanced functions</h2>
This part covers additional functionality of the modules which are only
needed by a minority of modules. The examples are taken from different
existing modules.<br>
<br>
<h3><a href="mod_profiles.htm">1. Account profiles</a></h3>
<br>
<h3><a href="mod_config.htm">2. Configuration options</a></h3>
<br>
<h3><a href="mod_upload2.htm">3. Advanced upload options</a></h3>
<br>
<h3><a href="mod_rdn.htm">4. Defining the RDN</a></h3>
<br>
<br>
</div>
</div>
</body>
</html>

View File

@ -1,106 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - PDF output</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - PDF output<br>
</h1>
<br>
<br>
<div style="text-align: left;"><br>
<h2>1. Defining possible PDF values<br>
</h2>
The first step to PDF output is defining what values your module
provides. This is needed for the PDF editor, otherwise the user will
not be able to select values from your module.<br>
<br>
The PDF values are specified with <span style="font-weight: bold;">get_pdfFields()</span>
or <span style="font-weight: bold;">meta['PDF_fields']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span>
module has only one attribute and therefore one PDF value: the MAC
address.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
[...]<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // available PDF fields<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; $return['PDF_fields'] = array(</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'macAddress'</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; );</span><br style="color: rgb(255, 0, 0);">
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>2. Providing data to put into the PDF file<br>
</h2>
When the user wants to create a PDF file the LDAP account is loaded and
you module is asked for data to put into the PDF file.<br>
<br>
This is done with <span style="font-weight: bold;">get_pdfEntries()</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span>
module will return the MAC address list of the account.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp; &nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns a list of PDF entries<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; function get_pdfEntries() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(sizeof($this-&gt;attributes['macAddress']) &gt; 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$return['ieee802Device_macAddress'] = '&lt;block&gt;&lt;key&gt;' .
_('MAC address list') . '&lt;/key&gt;&lt;value&gt;' . implode(', ',
$this-&gt;attributes['macAddress']) . '&lt;/value&gt;&lt;/block&gt;';<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<br>
<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,162 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Account profiles</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Account profiles<br>
</h1>
<div style="text-align: left;"><br>
Account profiles make it easy to set default values for new accounts
and even to reset an existing account to default values.<br>
Your module should provide the possibility to define default values for
all attributes which do not differ for each account.<br>
</div>
<div style="text-align: left;"><br>
<h2>1. Defining possible profile options<br>
</h2>
The first step to account profiles is defining the attributes for which
the user can set default values. You will also have to define the type
(text, checkbox, ...) of the profile options.<br>
The profile editor then will display a fieldset for each module
containing its profile options.<br>
<br>
The profile options are specified with <span style="font-weight: bold;">get_profileOptions()</span>
or <span style="font-weight: bold;">meta['profile_options']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">inetOrgPerson</span>
module has only two attributes which may be set to a default value: job
title and employee type.<br>
The other attributes are account specific and not useful as profile
options.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // profile elements<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return[<span
style="color: rgb(255, 0, 0);">'profile_options'</span>] = array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 0 =&gt; array('kind' =&gt; 'text', 'text' =&gt;
_('Job title') . ":"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 1 =&gt; array('kind' =&gt; 'input', 'name' =&gt;
'inetOrgPerson_title', 'type' =&gt; 'text', 'size' =&gt; '30',
'maxlength' =&gt; '255'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 2 =&gt; array('kind' =&gt; 'help', 'value' =&gt;
'title')),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 0 =&gt; array('kind' =&gt; 'text', 'text' =&gt;
_('Employee type') . ":"),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 1 =&gt; array('kind' =&gt; 'input', 'name' =&gt;
'inetOrgPerson_employeeType', 'type' =&gt; 'text', 'size' =&gt; '30',
'maxlength' =&gt; '255'),<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 2 =&gt; array('kind' =&gt; 'help', 'value' =&gt;
'employeeType'))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
This defines two text boxes in the profile editor, one for the job
title and one for the employee type.<br>
Your profile options should also provide a help link if the description
of the input element might be not enough.<br>
<br>
<br>
<h2>2. Checking user input</h2>
Probably you also want to check if the input data is syntactically
correct.<br>
The <span style="font-style: italic;">baseModule</span> already
provides different checks which can be activated with <span
style="font-style: italic;">meta data</span>. However you can also do
the checking in the module.<br>
Implementing the function <span style="font-weight: bold;">check_profileOptions()</span>
in your module will allow you to do the checks yourself. Basic checks
can be defined with <span style="font-weight: bold;">meta['profile_checks']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">inetOrgPerson</span> module only
needs some regular expression checks on the input. This can be done by
the <span style="font-style: italic;">baseModule</span>.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // profile checks<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'profile_checks'</span>][<span
style="color: rgb(255, 0, 0);">'inetOrgPerson_title'</span>] = array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'type' =&gt;
'ext_preg',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'regex' =&gt;
'title',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'error_message' =&gt; $this-&gt;messages['title'][0]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'profile_checks'</span>][<span
style="color: rgb(255, 0, 0);">'inetOrgPerson_employeeType'</span>] =
array(<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'type' =&gt;
'ext_preg',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'regex' =&gt;
'employeeType',<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;'error_message' =&gt; $this-&gt;messages['employeeType'][0]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
The type <span style="font-weight: bold;">"ext_preg"</span> means that
the <span style="font-style: italic;">baseModule</span> will use the <span
style="font-style: italic;">get_preg()</span> function in <span
style="font-style: italic;">lib/account.inc</span> for the syntax
check. This function already contains regular expressions for the most
common cases.<br>
<br>
<br>
<h2>3. Loading an account profile</h2>
<br>
TODO<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,59 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Defining the RDN</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Defining the RDN<br>
</h1>
<div style="text-align: left;"><br>
Every LDAP DN starts with a RDN (relative DN). This is the value of a
LDAP attribute. Users usually use "uid", groups use "cn".<br>
You can provide a list of suitable RDN attributes for your module and
give them a priority, too.<br>
<br>
</div>
<div style="text-align: left;">You will need to implement the function <span
style="font-weight: bold;">get_RDNAttributes()</span> or use <span
style="font-weight: bold;">meta['RDN']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">posixAccount</span> module
offers to create accounts with DNs uid=foo,dc=.... and cn=foo,dc=...<br>
The uid attribute has a higher priority as it is the usual attribute
for Unix accounts.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;"> function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // RDN attributes<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return["RDN"] = array("uid"
=&gt; "normal", "cn" =&gt; "low");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,171 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - File upload</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - File upload<br>
</h1>
<br>
<br>
<div style="text-align: left;"><br>
<h2>1. Defining upload columns<br>
</h2>
If you want to support account creation via file upload you have to
define columns in the CSV file.<br>
Each column has an non-translated identifier, a description, help entry
and several other values.<br>
<br>
The upload columns are specified with <span style="font-weight: bold;">get_uploadColumns()</span>
or <span style="font-weight: bold;">meta['upload_columns']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span>
module has only one attribute and therefore one column: the MAC address.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // manages host accounts<br>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; $return["account_types"] = array("host");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // upload fields<br>
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; $return['upload_columns'] = array(</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;array(</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'name' =&gt;
'ieee802Device_mac',</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'description'
=&gt; _('MAC address'),</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'help' =&gt;
'mac',</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;'example'
=&gt; '00:01:02:DE:EF:18'</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; )</span><br
style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">&nbsp;&nbsp; &nbsp;
&nbsp;&nbsp; );</span><br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $return;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>2. Building the accounts<br>
</h2>
When the user has uploaded the CSV file the modules have to transform
the input data to LDAP accounts.<br>
<br>
This is done with <span style="font-weight: bold;">build_uploadAccounts()</span>.
The function gets the input data and a list of LDAP accounts as
parameter.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">ieee802Device</span>
module has only one LDAP attribute - <span style="font-style: italic;">'macAddress'</span>
- and the <span style="font-style: italic;">'ieee802Device'</span>
objectClass which is added to all accounts.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * In this function the LDAP account is built up.<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @param array $rawAccounts list of hash arrays
(name =&gt; value) from user input<br>
&nbsp;&nbsp;&nbsp; * @param array $partialAccounts list of hash arrays
(name =&gt; value) which are later added to LDAP<br>
&nbsp;&nbsp;&nbsp; * @param array $ids list of IDs for column position
(e.g. "posixAccount_uid" =&gt; 5)<br>
&nbsp;&nbsp;&nbsp; * @return array list of error messages if any<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">build_uploadAccounts</span>($rawAccounts,
$ids, &amp;$partialAccounts) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $messages = array();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for ($i = 0; $i &lt;
sizeof($rawAccounts); $i++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // add object
class<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
(!in_array("ieee802Device", $partialAccounts[$i]['objectClass']))
$partialAccounts[$i]['objectClass'][] = "ieee802Device";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // add MACs<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
($rawAccounts[$i][$ids['ieee802Device_mac']] != "") {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; $macs = explode(',',
$rawAccounts[$i][$ids['ieee802Device_mac']]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; // check format<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; for ($m = 0; $m &lt; sizeof($macs); $m++) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (get_preg($macs[$m],
'macAddress')) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
$partialAccounts[$i]['macAddress'][] = $macs[$m];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $errMsg =
$this-&gt;messages['mac'][1];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
array_push($errMsg, array($i));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $messages[] =
$errMsg;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $messages;<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<br>
<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,122 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Module HowTo - Advanced upload options</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<div style="text-align: center;">
<h1>Module HowTo - Advanced upload options<br>
</h1>
<div style="text-align: left;"><br>
The <span style="font-style: italic;">ieee802Device</span> module only
needs the basic upload functions for its functionality.<br>
However there are more possibilities for the modules to control the
file upload.<br>
</div>
<div style="text-align: left;"><br>
<h2>1. Module order<br>
</h2>
Your module might depend on the input values of another module. In this
case you probably want that your module is called as the second one.<br>
<br>
You can define dependencies to other modules with the function <span
style="font-weight: bold;">get_uploadPreDepends()</span> or <span
style="font-weight: bold;">meta['upload_preDepends']</span>.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">sambaGroupMapping</span> module
needs the group name to set the default <span
style="font-style: italic;">displayName</span>. Therefore it depends
on the <span style="font-style: italic;">posixGroup</span> module<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * Returns meta data that is interpreted by parent
class<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @return array array with meta data<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;"> function</span>
get_metaData() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $return = array();<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; // upload dependencies<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;$return[<span
style="color: rgb(255, 0, 0);">'upload_preDepends'</span>] =
array('posixGroup');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>2. Upload post actions<br>
</h2>
If your module does not only create an account but relates the account
with other existing LDAP entries you can do these modifications after
the account was created.<br>
This is useful for adding users to groups or setting quotas.<br>
<br>
You have to implement the function <span style="font-weight: bold;">doUploadPostActions()</span>
in your module. Since post actions are very special there is no <span
style="font-style: italic;">meta data</span> for this.<br>
<br>
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
style="font-weight: bold; text-decoration: underline;">
<br>
The <span style="font-style: italic;">posixAccount</span> module
offers to put the user account in additional groups. This is done in
the post actions.<br>
<br>
<table style="width: 100%; text-align: left;" class="mod-code"
border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">&nbsp;&nbsp;&nbsp; /**<br>
&nbsp;&nbsp;&nbsp; * This function executes one post upload action.<br>
&nbsp;&nbsp;&nbsp; *<br>
&nbsp;&nbsp;&nbsp; * @param array $data array containing one account in
each element<br>
&nbsp;&nbsp;&nbsp; * @param array $ids array(&lt;column_name&gt; =&gt;
&lt;column number&gt;)<br>
&nbsp;&nbsp;&nbsp; * @param array $failed list of accounts which were
not created successfully<br>
&nbsp;&nbsp;&nbsp; * @param array $temp variable to store temporary
data between two post actions<br>
&nbsp;&nbsp;&nbsp; * @return array current status<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt; array (<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;&nbsp; 'status' =&gt; 'finished' |
'inProgress'<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;&nbsp; 'progress' =&gt; 0..100<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt;&nbsp; 'errors' =&gt; array (&lt;array
of parameters for StatusMessage&gt;)<br>
&nbsp;&nbsp;&nbsp; * &lt;br&gt; )<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">function</span> <span
style="color: rgb(255, 0, 0);">doUploadPostActions</span>($data, $ids,
$failed, &amp;$temp) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]<br>
&nbsp;&nbsp;&nbsp; }<br>
</td>
</tr>
</tbody>
</table>
<br>
Please make sure that the actions in one call of <span
style="font-weight: bold;">doUploadPostActions()</span> are not very
time consuming (only one LDAP operation). Your function will be called
repeatedly until you give back the status "finished".<br>
This allows LAM to avoid running longer than the maximum execution time
by sending meta refreshes to the browser.<br>
<span style="font-weight: bold;"></span>
<h2><span style="font-weight: bold;"></span></h2>
</div>
</div>
</body>
</html>

View File

@ -1,33 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Other libraries</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Other libraries<br>
</h1>
<br>
<h2><a name="lamdaemon"></a>Lamdaemon (lamdaemon.pl)<br>
</h2>
<h2><a name="blowfish"></a>Blowfish (blowfish.inc)</h2>
If MCrypt is not available LAM uses the Blowfish algorithm to store
sensitive data in the session file.<br>
This file was copied from the <span style="font-style: italic;">Horde</span>
project and modified to fit LAM's needs.<br>
<br>
<h2><a name="cache"></a>LDAP cache (cache.inc)</h2>
<br>
<h2><a name="lists"></a>Account lists (lists.inc)</h2>
This file provides basic functions used by the account lists. They
cover major parts of the HTML output.<br>
There is also one list of LDAP attribute descriptions per account type.
They allow to have translated descriptions of the most common
attributes.<br>
<br>
<h2><a name="status"></a>Status messages (status.inc)<br>
</h2>
</body>
</html>

View File

@ -1,89 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Profile editor</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Profile editor<br>
</h1>
<div style="text-align: center;"><img alt="profile editor"
src="images/lam_profedit.png" style="width: 502px; height: 236px;"><br>
</div>
<div style="text-align: center;"><br>
<div style="text-align: left;">The <span style="font-style: italic;">profile
editor</span> allows the user to set default values for new accounts.<br>
These defaults are saved as files in <span style="font-weight: bold;">config/profiles</span>.<br>
<br>
<h2>Profilemain.php<br>
</h2>
This is the start page of the <span style="font-style: italic;">profile
editor</span>. The user can select to add/modify/remove selected
account profiles.<br>
<br>
The list of existing account profiles is returned by <span
style="font-weight: bold;">getAccountProfiles()</span> in <span
style="font-style: italic;">modules.inc</span>. It includes all
profile names without file extensions.<br>
<br>
<h2>Profilepage.php<br>
</h2>
This script is used to display the account profile to the user. <br>
<br>
The profile options include the LDAP OU suffix and options provided by
the account modules.<br>
<br>
The values for the OU selection are read with <span
style="font-weight: bold;">search_units()</span>.<br>
<br>
The <span style="font-style: italic;">account modules</span> provide
all other profile options. The profile editor displays a separate
fieldset for each module containing its options.<br>
The function <span style="font-weight: bold;">print_option()</span>
manages the display of the different option types (checkbox, select,
...). The type of each option is saved in <span
style="font-weight: bold;">$_SESSION['profile_types']</span>.<br>
See the <a href="../modules-specification.htm">modules specification</a>
for a complete list of supported types.<br>
<br>
The profiles have unique names under which they are saved. If a profile
with the same name already exists it will be overwritten.<br>
When the user selects to save the profile he will be redirected to
profilecreate.php.<br>
<br>
<h2>Profilecreate.php</h2>
This script takes the values which were entered in profilepage.php and
checks them for correctness. <br>
<br>
First the values are converted to the correct type (checkbox -&gt;
Boolean) by checking <span style="font-weight: bold;">$_SESSION['profile_types']</span>.<br>
<br>
Then LAM will replace all "\'" with&nbsp; "'" if <span
style="font-style: italic;">magic_quotes_gpc</span> is on.<br>
<br>
Now the input data is checked for correctness by calling <span
style="font-weight: bold;">checkProfileOptions()</span>. The <span
style="font-style: italic;">account modules</span> return a list of
error messages if one or more options are incorrect.<br>
If there are errors they will be displayed, otherwise the profile is
saved by calling <span style="font-weight: bold;">saveAccountProfile()</span>.<br>
<br>
<h2>Profiledelete.php</h2>
When the user selected to delete a profile in <span
style="font-style: italic;">profilemain.php</span> he is redirected to
this page.<br>
<br>
LAM will ask once again if the user is sure to delete the profile. If
this is the case the profile will be deleted with <span
style="font-weight: bold;">delAccountProfile()</span> from <span
style="font-style: italic;">profiles.inc</span>.<br>
<br>
<br>
<br>
<br>
</div>
</div>
</body>
</html>

View File

@ -1,36 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Account profiles</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">Account profiles</h1>
<br>
Every account profile is saved as single file in <span
style="font-weight: bold;">config/profiles</span>. The
file extension is the account type (user, group, ...).<br>
In contrast to the configuration profiles the account profiles are not
designed to be editable by hand. They do not allow to add comments and
have a simpler format.<br>
<br>
<h2>Format</h2>
There is one option per line which is formated: &lt;identifier&gt;:
&lt;value&gt;<br>
<br>
Identifier is the option's name, value is the rest of the line after
the first <span style="font-weight: bold;">": "</span>.<br>
Some options are multi-valued, the sub-values are separated by <span
style="font-weight: bold;">"+::+"</span>.<br>
<br>
<br>
<span style="font-weight: bold;">Examples:</span><br
style="font-weight: bold;">
<br>
posixAccount_primaryGroup: group1<br>
posixAccount_additionalGroup: group3+::+group4+::+group5+::+group6<br>
<br>
</body>
</html>

View File

@ -1,25 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>Account profiles</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">profiles.inc</h1>
<br>
This file includes all functions to manage <a href="profile_files.htm">account
profiles</a>. You can read/store/list/delete profiles.<br>
<br>
Profile names may contain letters, numbers, "_" and "-". All functions
which have a profile name as parameter check this.<br>
Functions which modify the filesystem (<span style="font-style: italic;">saveAccountProfile,
delAccountProfile</span>) also check if the user is logged in to LAM
for security reasons. This is done by reading <span
style="font-style: italic;">$_SESSION['logedIn']</span>.<br>
<br>
<br>
<br>
</body>
</html>

View File

@ -1,57 +0,0 @@
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2004 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more detaexils.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* CSS layout for LAM development documentation */
h1,h2,h3,h4 {
color:#0c12b7;
}
/* links */
a {
color:blue;
text-decoration:none;
}
a:visited {
color:blue;
text-decoration:none;
}
a:hover {
color:red;
text-decoration:none;
}
a:active {
color:red;
text-decoration:none;
}
/* module HowTo */
table.mod-code {
background-color:#fffde2;
}

View File

@ -1,102 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-15"
http-equiv="content-type">
<title>File upload</title>
<link rel="stylesheet" type="text/css" href="style/layout.css">
</head>
<body>
<h1 style="text-align: center;">File upload<br>
</h1>
<br>
<div style="text-align: center;"><img
style="width: 886px; height: 162px;" alt="upload"
src="images/lam_upload.png"><br>
<div style="text-align: left;"><br>
<h2>Account selection (masscreate.php)<br>
</h2>
This is the initial page of the file upload. The user selects the
account type for the new upload.<br>
<br>
<br>
<h2>Attribute overview (masscreate.php)</h2>
After the account selection LAM will display an overview of the
possible and required input columns.<br>
The <span style="font-style: italic;">DN</span> attributes (<span
style="font-style: italic;">DN suffix</span> and <span
style="font-style: italic;">RDN</span>) are static and are always
displayed. The default suffix is read from config with <span
style="font-weight: bold;">getAccountSuffix()</span> and the list of
RDN possibilities is taken from modules.inc - <span
style="font-weight: bold;">getRDNAttributes()</span>.<br>
The next attributes are read from modules.inc - <span
style="font-weight: bold;">getUploadColumns()</span>. LAM will display
all attributes of one module in a separate fieldset. The <span
style="font-weight: bold;">getUploadColumns()</span> function also
returns if an attribute is required and additional information like an
example value.<br>
<br>
After clicking the upload button the user will be forwarded to the
account building page.<br>
<br>
<br>
<h2>Account building (massBuildAccounts.php)<br>
</h2>
This part takes the submitted <span style="font-weight: bold;">CSV file</span>
and generates the LDAP accounts.<br>
<br>
The scripts separates the head row from the data rows in the CSV file.
The head array is used to find the position of the input values. The
data array contains one subarray for each account.<br>
<br>
After the data has been extracted there are some basic checks done,
e.g. checking required and unique columns. The modules provide the
necessary information for this.<br>
<br>
Then all data is given to the modules with <span
style="font-weight: bold;">buildUploadAccounts()</span> in
modules.inc. They return a list of accounts which can be uploaded with <span
style="font-style: italic;">ldap-add()</span> and generate possible
error messages.<br>
<br>
If the accounts are built the script will give the user the possibility
to check the result with an <span style="font-style: italic;">LDIF-file</span>
or to do the upload.<br>
<br>
<br>
<h2>LDIF export (massBuildAccounts.php)<br>
</h2>
LAM simply takes the built accounts and generates an <span
style="font-style: italic;">LDIF-file</span> from them. This is passed
to the user's browser.<br>
The <span style="font-style: italic;">LDIF-file</span> will only
contain the accounts itself. If modules do additional tasks after the
upload (e.g. adding users to groups) this will not be covered.<br>
<br>
<br>
<h2>Account creation (massDoUpload.php)<br>
</h2>
This script finally uploads the LDAP accounts with <span
style="font-style: italic;">ldap_add()</span>.<br>
<br>
The upload can last longer than the maximum execution time of PHP.
Therefore the script will check regulary how much time is left and
pause the upload. This is resumed with a meta refresh which loads the
script again.<br>
<br>
After all accounts were created in LDAP the modules may do additional
tasks. LAM will call <span style="font-weight: bold;">doUploadPostActions()</span>
and also provide a list of failed accounts which can be ignored. The
function is called as long the returned status is <span
style="font-style: italic;">"inProgress"</span>. The script uses again
a
meta refresh to handle the maximum execution time.<br>
Typical post actions are setting quotas or adding an user to groups.<br>
<br>
A progress bar is shown for the LDAP adding and the module actions to
give the user a hint how long it will still take.<br>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,28 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 Michael Duergner
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
LDAP Account Manager example file for external help pages.
*/
?>
<h1 class="help"><?php echo "Help test"; ?></h1>
<p class="help"><?php echo "Some text descibing the error"; ?></p>
<p class="help"><?php echo "Optionalle some links to referring help topics"; ?></p>

View File

@ -1,262 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 Michael Duergner
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
LDAP Account Manager help topics.
*/
/**
* LDAP Account Manager help entries.
*
* @author Michael Dürgner
* @version 0.5
* @package Help
* @copyright Copyright (C) 2003-2004 Michael Dürgner
* @license GPL
*/
setlanguage();
$helpArray = array (
// 0 - 99
// any developer
// 200 - 299
// Roland Gruber
// configuration wizard
// configuration login
// config profile management
"200" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Login"),
"Text" => _("Please enter the configuration password. This is NOT your LDAP password. It is stored in your .conf-file. If this is the first time you log in, enter \"lam\".")),
"201" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Server address"),
"Text" => _("This is the server address of your LDAP server. Use ldap:// for standard LDAP connections and ldaps:// for encrypted (require server certificates) connections. The port value is optional.") .
"<br><br><b> " .
_("Examples") .
":</b><br><br> " .
_("ldap://localhost:389 connects to localhost using a standard LDAP connection on port 389") .
"<br> " .
_("ldaps://141.40.146.133 connects to 141.40.146.133 using an encrypted LDAP connection.") .
"<br><br><br><b> " .
_("Note") .
":</b><br><br>" .
_("When using ldaps:// be sure to use exactly the same IP/domain name as in your certificate!")),
"202" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("User/Group/Host suffix"),
"Text" => _("This is the suffix of the LDAP tree from where to search for user/group/host entries. Only entries in these subtrees will be displayed in the user/group/host list. When creating a new accont this will be the DN where it is saved.") .
"<br><br><b>".
_("Examples").
":</b><br><br>".
_("ou=People,dc=yourcompany,dc=com will read and store all accounts in this subtree.")),
"206" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("List attributes"),
"Text" => _("This is the list of attributes to show in the user/group/host list. The entries can either be predefined values, \"#attribute\", or individual ones, \"attribute:description\". Several entries are seperated by semicolons.") .
"<br><br><b>" .
_("Example") .
": </b>#homeDirectory;#uid;#uidNumber;#gidNumber;mail:Mail address<br><br><br><u><b>" .
_("Predefined values") .
":</b></u><br><br><b>" .
_("Users") .
": </b>#uid, #uidNumber, #gidNumber, #cn, #host, #givenName, #sn, #homeDirectory, #loginShell, #mail, #gecos".
"<br><b>" .
_("Groups") .
": </b>#cn, #gidNumber, #memberUID, #member, #description".
"<br><b>" .
_("Hosts") .
": </b>#uid, #cn, #rid, #description"),
"207" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Valid users"),
"Text" => _("This is a list of valid DN entries of all users that are allowed to login to LDAP Account Manager. The user names have to be separated by semicolons.") .
"<br><br><b>" .
_("Example") .
": </b>cn=admin,dc=yourdomain,dc=org;cn=manager,dc=yourdomain,dc=org"),
"208" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Maximum list entries"),
"Text" => _("This is the number of rows to show in the user/group/host list. If more entries are found the list will be split into several pages.")),
"209" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Default language"),
"Text" => _("This defines the language of the login window and sets this language as the default language. Users can change the language at login.")),
"210" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Script path"),
"Text" => _("This is the absolute path to an external script for setting quotas and creating home directories.").
"<br><br><b>".
_("Use it at your own risk and read the documentation for lamdaemon before you use it!").
"</b>"),
"211" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Script server"),
"Text" => _("This is the server where the lamdaemon script is stored. LDAP Account Manager will make a SSH connection to this server with username and password provided at login.").
"<br><br><b>".
_("Use it at your own risk and read the documentation for lamdaemon before you use it!").
"</b>"),
"212" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Change password"),
"Text" => _("If you want to change the current preferences password, please enter it here.")),
"214" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Cache timeout"),
"Text" => _("This is the time in minutes which LAM caches its LDAP searches. Shorter times will stress LDAP more but decrease the possibility that changes are not identified.")),
"216" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Text for user PDF"),
"Text" => _("This text will appear on top of every user PDF file.")),
"217" => array ("ext" => "FALSE", "Headline" => _("Configuration wizard") . " - " . _("Account modules"),
"Text" => _("Here you can select which plugins you want to use for account management.")),
"230" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Add profile"),
"Text" => _("Please enter the name of the new profile and the password to change its settings. Profile names may contain letters, numbers and -/_.")),
"231" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Rename profile"),
"Text" => _("Please enter the new name of the profile. The name may contain letters, numbers and -/_.")),
"232" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Delete profile"),
"Text" => _("This will delete the selected profile.")),
"233" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Set profile password"),
"Text" => _("This changes the password of the selected profile.")),
"234" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Change default profile"),
"Text" => _("This changes the profile which is selected by default at login.")),
"235" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Change master password"),
"Text" => _("If you want to change your master configuration password, please enter it here.")),
"236" => array ("ext" => "FALSE", "Headline" => _("Profile management") . " - " . _("Master password"),
"Text" => _("Please enter the master configuration password. This is NOT your LDAP password. It is stored in your config.cfg file. If this is the first time you log in, enter \"lam\".")),
// 300 - 399
// Roland Gruber
// profile editor, file upload
"301" => array ("ext" => "FALSE", "Headline" => _("RDN identifier"),
"Text" => _("This is the identifier for the relative DN value. It must be one of the given allowed LDAP attributes (e.g. user accounts usually use \"uid\" while groups use \"cn\").")),
"360" => array ("ext" => "FALSE", "Headline" => _("Profile name"),
"Text" => _("Name under which the profile will be saved. If a profile with the same name exists, it will be overwritten.")),
"361" => array ("ext" => "FALSE", "Headline" => _("DN suffix"),
"Text" => _("The new account will be saved under this LDAP suffix.")),
// 400 - 499
// Tilo Lutz
// account.php
"400" => array ("ext" => "FALSE", "Headline" => _("Username"),
"Text" => _("Username of the user who should be created. Valid characters are: a-z,0-9, .-_. Lam does not allow a number as first character because useradd also does not allow it. Lam does not allow capital letters A-Z because it can cause several problems. If username is already used username will be expanded with a number. The next free number will be used. Warning: Older systems have problems with usernames longer than 8 characters. You can not log in to Windows if username is longer than 16 characters.")),
"401" => array ("ext" => "FALSE", "Headline" => _("UID number"),
"Text" => _("If empty UID number will be generated automaticly.")),
"402" => array ("ext" => "FALSE", "Headline" => _("Additional groups"),
"Text" => _("Hold the CTRL-key to (de)select multiple groups."). ' '. _("Can be left empty.")),
"403" => array ("ext" => "FALSE", "Headline" => _("Home directory"),
"Text" => _("$user and $group are replaced with username or primary groupname.")),
"404" => array ("ext" => "FALSE", "Headline" => _("Gecos"),
"Text" => _("User description. If left empty sur- and give name will be used.")),
"405" => array ("ext" => "FALSE", "Headline" => _("Login shell"),
"Text" => _("To disable login use /bin/false. List of shells is read from lam/config/shells")),
"406" => array ("ext" => "FALSE", "Headline" => _("Primary group"),
"Text" => _("The Primary Group the user should be member of.")),
"407" => array ("ext" => "FALSE", "Headline" => _("Groupname"),
"Text" => _("Group name of the group which should be created. Valid characters are: a-z,0-9, .-_. Lam does not allow a number as first character because groupadd also does not allow it. Lam does not allow capital letters A-Z because it can cause several problems. If groupname is already used groupname will be expanded with a number. The next free number will be used.")),
"408" => array ("ext" => "FALSE", "Headline" => _("GID number"),
"Text" => _("If empty GID number will be generated automaticly depending on your configuration settings.")),
"409" => array ("ext" => "FALSE", "Headline" => _("Gecos"),
"Text" => _("Group description. If left empty group name will be used.")),
"410" => array ("ext" => "FALSE", "Headline" => _("Host name"),
"Text" => _("Host name of the host which should be created. Valid characters are: a-z,0-9, .-_$. Lam does not allow a number as first character because useradd also does not allow it. Lam does not allow capital letters A-Z because it can cause several problems. Hostnames are always ending with $. If last character is not $ it will be added. If hostname is already used hostname will be expanded with a number. The next free number will be used.")),
"411" => array ("ext" => "FALSE", "Headline" => _("UID number"),
"Text" => _("If empty UID number will be generated automaticly.")),
"412" => array ("ext" => "FALSE", "Headline" => _("Primary group"),
"Text" => _("The Primary group the host should be member of.")),
"413" => array ("ext" => "FALSE", "Headline" => _("Gecos"),
"Text" => _("Host description. If left empty host name will be used.")),
"414" => array ("ext" => "FALSE", "Headline" => _("Password warn"),
"Text" => _("Days before password is to expire that user is warned of pending password expiration. If set value must be 0<."). ' '. _("Can be left empty.")),
"415" => array ("ext" => "FALSE", "Headline" => _("Password expire"),
"Text" => _("Number of days a user can login even his password has expired. -1=always."). ' '. _("Can be left empty.")),
"416" => array ("ext" => "FALSE", "Headline" => _("Maximum password age"),
"Text" => _("Number of days after a user has to change his password again. If set value must be 0<."). ' '. _("Can be left empty.")),
"417" => array ("ext" => "FALSE", "Headline" => _("Minimum password age"),
"Text" => _("Number of days a user has to wait until he\'s allowed to change his password again. If set value must be 0<."). ' '. _("Can be left empty.")),
"418" => array ("ext" => "FALSE", "Headline" => _("Expire date"),
"Text" => _("Account expire date. Format: DD-MM-YYYY")),
"419" => array ("ext" => "FALSE", "Headline" => _("Group members"),
"Text" => _("Users wich are also members of group.")),
"420" => array ("ext" => "FALSE", "Headline" => _("Display name"),
"Text" => _("Windows clients will show display name as group description.")),
"421" => array ("ext" => "FALSE", "Headline" => _("Load profile"),
"Text" => _("You can select a previous defined profile here. This will set all fields to the profile values.")),
"422" => array ("ext" => "FALSE", "Headline" => _("Expand suffix with primary groupname"),
"Text" => _("If selected users will be added with OUs expanded with their primary group. E.g. if a user is in group admin the user suffix will be ou=admin,+user suffix.")),
"423" => array ("ext" => "FALSE", "Headline" => _("Group suffix"),
"Text" => _("If a not yet existing group is defined in csv-file, a new group in the selected group suffix will be created.")),
"424" => array ("ext" => "FALSE", "Headline" => _("Last name"),
"Text" => _("Last name of user. Only letters, - and spaces are allowed.")),
"425" => array ("ext" => "FALSE", "Headline" => _("First name"),
"Text" => _("First name of user. Only letters, - and spaces are allowed.")),
"426" => array ("ext" => "FALSE", "Headline" => _("Use no password"),
"Text" => _("If checked no password will be used.")),
"428" => array ("ext" => "FALSE", "Headline" => _("Use unix password"),
"Text" => _("If checked unix password will also be used as samba password.")),
"429" => array ("ext" => "FALSE", "Headline" => _("Password does not expire"),
"Text" => _("If checked password does not expire. (Setting X-Flag)")),
"430" => array ("ext" => "FALSE", "Headline" => _("User can change password"),
"Text" => _("Date after the user is able to change his password. Format: DD-MM-YYYY")),
"431" => array ("ext" => "FALSE", "Headline" => _("User must change password"),
"Text" => _("Date after the user must change his password. Format: DD-MM-YYYY")),
"432" => array ("ext" => "FALSE", "Headline" => _("Account is deactivated"),
"Text" => _("If checked account will be deactivated. (Setting D-Flag)")),
"433" => array ("ext" => "FALSE", "Headline" => _("Home drive"),
"Text" => _("Driveletter assigned on windows workstations as homedirectory.")),
"434" => array ("ext" => "FALSE", "Headline" => _("Script path"),
"Text" => _("Filename and -path relative to netlogon-share which should be executed on logon. $%s and $%s are replaced with user- and groupname."). ' '. _("Can be left empty."),
"variables" => array('user', 'group')),
"435" => array ("ext" => "FALSE", "Headline" => _("Profile path"),
"Text" => _("Path of the user profile. Can be a local absolute path or a UNC-path (\\\\server\\share). $%s and $%s are replaced with user- and groupname."). ' '. _("Can be left empty."),
"variables" => array('user', 'group')),
"436" => array ("ext" => "FALSE", "Headline" => _("Samba workstations"),
"Text" => _("List of Samba workstations the user is allowed to login. Empty means every workstation."). ' '. _("Can be left empty.")),
"437" => array ("ext" => "FALSE", "Headline" => _("Home path"),
"Text" => _("UNC-path (\\\\server\\share) of homedirectory. $%s and $%s are replaced with user- and groupname."). ' '. _("Can be left empty."),
"variables" => array('user', 'group')),
"438" => array ("ext" => "FALSE", "Headline" => _("Domain"),
"Text" => _("Windows-Domain of user."). ' '. _("Can be left empty.")),
"457" => array ("ext" => "FALSE", "Headline" => _("Save profile"),
"Text" => _("This will make a profile of the current account. The saved values are the same as in the profile editor. Profile names may contain the letters a-z, 0-9 and -_.")),
"458" => array ("ext" => "FALSE", "Headline" => _("Select group profile"),
"Text" => _("If a not yet existing group is defined in csv-file, a new group with the selected group profile will be created.")),
"460" => array ("ext" => "FALSE", "Headline" => _("Windows domain"),
"Text" => _("Windows domain of host."). ' '. _("Can be left empty.")),
"461" => array ("ext" => "FALSE", "Headline" => _("Suffix"),
"Text" => _("Position in ldap-tree where the user should be created.")),
"462" => array ("ext" => "FALSE", "Headline" => _("Suffix"),
"Text" => _("Position in ldap-tree where the group should be created.")),
"463" => array ("ext" => "FALSE", "Headline" => _("Suffix"),
"Text" => _("Position in ldap-tree where the host should be created.")),
"464" => array ("ext" => "FALSE", "Headline" => _("Windows group name"),
"Text" => _("If you want to use a well known RID you can selcet a well known group.")),
"466" => array ("ext" => "FALSE", "Headline" => _("Unix workstations"),
"Text" => _("Comma separated list of unix workstations the user is allowed to login."). ' '. _("Can be left empty.")),
"467" => array ("ext" => "FALSE", "Headline" => _("Domain"),
"Text" => _("Windows-Domain of group."). ' '. _("Can be left empty.")),
"468" => array ("ext" => "FALSE", "Headline" => _("Group members"),
"Text" => _("Users also being member of the current group."). ' '. _("Can be left empty.")),
// 600 - 699
// Roland Gruber
// OU-editor, domain page
"601" => array ("ext" => "FALSE", "Headline" => _("OU-Editor") . " - " . _("New organizational unit"),
"Text" => _("This will create a new organizational unit under the selected one.")),
"602" => array ("ext" => "FALSE", "Headline" => _("OU-Editor") . " - " . _("Delete organizational unit"),
"Text" => _("This will delete the selected organizational unit. The OU has to be empty.")),
"651" => array ("ext" => "FALSE", "Headline" => _("Domain name"),
"Text" => _("The name of your Windows domain or workgroup.")),
"652" => array ("ext" => "FALSE", "Headline" => _("Suffix"),
"Text" => _("The domain entry will be saved under this suffix.")),
"653" => array ("ext" => "FALSE", "Headline" => _("Domain SID"),
"Text" => _("The SID of your Samba server. Get it with \"net getlocalsid\".")),
"654" => array ("ext" => "FALSE", "Headline" => _("Next RID"),
"Text" => _("Next RID to use when creating accounts.")),
"655" => array ("ext" => "FALSE", "Headline" => _("Next User RID"),
"Text" => _("Next RID to use when creating user accounts.")),
"656" => array ("ext" => "FALSE", "Headline" => _("Next Group RID"),
"Text" => _("Next RID to use when creating groups.")),
"657" => array ("ext" => "FALSE", "Headline" => _("Algorithmic RID Base"),
"Text" => _("Used for calculating RIDs from UID/GID. Do not change if unsure."))
/* This is a sample help entry. Just copy this line an modify the vakues between the [] brackets.
Help text is located in the array:
"[Helpnumber]" => array ("ext" => "FALSE", "Headline" => _("[Headline]"), "Text" => _("[Text]"), "SeeAlso" => "[SeeAlso link]"),
Help text is located in an extra file; File must be stored in help directory; Link has to be the path to the file if it is stored in a subdirectory and the filename with a leading slash;
"[Helpnumber]" => array ("ext" => "TRUE", "Link" => "[path/FileName]),
*/
);
?>

View File

@ -1,16 +0,0 @@
/*
This file contains a list of 100er blocks of help numbers. Each block can be unassigned or assigned to a developer. Each block description contains the name of the developer and the topic the help numbers are used for.
If you are a developer and need a block of help numbers please contact Michael Dürgner <michael@duergner.com> ICQ-UIN:176796482.
Help numbers should only be used if they are assigned in this file to avoid double entries. In the help/help.inc file each block should begin with the range of help numbers, the developers name and the topic.
*/
0 - 99: any developer: for testing purposes
100 - 199: unassigend
200 - 299: Roland Gruber: configuration wizard, configuration login
300 - 399: Roland Gruber: profil editor
400 - 499: Tilo Lutz: account.php
500 - 599: Tilo Lutz: Masscreate and Massdelete
600 - 699: Roland Gruber: OU-Editor
700 -: unassigned

View File

@ -1,8 +0,0 @@
<html>
<head>
<title>LDAP Account Manager</title>
<meta http-equiv="refresh" content="0; URL=templates/login.php">
</head>
<body>
</body>
</html>

View File

@ -1,12 +0,0 @@
<Files ~ .*>
Order allow,deny
Deny from all
</Files>
<Files ~ functions.js>
Order allow,deny
Allow from all
</Files>
<Files ~ fpdf.php>
Order allow,deny
Allow from all
</Files>

View File

@ -1,537 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 Tilo Lutz
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This provides several helper function for the account modules.
*
* @author Tilo Lutz
* @author Roland Gruber
*
* @package modules
*/
/** Needed to calculate Samba passwords */
include_once("createntlm.inc");
/* Return a list of all shells listed in ../config/shells
* Normally ../config/shells is a symbolic link to /etc/shells
*/
function getshells() {
// Load shells from file
if (file_exists($_SESSION['lampath'] . 'config/shells')) {
$shells = file($_SESSION['lampath'] . 'config/shells');
$i = 0;
while (count($shells) > $i) {
// remove whitespaces
trim($shells[$i]);
// remove lineend
$shells[$i] = substr($shells[$i], 0, strpos($shells[$i], "\n"));
// remove comments
if ($shells[$i]{0}=='#') unset ($shells[$i]);
else $i++;
}
// $shells is array with all valid shells
return $shells;
}
else return array();
}
/* This function will replace umlates with ascci-chars
* fixme ***
* In order to map all non-ascii characters this function should be changed
*/
/* This function will return all values from $array without values of $values
* $values, $array and $return are arrays
*/
function array_delete($values, $array) {
// Loop for every entry and check if it should be removed
if (is_array($array)) {
$return = array();
foreach ($array as $array_value)
if (!@in_array($array_value, $values))
$return[] = $array_value;
return $return;
}
else return array();
}
// This function will return a password with max. 8 characters
function genpasswd() {
// Allowed Characters to generate passwords
// I'Ve removed characters like l and 1 because they are too similar
$LCase = 'abcdefghjkmnpqrstuvwxyz';
$UCase = 'ABCDEFGHJKMNPQRSTUVWXYZ';
$Integer = '23456789';
// DEFINE CONSTANTS FOR ALGORTTHM
define("LEN", '1');
$a = RndInt('letter');
$b = RndInt('letter');
$c = RndInt('letter');
$d = RndInt('letter');
$e = RndInt('number');
$f = RndInt('number');
$g = RndInt('letter');
$h = RndInt('letter');
// EXTRACT 8 CHARACTERS RANDOMLY FROM TH // E DEFINITION STRINGS
$L1 = substr($LCase, $a, LEN);
$L2 = substr($LCase, $b, LEN);
$L3 = substr($LCase, $h, LEN);
$U1 = substr($UCase, $c, LEN);
$U2 = substr($UCase, $d, LEN);
$U3 = substr($UCase, $g, LEN);
$I1 = substr($Integer, $e, LEN);
$I2 = substr($Integer, $f, LEN);
// COMBINE THE CHARACTERS AND DISPLAY TH // E NEW PASSWORD
$PW = $L1 . $U2 . $I1 . $L2 . $I2 . $U1 . $U3 . $L3;
return $PW;
}
/* THIS FUNCTION GENERATES A RANDOM NUMBER THAT WILL BE USED TO
* RANDOMLY SELECT CHARACTERS FROM THE STRINGS ABOVE
*/
function RndInt($Format){
switch ($Format){
case 'letter':
$Rnd = rand(0,23);
if ($Rnd > 23){
$Rnd = $Rnd - 1;
}
break;
case 'number':
$Rnd = rand(2,9);
if ($Rnd > 8){
$Rnd = $Rnd - 1;
}
break;
}
return $Rnd;
} // END RndInt() FUNCTION
// This function will return the days from 1.1.1970 until now
function getdays() {
$days = time() / 86400;
settype($days, 'integer');
return $days;
}
/* This function creates all attributes stored in attrFlags. It's the same
* syntax used in smbpasswd
* $values is an array of samba flags as defined in account object
* Return value is a string
*/
function smbflag($input) {
// Start character
$flag = "[";
// Add Options
if ($input['W']) $flag .= "W"; else $flag .= "U";
if ($input['D']) $flag .= "D";
if ($input['X']) $flag .= "X";
if ($input['N']) $flag .= "N";
if ($input['S']) $flag .= "S";
if ($input['H']) $flag .= "H";
// Expand string to fixed length
$flag = str_pad($flag, 12);
// End character
$flag = $flag. "]";
return $flag;
}
/**
* Generates the LM hash of a password.
*
* @param string password original password
* @return string password hash
*/
function lmPassword($password) {
$hash = new smbHash();
return $hash->lmhash($password);
}
/**
* Generates the NT hash of a password.
*
* @param string password original password
* @return string password hash
*/
function ntPassword($password) {
$hash = new smbHash();
return $hash->nthash($password);
}
/**
* Returns the hash value of a plain text password
* the hash algorithm depends on the configuration file
*
* @param string $password the password string
* @param boolean $enabled marks the hash as enabled/disabled (e.g. by prefixing "!")
* @param string $hashType password hash type (CRYPT, SHA, SSHA, MD5, SMD5, PLAIN)
* @return string the password hash
*/
function pwd_hash($password, $enabled = true, $hashType = 'SSHA') {
// check for empty password
if (! $password || ($password == "")) {
return "";
}
// calculate new random number
$_SESSION['ldap']->new_rand();
$hash = "";
switch ($hashType) {
case 'CRYPT':
$hash = "{CRYPT}" . crypt($password);
break;
case 'MD5':
$hash = "{MD5}" . base64_encode(hex2bin(md5($password)));
break;
case 'SMD5':
$salt0 = substr(pack("h*", md5($_SESSION['ldap']->rand)), 0, 8);
$salt = substr(pack("H*", md5($salt0 . $password)), 0, 4);
$hash = "{SMD5}" . base64_encode(hex2bin(md5($password . $salt)) . $salt);
break;
case 'SHA':
// PHP 4.3+ can use sha1() function
if (function_exists('sha1')) {
$hash = "{SHA}" . base64_encode(hex2bin(sha1($password)));
}
// otherwise use MHash
elseif (function_exists('mHash')) {
$hash = "{SHA}" . base64_encode(mHash(MHASH_SHA1, $password));
}
// if SHA1 is not possible use crypt()
else {
$hash = "{CRYPT}" . crypt($password);
}
break;
case 'SSHA':
// PHP 4.3+ can use sha1() function
if (function_exists('sha1')) {
$salt0 = substr(pack("h*", md5($_SESSION['ldap']->rand)), 0, 8);
$salt = substr(pack("H*", sha1($salt0 . $password)), 0, 4);
$hash = "{SSHA}" . base64_encode(hex2bin(sha1($password . $salt)) . $salt);
}
// otherwise use MHash
elseif (function_exists('mHash')) {
$salt = mhash_keygen_s2k(MHASH_SHA1, $password, substr(pack("h*", md5($_SESSION['ldap']->rand)), 0, 8), 4);
$hash = base64_encode(mHash(MHASH_SHA1, $password . $salt) . $salt);
$hash = "{SSHA}" . $hash;
}
// if SSHA is not possible use crypt()
else {
$hash = "{CRYPT}" . crypt($password);
}
break;
case 'PLAIN':
$hash = $password;
break;
// use SSHA if the setting is invalid
default:
// PHP 4.3+ can use sha1() function
if (function_exists('sha1')) {
$salt0 = substr(pack("h*", md5($_SESSION['ldap']->rand)), 0, 8);
$salt = substr(pack("H*", sha1($salt0 . $password)), 0, 4);
$hash = "{SSHA}" . base64_encode(hex2bin(sha1($password . $salt)) . $salt);
}
// otherwise use MHash
elseif (function_exists('mHash')) {
$salt = mhash_keygen_s2k(MHASH_SHA1, $password, substr(pack("h*", md5($_SESSION['ldap']->rand)), 0, 8), 4);
$hash = base64_encode(mHash(MHASH_SHA1, $password . $salt) . $salt);
$hash = "{SSHA}" . $hash;
}
// if SSHA is not possible use crypt()
else {
$hash = "{CRYPT}" . crypt($password);
}
break;
}
// enable/disable password
if (! $enabled) return pwd_disable($hash);
else return $hash;
}
/**
* Marks an password hash as enabled and returns the new hash string
*
* @param string $hash hash value to enable
* @return string enabled password hash
*/
function pwd_enable($hash) {
// check if password is disabled (old wrong LAM method)
if ((substr($hash, 0, 2) == "!{") || ((substr($hash, 0, 2) == "*{"))) {
return substr($hash, 1, strlen($hash));
}
// check for "!" or "*" at beginning of password hash
else {
if (substr($hash, 0, 1) == "{") {
$pos = strpos($hash, "}");
if ((substr($hash, $pos + 1, 1) == "!") || (substr($hash, $pos + 1, 1) == "*")) {
// enable hash
return substr($hash, 0, $pos + 1) . substr($hash, $pos + 2, strlen($hash));
}
else return $hash; // not disabled
}
else return $hash; // password is plain text
}
}
/**
* Marks an password hash as disabled and returns the new hash string
*
* @param string $hash hash value to disable
* @return string disabled hash value
*/
function pwd_disable($hash) {
// check if password is disabled (old wrong LAM method)
if ((substr($hash, 0, 2) == "!{") || ((substr($hash, 0, 2) == "*{"))) {
return $hash;
}
// check for "!" or "*" at beginning of password hash
else {
if (substr($hash, 0, 1) == "{") {
$pos = strpos($hash, "}");
if ((substr($hash, $pos + 1, 1) == "!") || (substr($hash, $pos + 1, 1) == "*")) {
// hash already disabled
return $hash;
}
else return substr($hash, 0, $pos + 1) . "!" . substr($hash, $pos + 1, strlen($hash)); // not disabled
}
else return $hash; // password is plain text
}
}
/**
* Checks if a password hash is enabled/disabled
*
* @param string $hash password hash to check
* @return boolean true if the password is marked as enabled
*/
function pwd_is_enabled($hash) {
// disabled passwords have a "!" or "*" at the beginning (old wrong LAM method)
if ((substr($hash, 0, 2) == "!{") || ((substr($hash, 0, 2) == "*{"))) return false;
if (substr($hash, 0, 1) == "{") {
$pos = strrpos($hash, "}");
// check if hash starts with "!" or "*"
if ((substr($hash, $pos + 1, 1) == "!") || (substr($hash, $pos + 1, 1) == "*")) return false;
else return true;
}
else return true;
}
/**
* Returns an array with all Samba 3 domain entries under the given suffix
*
* @param string $suffix search suffix
* @return array list of samba3domain objects
*/
function search_domains($suffix) {
$ret = array();
$attr = array("DN", "sambaDomainName", "sambaSID", "sambaNextRid", "sambaNextGroupRid",
"sambaNextUserRid", "sambaAlgorithmicRidBase");
$sr = @ldap_search($_SESSION['ldap']->server(), $suffix, "objectClass=sambaDomain", $attr);
if ($sr) {
$units = ldap_get_entries($_SESSION['ldap']->server, $sr);
// delete count entry
array_shift($units);
// extract attributes
for ($i = 0; $i < sizeof($units); $i++) {
$ret[$i] = new samba3domain();
$ret[$i]->dn = $units[$i]['dn'];
$ret[$i]->name = $units[$i]['sambadomainname'][0];
$ret[$i]->SID = $units[$i]['sambasid'][0];
$ret[$i]->nextRID = $units[$i]['sambanextrid'][0];
$ret[$i]->nextGroupRID = $units[$i]['sambanextgrouprid'][0];
$ret[$i]->nextUserRID = $units[$i]['sambanextuserrid'][0];
if (isset($units[$i]['sambaalgorithmicridbase'][0])) $ret[$i]->RIDbase = $units[$i]['sambaalgorithmicridbase'][0];
}
// sort array by domain name
usort($ret, "cmp_domain");
}
return $ret;
}
/**
* Helper function to sort the domains
*
* @param string $a first argument to compare
* @param string $b second argument to compare
* @return integer 0 if equal, 1 if $a is greater, -1 if $b is greater
*/
function cmp_domain($a, $b) {
if ($a->name == $b->name) return 0;
elseif ($a->name == max($a->name, $b->name)) return 1;
else return -1;
}
/**
* Represents a Samba 3 domain entry
*
* @package modules
*/
class samba3domain {
/** DN */
var $dn;
/** Domain name */
var $name;
/** Domain SID */
var $SID;
/** Next RID */
var $nextRID;
/** Next user RID */
var $nextUserRID;
/** Next group RID */
var $nextGroupRID;
/** RID base to calculate RIDs, default 1000 */
var $RIDbase = 1000;
}
/** This functions contains a collection of regular expressions
* It's much easier to handle them here than in every module
* because many of them are used several times.
**/
function get_preg($argument, $regexp) {
/* Bug in php preg_match doesn't work correct with utf8
*/
$language = explode(":", $_SESSION['language']);
$language2 = explode ('.', $language[0]);
setlocale(LC_ALL, $language2[0]);
// First we check "positive" cases
$pregexpr = '';
switch ($regexp) {
case 'password': // fixme where do i get an exact regexp?
$pregexpr = '/^([[:alnum:]\\ \\|\\#\\*\\,\\.\\;\\:\\_\\+\\!\\%\\&\\/\\?\\{\\(\\)\\}-])*$/u';
break;
case 'groupname': // first character must be a letter. All letters, numbers, space and ._- are allowed characters
case 'username': // first character must be a letter. All letters, numbers, space and ._- are allowed characters
$pregexpr = '/^[[:alpha:]]([[:alnum:]\\.\\ \\_-])*$/u';
break;
case 'usernameList': // comma separated list of user names
case 'groupnameList': // comma separated list of group names
$pregexpr = '/^[[:alpha:]]([[:alnum:]\\.\\ \\_-])*(,[[:alpha:]]([[:alnum:]\\.\\ \\_-])*)*$/u';
break;
case 'hostname': // first character must be letter, last must be $. Only normal letters, numbers and ._- are allowed
$pregexpr = '/^[a-zA-Z]([a-zA-Z0-9\\.\\_-])*\\$$/u';
break;
case 'cn':
case 'realname': // Allow all letters, space and .-_
$pregexpr = '/^[[:alpha:]]([[:alpha:]\\.\\ \\_-])*$/u';
break;
case "telephone": // Allow numbers, space, brackets, /-+.
$pregexpr = '/^(\\+)*([0-9\\.\\ \\(\\)\\/-])*$/';
break;
case "email":
$pregexpr = '/^([0-9a-z\\._-])+[@]([0-9a-z-])+([.]([0-9a-z-])+)*$/';
break;
case "street": // Allow all letters, numbers, space and .-_
$pregexpr = '/^([[:alnum:]\\.\\ \\_-])*$/u';
break;
case "postalAddress": // Allow all letters, numbers, space and .-_
case "postalCode": // Allow all letters, numbers, space and .-_
case "title": // Allow all letters, numbers, space and .-_
case "employeeType": // Allow all letters, numbers, space and .-_
$pregexpr = '/^([[:alnum:]\\.\\ \\_-])*$/u';
break;
case "homeDirectory": // Homapath, /path/......
$pregexpr = '/^([\/]([[:alnum:]\\.\\ \\_-])+)+$/u';
break;
case "digit": // Normal number
$pregexpr = '/^[[:digit:]]*$/';
break;
case "UNC": // UNC Path, e.g. \\server\share\folder\...
$pregexpr = '/^([\\\][\\\]([a-zA-Z0-9\\.-])+)([\\\]([[:alnum:]\\.\\ \\_-])+)+$/u';
break;
case "logonscript": // path to login-script. normal unix file
$pregexpr = '/^(([\/])*([[:alnum:]\\.\\ \\_-])+([\/]([[:alnum:]\\.\\ \\_-])+)*((\\.bat)|(\\.cmd)|(\\.exe)))*$/u';
break;
case "workstations": // comma separated list with windows-hosts
$pregexpr = '/^(([a-zA-Z0-9\\.\\_-])+(,[a-zA-Z0-9\\.\\_-])*)*$/';
break;
case "domainname": // Windows Domainname
$pregexpr = '/^([a-z0-9\\.\\_-])+$/';
break;
case "unixhost": // Unix hosts
$pregexpr = '/^([a-z0-9\\.\\_-])*$/';
break;
case 'digit2': // Same as digit but also -1
$pregexpr = '/^(([-][1])|([[:digit:]]*))$/';
break;
case 'gecos':
$pregexpr = '/^[a-zA-z0-9 \\._-]+([,][a-zA-z0-9 \\._-]+)*$/';
break;
case 'macAddress':
$pregexpr = '/^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/';
break;
case 'date':
$pregexpr = '/^((0[1-9])|([1-2][0-9])|30|31)\\-((0[1-9])|(1[0-2]))\\-[1-3][0-9][0-9][0-9]$/';
break;
case 'sambaLogonHours':
$pregexpr = '/^[0-9a-fA-F]{42}$/';
break;
}
if ($pregexpr!='')
if (preg_match($pregexpr, $argument)) {
/* Bug in php preg_match doesn't work correct with utf8
*/
setlocale(LC_ALL, $language[0]);
return true;
}
// Now we check "negative" cases, characters which are not allowed
$pregexpr = '';
switch ($regexp) {
case "!lower":
$pregexpr = '/[[:lower:]]/';
break;
case "!upper":
$pregexpr = '/[[:upper:]]/';
break;
case "!digit":
$pregexpr = '/[[:digit:]]/';
break;
}
if ($pregexpr!='')
if (!preg_match($pregexpr, $argument)) {
/* Bug in php preg_match doesn't work correct with utf8
*/
setlocale(LC_ALL, $language[0]);
return true;
}
/* Bug in php preg_match doesn't work correct with utf8
*/
setlocale(LC_ALL, $language[0]);
return false;
}
?>

View File

@ -1,576 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 - 2004 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This is the parent class for all account modules.
*
* It implements the complete module interface and uses meta-data
* provided by the account modules for its functions.
*
* @package modules
* @author Roland Gruber
*/
/**
* Parent class of all account modules
*
* @package modules
*/
class baseModule {
/** includes all meta data provided by the sub class */
var $meta;
/** the account type of this module (user, group, host) */
var $scope;
/** configuration settings of all modules */
var $moduleSettings;
/** name of parent accountContainer ($_SESSION[$base]) */
var $base;
/** contains all ldap attributes which should be written */
var $attributes;
/** contains all ldap attributes which are loaded from ldap */
var $orig;
/** contains all messages wich were triggered*/
var $triggered_messages;
/** contains all error messages of a module */
var $messages;
/**
* Creates a new base module class
*
* @param string $scope the account type (user, group, host)
*/
function baseModule($scope) {
$this->scope = $scope;
$this->load_Messages();
$this->meta = $this->get_metaData();
if (isset($_SESSION['config'])) $this->moduleSettings = $_SESSION['config']->get_moduleSettings();
}
/**
* This function fills the $messages variable with output messages from this module.
*/
function load_Messages() {
}
/**
* Initializes the module after it became part of an accountContainer
*
* @param string $base the name of the accountContainer object ($_SESSION[$base])
*/
function init($base) {
$this->base = $base;
// Create Arrays with ldap attributes
$this->attributes =& $_SESSION[$this->base]->get_module_attributes(get_class($this));
$this->orig =& $_SESSION[$this->base]->get_module_attributes(get_class($this), true);
$line=-1;
for ($i=0; $i<count($_SESSION['ldap']->objectClasses) || $i==-1; $i++) {
if (strpos(strtolower($_SESSION['ldap']->objectClasses[$i]), strtolower("NAME '".get_class($this)."'"))) $line = $i;
}
$objectClassName = substr($_SESSION['ldap']->objectClasses[$line], 6+strpos($_SESSION['ldap']->objectClasses[$line], "NAME '"), strlen(get_class($this)) );
$this->attributes['objectClass'][0] = $objectClassName;
}
/* This function loads all standard ldap attributes. It is used
* by the modules to reduce code
*/
function load_ldap_attributes($attr) {
// Load attributes which are displayed
$objectClassName = $this->attributes['objectClass'];
// unset count entries
unset ($attr['count']);
$attributes = array_keys($attr);
foreach ($attributes as $attribute) unset ($attr[$attribute]['count']);
// unset double entries
for ($i=0; $i<count($attr); $i++)
if (isset($attr[$i])) unset($attr[$i]);
foreach ($attributes as $attribute) {
if (isset($this->attributes[$attribute])) {
// decode as unicode
$this->attributes[$attribute] = $attr[$attribute];
$this->orig[$attribute] = $attr[$attribute];
}
}
$this->attributes['objectClass'] = $objectClassName;
if (in_array($objectClassName[0], $attr['objectClass']))
$this->orig['objectClass'] = $objectClassName;
else $this->orig['objectClass'] = array();
}
/**
* Dummy function, meta data is provided by sub classes.
*
* @return array empty array
*/
function get_metaData() {
return array();
}
/**
* Returns the account type of this module (user, group, host)
*
* @return string account type
*/
function get_scope() {
return $this->scope;
}
/**
* Returns true if this module fits for the current scope.
*
* @return boolean true if module fits
*/
function can_manage() {
if (is_array($this->meta["account_types"]) && in_array($this->scope, $this->meta["account_types"])) return true;
else return false;
}
/**
* Returns true if this module is enough to provide a sensible account.
*
* There is no relation to the name of this class.
*
* @return boolean true if base module
*/
function is_base_module() {
if ($this->meta['is_base'] == true) return true;
else return false;
}
/**
* returns an LDAP filter for the account lists
*
* @return string LDAP filter
*/
function get_ldap_filter() {
if (isset($this->meta['ldap_filter'])) return $this->meta['ldap_filter'];
else return "";
}
/**
* Returns an alias name for the module.
*
* This alias is used in various places instead of the less descriptive class name.
* The alias also has less syntax restrictions and may contain spaces or special characters.
*
* @return string alias name
*/
function get_alias() {
if (isset($this->meta['alias'])) return $this->meta['alias'];
else return get_class($this);
}
/**
* Returns a list of possible LDAP attributes which can be used to form the RDN.
*
* The returned elements have this form: <attribute> => <priority>
* <br> <attribute> is the name of the LDAP attribute
* <br> <priority> defines the priority of the attribute (can be "low", "normal", "high")
*
* @return array list of attributes
*/
function get_RDNAttributes() {
if (isset($this->meta['RDN'])) return $this->meta['RDN'];
else return array();
}
/**
* This function returns a list with all depending and conflicting modules.
*
* @return array list of dependencies and conflicts
*/
function get_dependencies() {
if (isset($this->meta['dependencies'])) return $this->meta['dependencies'];
else return array('depends' => array(), 'conflicts' => array());
}
/**
* Returns a list of elements for the account profiles.
*
* @return profile elements
*/
function get_profileOptions() {
if (isset($this->meta['profile_options'])) return $this->meta['profile_options'];
else return array();
}
/**
* Checks input values of account profiles.
*
* @param array $options a hash array (name => value) containing the options
* @return array list of error messages (array(type, title, text)) to generate StatusMessages, if any
*/
function check_profileOptions($options) {
$messages = array();
if (is_array($this->meta['profile_checks'])) {
$identifiers = array_keys($this->meta['profile_checks']);
for ($i = 0; $i < sizeof($identifiers); $i++) {
// empty input
if (($options[$identifiers[$i]][0] == '') || !isset($options[$identifiers[$i]][0])) {
// check if option is required
if ($this->meta['profile_checks'][$identifiers[$i]]['required']) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['required_message'];
}
return $messages;
}
switch ($this->meta['profile_checks'][$identifiers[$i]]['type']) {
// check by regular expression (from account.inc)
case "ext_preg":
// ignore empty fileds
if ($options[$identifiers[$i]][0] == '') continue;
if (! get_preg($options[$identifiers[$i]][0], $this->meta['profile_checks'][$identifiers[$i]]['regex'])) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
}
break;
// check by regular expression (case insensitive)
case 'regex_i':
// ignore empty fileds
if ($options[$identifiers[$i]][0] == '') continue;
if (! eregi($this->meta['profile_checks'][$identifiers[$i]]['regex'], $options[$identifiers[$i]][0])) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
}
break;
// check by regular expression (case sensitive)
case 'regex':
// ignore empty fileds
if ($options[$identifiers[$i]][0] == '') continue;
if (! ereg($this->meta['profile_checks'][$identifiers[$i]]['regex'], $options[$identifiers[$i]][0])) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
}
break;
// check by integer comparison (greater)
case 'int_greater':
// ignore if both fields are empty
if (($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name1']][0] == '') && ($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name2']][0] == '')) continue;
// print error message if only one field is empty
if (($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name1']][0] == '') || ($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name2']][0] == '')) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
continue;
}
// compare
if (!(intval($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name1']][0]) > intval($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name2']][0]))) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
}
break;
// check by integer comparison (greater or equal)
case 'int_greaterOrEqual':
// ignore if both fields are empty
if (($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name1']][0] == '') && ($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name2']][0] == '')) continue;
// print error message if only one field is empty
if (($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name1']][0] == '') || ($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name2']][0] == '')) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
continue;
}
// compare
if (!(intval($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name1']][0]) >= intval($options[$this->meta['profile_checks'][$identifiers[$i]]['cmp_name2']][0]))) {
$messages[] = $this->meta['profile_checks'][$identifiers[$i]]['error_message'];
}
break;
// print error message for invalid types
default:
StatusMessage("ERROR", "Unsupported type!", $this->meta['profile_checks'][$identifiers[$i]]['type']);
break;
}
}
}
return $messages;
}
/**
* Returns a list of elements for the configuration.
*
* @param array $scopes account types (user, group, host)
* @return array configuration elements
*/
function get_configOptions($scopes) {
$return = array();
for ($i = 0; $i < sizeof($scopes); $i++) {
if (isset($this->meta['config_options'][$scopes[$i]])) $return = array_merge($return, $this->meta['config_options'][$scopes[$i]]);
}
if (isset($this->meta['config_options']['all'])) $return = array_merge($return, $this->meta['config_options']['all']);
return $return;
}
/**
* Returns an array containing descriptions shown on configuration pages.
*
* The returned array has the format array('legend' => '...', descriptions => array('option1' => '...', ...)).
* <br> The "legend" value is used as text for the fieldset, the descriptions are used when the configuration is printed.
*
* @return array configuration elements
*/
function get_configDescriptions() {
$return = array('legend' => 'no description', 'descriptions' => array());
if (isset($this->meta['config_descriptions'])) $return = $this->meta['config_descriptions'];
return $return;
}
/**
* Checks input values of module settings.
*
* @param array $scopes list of account types which are used
* @param array $options hash array containing the settings (array('option' => array('value')))
* @return array list of error messages
*/
function check_configOptions($scopes, $options) {
$messages = array();
$scopes[] = 'all'; // add checks that are independent of scope
for ($s = 0; $s < sizeof($scopes); $s++) {
if (is_array($this->meta['config_checks'][$scopes[$s]])) {
$identifiers = array_keys($this->meta['config_checks'][$scopes[$s]]);
for ($i = 0; $i < sizeof($identifiers); $i++) {
// check if option is required
if ($this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['required'] && ($options[$identifiers[$i]][0] == '')) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['required_message'];
}
switch ($this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['type']) {
// check by regular expression (from account.inc)
case "ext_preg":
// ignore empty fileds
if ($options[$identifiers[$i]][0] == '') continue;
if (! get_preg($options[$identifiers[$i]][0], $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['regex'])) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
}
break;
// check by regular expression (case insensitive)
case "regex_i":
// ignore empty fileds
if ($options[$identifiers[$i]][0] == '') continue;
if (! eregi($this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['regex'], $options[$identifiers[$i]][0])) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
}
break;
// check by regular expression (case sensitive)
case "regex":
// ignore empty fileds
if ($options[$identifiers[$i]][0] == '') continue;
if (! ereg($this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['regex'], $options[$identifiers[$i]][0])) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
}
break;
// check by integer comparison (greater)
case "int_greater":
// ignore if both fields are empty
if (($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name1']][0] == '') && ($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name2']][0] == '')) continue;
// print error message if only one field is empty
if (($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name1']][0] == '') || ($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name2']][0] == '')) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
continue;
}
// compare
if (!(intval($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name1']][0]) > intval($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name2']][0]))) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
}
break;
// check by integer comparison (greater or equal)
case "int_greaterOrEqual":
// ignore if both fields are empty
if (($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name1']][0] == '') && ($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name2']][0] == '')) continue;
// print error message if only one field is empty
if (($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name1']][0] == '') || ($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name2']][0] == '')) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
continue;
}
// compare
if (!(intval($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name1']][0]) >= intval($options[$this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['cmp_name2']][0]))) {
$messages[] = $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['error_message'];
}
break;
// print error message on undefined type
default:
StatusMessage("ERROR", "Unsupported type!", $this->meta['config_checks'][$scopes[$s]][$identifiers[$i]]['type']);
break;
}
}
}
}
return $messages;
}
/**
* Returns an array with all fields available for this account type on the PDF
* output. This method may be overwritten by subclasses or it may be used
* by using entries in the $this->meta['PDF_fields'] array of the specific sub-
* class.
*
* @param string $scope account type
* @return array list of available fields for PDF output
*/
function get_pdfFields($scope = 'user') {
return ((isset($this->meta['PDF_fields'])) ? $this->meta['PDF_fields'] : array());
}
/**
* Returns a hastable with all entries that may be printed out in the PDF. The
* syntax of the hashtable is specified by the module specification and the
* corresponding DTD. This method must be overwritten in case that there
* are non static things to be returned. The $this->meta['PDF_entries'] array
* may be used when there is only static content.
*
* @param string $scope account type
* @return array hastable of entries for the PDF. Each entry is an array where
* each entry is treated as a new line in the PDF.
*/
function get_pdf_entries($scope = 'user') {
return ((isset($this->meta['PDF_entries'])) ? $this->meta['PDF_entries'] : array());
}
/**
* Returns an array containing all input columns for the file upload.
*
* Syntax:
* <br> array(
* <br> string: name, // fixed non-translated name which is used as column name (should be of format: <module name>_<column name>)
* <br> string: description, // short descriptive name
* <br> string: help, // help ID
* <br> string: example, // example value
* <br> boolean: required // true, if user must set a value for this column
* <br> )
*
* @return array column list
*/
function get_uploadColumns() {
if (isset($this->meta['upload_columns'])) return $this->meta['upload_columns'];
else return array();
}
/**
* Returns a list of module names which must be processed in building the account befor this module.
*
* @return array list of module names
*/
function get_uploadPreDepends() {
if (isset($this->meta['upload_preDepends'])) return $this->meta['upload_preDepends'];
else return array();
}
/**
* In this function the LDAP account is built up.
*
* @param array $rawAccounts list of hash arrays (name => value) from user input
* @param array $partialAccounts list of hash arrays (name => value) which are later added to LDAP
* @param array $ids list of IDs for column position (e.g. "posixAccount_uid" => 5)
* @return array list of error messages if any
*/
function build_uploadAccounts($rawAccounts, $ids, &$partialAccounts) {
// must be implemented in sub modules
return array();
}
/**
* This function return the help entry array for a specific help id. Normally this->meta can be used.
*
* @param string $id The id string for the help entry needed.
* @param string $scope The scope for which the help entry should be retrieved. May be empty when
* there is now difference of the help entry depending on the actual scope.
*
* @return array The desired help entry.
*/
function get_help($id) {
if(isset($this->meta['help'][$id])) {
return $this->meta['help'][$id];
}
elseif(isset($this->meta['help'][$this->scope][$id])) {
return $this->meta['help'][$this->scope][$id];
}
else {
return false;
}
}
function input_check() {
/* We have to some string checks now. Not every ldap attributes allow utf8
* strings. Therefore we do a syntax check here and change utf8 strings to ascci
* strings. Only "7bit" ascci is allowed
* We check als the max length as defined in ldap.
*/
// Do a check for every ldap attribute
$attributes = array_keys($this->attributes);
for ($i=0; $i<count($attributes); $i++) {
if ($_SESSION['ldap']->attributes[$attributes[$i]]['SYNTAX']=='1.3.6.1.4.1.1466.115.121.1.36') {
// found numeric attribute
for ($j=0; $j<count($this->attributes[$attributes[$i]]); $j++)
if ($this->attributes[$attributes[$i]][$j]!=intval($this->attributes[$attributes[$i]][$j])) {
$this->attributes[$attributes[$i]][$j] = intval($this->attributes[$attributes[$i]][$j]);
$messages[$attributes[$i]] = array('WARN', _($attributes[$i]), _('Changed value %s because only numeric values are allowed.'));
}
}
else if ($_SESSION['ldap']->attributes[$attributes[$i]]['SYNTAX']=='1.3.6.1.4.1.1466.115.121.1.26' ||
$_SESSION['ldap']->attributes[$attributes[$i]]['SYNTAX']=='1.3.6.1.4.1.1466.115.121.1.44' ||
$_SESSION['ldap']->attributes[$attributes[$i]]['SYNTAX']=='1.3.6.1.4.1.1466.115.121.1.11') {
// found "7bit" ascii attribute
// convert utf8 in us-ascii
$convert = array ( 'ä' => 'ae', 'Ä' => 'Ae', 'ö' => 'Oe', 'ü' => 'ue', 'Ü' => 'ue',
'ß' => 'ss', 'é' => 'e', 'è' => 'e', 'ô' => 'o'
);
$index = array_keys($convert);
for ($j=0; $j<count($this->attributes[$attributes[$i]]); $j++)
for ($k=0; $k<count($index); $k++) {
$temp = str_replace($index[$k], $convert[$index[$k]], $this->attributes[$attributes[$i]][$j]);
if ($temp!=$this->attributes[$attributes[$i]][$j]) {
$this->attributes[$attributes[$i]][$j] = $temp;
$messages[$attributes[$i]][] = array('WARN', _($attributes[$i]), _('Changed value because only ASCII characters are allowed.'));
}
}
}
// TODO length check
}
if (count($messages)!=0) return $messages;
else return 0;
}
/**
* This function executes one post upload action.
*
* @param array $data array containing one account in each element
* @param array $ids array(<column_name> => <column number>)
* @param array $failed list of accounts which were not created successfully
* @param array $temp variable to store temporary data between two post actions
* @return array current status
* <br> array (
* <br> 'status' => 'finished' | 'inProgress'
* <br> 'progress' => 0..100
* <br> 'errors' => array (<array of parameters for StatusMessage>)
* <br> )
*/
function doUploadPostActions($data, $ids, $failed, &$temp) {
return array(
'status' => 'finished',
'progress' => 100,
'errors' => array()
);
}
}
?>

View File

@ -1,548 +0,0 @@
<?php
/*
* The Cipher_blowfish:: class implements the Cipher interface enryption data
* using the Blowfish algorithm.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright 2002-2003 Mike Cochrane <mike@graftonhall.co.nz>
*
* See http://www.fsf.org/copyleft/lgpl.html for license information (LGPL).
*
* This file was copied from the Horde project (http://www.horde.org).
*
* author: Mike Cochrane <mike@graftonhall.co.nz>
*
* edited by Roland Gruber <post@rolandgruber.de> for LAM
* - added encrypt/decrypt functions
*/
/**
* Blowfish encryption/decryption
*
* @package LDAP
* @author Roland Gruber
* @author Mike Cochrane
*/
/**
* Encrypts the LDAP username and password before storing in session.
*
* @package LDAP
*/
class Cipher_blowfish {
/** Pi Array */
var $p = array(
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
0x9216D5D9, 0x8979FB1B);
/** S Boxes */
var $s1 = array(
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A);
/** S Boxes */
var $s2 = array(
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7);
/** S Boxes */
var $s3 = array(
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0);
/** S Boxes */
var $s4 = array(
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6);
/** The number of rounds to do */
var $_rounds = 16;
/** Constructor */
function Cipher_blowfish()
{
}
/**
* Set the key to be used for en/decryption
*
* @param String $key The key to use
*/
function setKey($key)
{
$key = $this->_formatKey($key);
$keyPos = $keyXor = 0;
$iMax = count($this->p);
$keyLen = count($key);
for ($i = 0; $i < $iMax; $i++) {
for ($t = 0; $t < 4; $t++) {
$keyXor = ($keyXor << 8) | (($key[$keyPos]) & 0x0ff);
if (++$keyPos == $keyLen) {
$keyPos = 0;
}
}
$this->p[$i] = $this->p[$i] ^ $keyXor;
}
$encZero = array('L' => 0, 'R' => 0);
for ($i = 0; $i + 1 < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->p[$i] = $encZero['L'];
$this->p[$i + 1] = $encZero['R'];
}
$iMax = count($this->s1);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s1[$i] = $encZero['L'];
$this->s1[$i + 1] = $encZero['R'];
}
$iMax = count($this->s2);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s2[$i] = $encZero['L'];
$this->s2[$i + 1] = $encZero['R'];
}
$iMax = count($this->s3);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s3[$i] = $encZero['L'];
$this->s3[$i + 1] = $encZero['R'];
}
$iMax = count($this->s4);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s4[$i] = $encZero['L'];
$this->s4[$i + 1] = $encZero['R'];
}
}
/**
* Return the size of the blocks that this cipher needs
*
* @return Integer The number of characters per block
*/
function getBlockSize()
{
return 8;
}
/**
* Encrypt a block on data.
*
* @param String $block The data to encrypt
* @param optional String $key The key to use
*
* @return String the encrypted output
*/
function encryptBlock($block, $key = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
list($L, $R) = array_values(unpack('N*', $block));
$parts = $this->_encryptBlock($L, $R);
return pack("NN", $parts['L'], $parts['R']);
}
/**
* Encrypt a string of data.
*
* @param String $data The string to encrypt
* @param optional String $key The key to use
*
* @return String the encrypted output
*/
function encrypt($data, $key = null) {
// add end marker
$data .= 'x';
// split data to array of encryptable blocks
$data_blocks = array();
for ($j = 0; $j < strlen($data); $j = $j + 8) {
$data_blocks[] = substr($data, $j, 8);
}
// add spaces to last block if needed
$data_blocks[sizeof($data_blocks) - 1] = str_pad($data_blocks[sizeof($data_blocks) - 1], 8);
// encrypt blocks
$crypt_blocks = array();
for ($i = 0; $i < sizeof($data_blocks); $i++) {
$crypt_blocks[] = $this->encryptBlock($data_blocks[$i], $key);
}
return implode("", $crypt_blocks);
}
/**
* Encrypt a block on data.
*
* @param String $L The data to encrypt.
* @param String $R The data to encrypt.
*
* @return String The encrypted output.
*/
function _encryptBlock($L, $R)
{
$L ^= $this->p[0];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[1];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[2];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[3];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[4];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[5];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[6];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[7];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[8];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[9];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[10];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[11];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[12];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[13];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[14];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[15];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[16];
$R ^= $this->p[17];
return array('L' => $R, 'R' => $L);
}
/**
* Decrypt a string of data.
*
* @param String $data The data to decrypt
* @param optional String $key The key to use
*
* @return String the decrypted output
*/
function decrypt($data, $key = null){
// decrypt string parts
$decr_blocks = array();
for ($i = 0; $i < (strlen($data) / 8); $i++) {
$decr_blocks[] = $this->decryptBlock(substr($data, $i * 8, 8), $key);
}
$decr_text = "";
$decr_text = implode("", $decr_blocks);
// removed whitespaces and end marker
$decr_text = chop($decr_text);
$decr_text = substr($decr_text, 0, (strlen($decr_text) - 1));
return $decr_text;
}
/**
* Decrypt a block on data.
*
* @param String $block The data to decrypt
* @param optional String $key The key to use
*
* @return String the decrypted output
*/
function decryptBlock($block, $key = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
list($L, $R) = array_values(unpack('N*', $block));
$L ^= $this->p[17];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[16];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[15];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[14];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[13];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[12];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[11];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[10];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[9];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[8];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[7];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[6];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[5];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[4];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[3];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[2];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[1];
$decrypted = pack("NN", $R ^ $this->p[0], $L);
return $decrypted;
}
/**
* Converts a text key into an array.
*
* @param String $key key string
* @return array The key.
*/
function _formatKey($key)
{
return array_values(unpack('C*', $key));
}
}
?>

View File

@ -1,337 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 Tilo Lutz
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
LDAP Account Manager functions used by account.php
*/
/* This class contains all functions
* which are needed to manage the ldap cache
*/
class cache {
function cache() {
$this->time = 0;
$this->attributes = array();
}
var $ldapcache; // This variable contains the cache
var $attributes; // This variable contains a list and their scope of attributes which should be cached
var $time; // This is the laste timestamp ldap cache has been refreshed
/* This function adds attributes to cache
* syntax of $attributes is array( scope1 => array ( attributes ), scope2 => array ( attributes ), ...)
*/
function add_cache($attributes) {
// Check input variable
$allowed_types = array ( 'user', 'group', 'host', 'domain', '*' );
if (!is_array($attributes)) trigger_error('Argument of add_cache must be : array ( scope => array(attribute1(string), attribute2(string), ..), scope => ... ).', E_USER_ERROR);
foreach ($attributes as $attribute) {
if (!is_array($attribute)) trigger_error('Argument of add_cache must be : array ( scope => array(attribute1(string), attribute2(string), ..), scope => ... ).', E_USER_ERROR);
foreach ($attribute as $singleattribute) {
if (!is_string($singleattribute)) trigger_error('Argument of add_cache must be : array ( scope => array(attribute1(string), attribute2(string), ..), scope => ... ).', E_USER_ERROR);
}
}
$scopes = array_keys($attributes);
foreach ($scopes as $scope) {
if (!@in_array($scope, $allowed_types)) trigger_error(sprintf('Invalid scope. Valid scopes are %s.', implode(" ", $allowed_types)), E_USER_ERROR);
}
// Everything seems to be OK, start processing data
foreach ($scopes as $scope) {
for ($i=0; $i<count($attributes[$scope]); $i++ ) {
if (!@in_array($attributes[$scope][$i] ,$this->attributes[$scope])) $this->attributes[$scope][] = $attributes[$scope][$i];
}
}
// Rebuild cache
$this->refresh_cache(true);
}
/* This function returns an array ( dn1 => array(uidnumber1), dn2 => array(uidnumber2), ... )
*
*/
function get_cache($attribute, $objectClass, $singlescope) {
$this->refresh_cache();
// Check input variables
$allowed_types = array ( 'user', 'group', 'host', 'domain', '*' );
if (!in_array($singlescope, $allowed_types)) trigger_error(sprintf('Invalid scope. Valid scopes are %s.', implode(" ", $allowed_types)), E_USER_ERROR);
$line=-1;
for ($i=0; $i<count($_SESSION['ldap']->objectClasses) || $i==-1; $i++) {
if (strpos($_SESSION['ldap']->objectClasses[$i], "NAME '$objectClass'")) $line = $i;
}
// Return error if objectClass isn't found
if ($line==-1) trigger_error (sprintf(_("ObjectClass %s required but not defined in LDAP."), $objectClass), E_USER_WARNING);
// Create list of all allowed attributes
for ($i=0; $i<count($_SESSION['ldap']->objectClasses); $i++ ) {
if (strpos($_SESSION['ldap']->objectClasses[$i], 'MUST (')) {
$string_withtail = substr($_SESSION['ldap']->objectClasses[$i], strpos($_SESSION['ldap']->objectClasses[$i], 'MUST (')+6);
// Now we have a string with all must-attributes
$string = substr($string_withtail, 0, strpos($string_withtail, ')'));
$string = trim($string);
$allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string));
}
// create array with may-attributes
// Get startposition in string
if (strpos($_SESSION['ldap']->objectClasses[$i], 'MAY (')) {
$string_withtail = substr($_SESSION['ldap']->objectClasses[$i], strpos($_SESSION['ldap']->objectClasses[$i], 'MAY (')+5);
// Now we have a string with all must-attributes
$string = substr($string_withtail, 0, strpos($string_withtail, ')'));
$string = trim($string);
$allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string));
}
}
$allowed_attributes = array_unique($allowed_attributes);
if (!in_array($attribute, $allowed_attributes)) trigger_error(_('Attribute not defined in LDAP.'), E_USER_WARNING);
// Everything seems to be OK, start processing data
$this->refresh_cache();
if ($singlescope == '*') $scopes = $allowed_types;
else $scopes = array ( $singlescope );
// Add cache entry dynamic
foreach ($scopes as $scope) {
if (!@in_array($attribute ,$this->attributes[$scope])) $add[$scope][] = $attribute;
}
if (count($add)!=0) $this->add_cache($add);
foreach ($scopes as $scope) {
if (isset($this->ldapcache[$scope])) {
$DNs = array_keys($this->ldapcache[$scope]);
foreach ($DNs as $dn) {
if (isset($this->ldapcache[$scope][$dn][$attribute]) && in_array($objectClass, $this->ldapcache[$scope][$dn]['objectClass'])) {
// return string if only attribute exists only once
if (count($this->ldapcache[$scope][$dn][$attribute])==1) $return[$dn] = array($this->ldapcache[$scope][$dn][$attribute][0]);
else {
// else return array with all attributes
$return[$dn] = $this->ldapcache[$scope][$dn][$attribute];
}
}
}
}
}
return $return;
}
/* This functions returns the dn if a dn with $attribute=$value is found
* $values is the value $attribute is set to
* $scope is the scope where to search
*/
function in_cache($value, $attribute, $singlescope) {
$this->refresh_cache();
// Check input variables
$allowed_types = array ( 'user', 'group', 'host', 'domain', '*' );
if (!in_array($singlescope, $allowed_types)) trigger_error(sprintf('Invalid scope. Valid scopes are %s.', implode(" ", $allowed_types)), E_USER_ERROR);
// Create list of all allowed attributes
for ($i=0; $i<count($_SESSION['ldap']->objectClasses); $i++ ) {
if (strpos($_SESSION['ldap']->objectClasses[$i], 'MUST (')) {
$string_withtail = substr($_SESSION['ldap']->objectClasses[$i], strpos($_SESSION['ldap']->objectClasses[$i], 'MUST (')+6);
// Now we have a string with all must-attributes
$string = substr($string_withtail, 0, strpos($string_withtail, ')'));
$string = trim($string);
$allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string));
}
// create array with may-attributes
// Get startposition in string
if (strpos($_SESSION['ldap']->objectClasses[$i], 'MAY (')) {
$string_withtail = substr($_SESSION['ldap']->objectClasses[$i], strpos($_SESSION['ldap']->objectClasses[$i], 'MAY (')+5);
// Now we have a string with all must-attributes
$string = substr($string_withtail, 0, strpos($string_withtail, ')'));
$string = trim($string);
$allowed_attributes = array_merge($allowed_attributes, explode(" $ ", $string));
}
}
$allowed_attributes = array_unique($allowed_attributes);
if (!in_array($attribute, $allowed_attributes)) trigger_error(_('Attribute not defined in LDAP.'), E_USER_WARNING);
// Everything seems to be OK, start processing data
$this->refresh_cache();
if ($singlescope == '*') $scopes = $allowed_types;
else $scopes = array ( $singlescope );
// Add cache entry dynamic
foreach ($scopes as $scope) {
if (!@in_array($attribute ,$this->attributes[$scope])) $add[$scope][] = $attribute;
}
if (count($add)!=0) $this->add_cache($add);
foreach ($scopes as $scope) {
if (isset($this->ldapcache[$scope])) {
$DNs = array_keys($this->ldapcache[$scope]);
foreach ($DNs as $dn) {
if (is_array($this->ldapcache[$scope][$dn][$attribute])) {
if (in_array($value, $this->ldapcache[$scope][$dn][$attribute])) {
// Return value if value was found
return $dn;
}
}
}
}
}
// Return false if value wasn't found
return false;
}
/* This functions refreshs the cache
*/
function refresh_cache($rebuild=false) {
if ($this->time + $_SESSION['config']->get_cacheTimeoutSec() < time() || $rebuild) {
// unset old cache
unset ($this->ldapcache);
$scopes = array_keys($this->attributes);
foreach ($scopes as $scope) {
// Get Scope
If ($scope != '*')
$suffix = call_user_func(array(&$_SESSION['config'], 'get_'.ucfirst($scope).'Suffix'));
else $suffix = '';
// Get Data from ldap
$search = $this->attributes[$scope];
$search[] = 'objectClass';
$result = @ldap_search($_SESSION['ldap']->server(), $suffix, 'objectClass=*', $search, 0);
// Write search result in array
$entry = @ldap_first_entry($_SESSION['ldap']->server(), $result);
while ($entry) {
$dn = (ldap_get_dn($_SESSION['ldap']->server(), $entry));
$attr = ldap_get_attributes($_SESSION['ldap']->server(), $entry);
// unset every count entry
unset ($attr['count']);
$attributes = array_keys($attr);
foreach ($attributes as $attribute) {
unset ($attr[$attribute]['count']);
}
// unset double entries
for ($i=0; $i<count($attr); $i++) {
if (isset($attr[$i])) unset($attr[$i]);
}
// Write new cache entry
$addcache = $attr;
unset ($addcache['objectClass']);
if (count($addcache)!=0) $this->ldapcache[$scope][$dn] = $attr;
$entry = ldap_next_entry($_SESSION['ldap']->server(), $entry);
}
}
$this->time = time();
}
}
/* This function update the cache when changes were
* made without refrehing the complete cache
*/
function update_cache($dn, $mode, $attributes=false) {
$allowed_modes = array ( 'add', 'remove', 'modify', 'delete_dn' );
$allowed_types = array ( 'user', 'group', 'host', '*' );
for ($i=0; $i<count($allowed_types); $i++) {
if ($allowed_types[$i]!='*') {
// *** fixme, where is get_DomainSuffix
If ($scope != '*')
$suffix = call_user_func(array(&$_SESSION['config'], 'get_'.ucfirst($allowed_types[$i]).'Suffix'));
else $suffix = '';
if (substr($suffix, $dn)) $singlescope = $allowed_types[$i];
}
}
if (!in_array($singlescope, $allowed_types)) trigger_error(sprintf('Invalid scope. Valid scopes are %s.', implode(" ", $allowed_types)), E_USER_ERROR);
if (!in_array($mode, $allowed_modes)) trigger_error(sprintf('Invalid mode. Valid modes are %s.', implode(" ", $allowed_modes)), E_USER_ERROR);
// Everything seems to be OK, start processing data
// Get Scope
foreach ($allowed_types as $scope) {
if ($scope!='*') {
$suffix = call_user_func(array(&$_SESSION['config'], 'get_'.ucfirst($scope).'Suffix'));
if (strpos($dn, $suffix)) $singlescope = $scope;
}
}
if (!isset($singlescope)) trigger_error(sprintf('Invalid dn: %s. DN not covered by any suffix.', $dn), E_USER_WARN);
// Refresh Cache
$this->refresh_cache();
if (is_array($attributes))
switch ($mode) {
case 'add':
$list = array_keys($attributes);
for ($i=0; $i<count($list); $i++)
foreach ($attributes[$list[$i]] as $attribute)
$this->ldapcache[$singlescope][$dn][$list[$i]][] = $attributes[$list[$i]];
break;
case 'remove':
$list = array_keys($attributes);
for ($i=0; $i<count($list); $i++)
foreach ($attributes[$list[$i]] as $attribute)
if (isset($this->ldapcache[$singlescope][$dn][$list[$i]][$attributes[$list[$i]]]))
unset($this->ldapcache[$singlescope][$dn][$list[$i]][$attributes[$list[$i]]]);
break;
case 'modify':
$list = array_keys($attributes);
for ($i=0; $i<count($list); $i++) {
if (isset($this->ldapcache[$singlescope][$dn][$list[$i]])) unset($this->ldapcache[$singlescope][$dn][$list[$i]]);
foreach ($attributes[$list[$i]] as $attribute)
$this->ldapcache[$singlescope][$dn][$list[$i]][] = $attributes[$list[$i]];
}
}
else {
if ($mode=='delete_dn')
if (isset($this->ldapcache[$singlescope][$dn])) unset($this->ldapcache[$singlescope][$dn]);
}
}
/* This function will return the gidNumber to an existing groupname
* gidNumbers are taken from cache-array
*/
function getgid($groupname) {
$dn_groups = $_SESSION['cache']->get_cache('gidNumber', 'posixGroup', 'group');
$DNs = array_keys($dn_groups);
foreach ($DNs as $DN) {
// TODO doesn't work when groupname is part of DN
if (strpos($DN, $groupname))
return $dn_groups[$DN][0];
}
}
/* This function will return an array with all groupnames
* found in ldap. Groupnames are taken from cache-array.
*/
function findgroups() {
$dn_groups = $_SESSION['cache']->get_cache('cn', 'posixGroup', 'group');
if (is_array($dn_groups)) {
$DNs = array_keys($dn_groups);
foreach ($DNs as $DN)
$return[] = $dn_groups[$DN][0];
return $return;
}
return array();
}
/* This function will return the groupname to an existing gidNumber
* groupnames are taken from cache-array
*/
function getgrnam($gidNumber) {
$dn_groups = $_SESSION['cache']->get_cache('gidNumber', 'posixGroup', 'group');
if (is_array($dn_groups)) {
$DNs = array_keys($dn_groups);
foreach ($DNs as $DN) {
if ($dn_groups[$DN][0]==$gidNumber)
$return = substr($DN, 3, strpos($DN, ',')-3);
}
return $return;
}
else return -1;
}
}
?>

View File

@ -1,902 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 - 2004 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This file includes functions to manage the configuration files.
*
* @package configuration
* @author Roland Gruber
*/
/** Used to print messages. */
include_once("status.inc");
/** Used to get module information. */
include_once("modules.inc");
/**
* Sets language settings for automatic translation
*/
function setlanguage() {
if (!isset($_SESSION['language'])) {
$_SESSION['language'] = "en_GB.utf8:UTF-8:English (Great Britain)";
}
$language = explode(":", $_SESSION['language']);
putenv("LANG=" . $language[0]); // e.g. LANG=de_DE
setlocale(LC_ALL, $language[0]); // set LC_ALL to de_DE
$locdir = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/locale"; // set path to translations
bindtextdomain("messages", $locdir);
textdomain("messages");
header("Content-type: text/html; charset=" . $language[1], true);
}
/**
* Returns an array of string with all available configuration profiles (without .conf)
*
* @return array profile names
*/
function getConfigProfiles() {
$dir = dir(substr(__FILE__, 0, strlen(__FILE__) - 15) . "/config");
$ret = array();
$pos = 0;
while ($entry = $dir->read()){
$ext = substr($entry, strlen($entry)-5, 5);
$name = substr($entry, 0, strlen($entry)-5);
// check if extension is right, add to profile list
if ($ext == ".conf") {
$ret[$pos] = $name;
$pos ++;
}
}
sort($ret);
return $ret;
}
/**
* Prints a meta refresh page
*
* @param string $page the URL of the target page
*/
function metaRefresh($page) {
echo $_SESSION['header'];
echo "<meta http-equiv=\"refresh\" content=\"0; URL=" . $page . "\">\n";
echo "<title></title>\n";
echo "</head>\n";
echo "<body>\n";
// print link if refresh does not work
echo "<p>\n";
echo "<a href=\"" . $page . "\">" . _("Click here if you are not directed to the next page.") . "</a>\n";
echo "</p>\n";
echo "</body>\n";
echo "</html>\n";
}
/**
* This class manages .conf files.
*
* @package configuration
*/
class Config {
/** Server address (e.g. ldap://127.0.0.1:389) */
var $ServerURL;
/** Array of string: users with admin rights */
var $Admins;
/** Password to edit preferences */
var $Passwd;
/** LDAP suffix for users */
var $usersuffix;
/** LDAP suffix for groups */
var $groupsuffix;
/** LDAP suffix for Samba hosts */
var $hostsuffix;
/** LDAP suffix for Samba 3 domains */
var $domainsuffix;
/** Attributes that are shown in the user list */
var $userlistAttributes;
/** Attributes that are shown in the group list */
var $grouplistAttributes;
/** Attributes that are shown in the host list */
var $hostlistAttributes;
/** Maximum number of rows shown in user/group/host lists */
var $maxlistentries;
/** Default language */
var $defaultLanguage;
/** module settings */
var $moduleSettings = array();
/**
* Path to external lamdaemon script on server where it is executed
*
* This is used for managing quota and home directories.
* optional setting, may not be defined
*/
var $scriptPath;
/**
* Server where lamdaemon script is executed
*
* This is used for managing quota and home directories.
* optional setting, may not be defined
*/
var $scriptServer;
/** LDAP cache timeout */
var $cachetimeout;
var $usermodules = "posixAccount,shadowAccount,quota";
/** Account modules for groups */
var $groupmodules = "posixGroup,quota";
/** Account modules for hosts */
var $hostmodules = "account,sambaSamAccount";
/** Name of configuration file */
var $file;
/** List of all settings in config file */
var $settings = array("ServerURL", "Passwd", "Admins", "usersuffix", "groupsuffix", "hostsuffix",
"domainsuffix", "userlistAttributes", "grouplistAttributes", "hostlistAttributes", "maxlistentries",
"defaultLanguage", "scriptPath", "scriptServer", "cachetimeout",
"usermodules", "groupmodules", "hostmodules", "modules");
/**
* Loads preferences from config file
*
* @param integer $file Index number in config file array
*/
function Config($file = 0) {
// load first profile if none is given
if (!is_string($file)) {
$profiles = getConfigProfiles();
$file = $profiles[0];
}
$this->file = $file;
$this->reload();
}
/**
* Reloads preferences from config file
*
* @return boolean true if file was readable
*/
function reload() {
$conffile = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/config/" . $this->file . ".conf";
if (is_file($conffile) == True) {
$file = @fopen($conffile, "r");
if (!$file) return false; // abort if file is not readable
while (!feof($file)) {
$line = fgets($file, 1024);
$line = trim($line); // remove spaces at the beginning and end
if (($line == "")||($line[0] == "#")) continue; // ignore comments and empty lines
// search keywords
for ($i = 0; $i < sizeof($this->settings); $i++) {
$keyword = $this->settings[$i];
$keylen = strlen($keyword);
if (strtolower(substr($line, 0, $keylen + 2)) == strtolower($keyword . ": ")) {
// module settings
if (strtolower(substr($line, 0, $keylen + 2)) == "modules: ") {
$option = substr($line, $keylen + 2, strlen($line) - $keylen - 2);
$pos = strpos($option, ":");
$this->moduleSettings[substr($option, 0, $pos)] = explode("+::+", substr($option, $pos + 2, strlen($option) - $pos - 2));
}
// general settings
else {
$this->$keyword = substr($line, $keylen + 2, strlen($line) - $keylen - 2);
}
break;
}
}
}
fclose($file);
}
// check modules
$scopes = array('user', 'group', 'host');
for ($s = 0; $s < sizeof($scopes); $s++) {
$scope = $scopes[$s];
$moduleVar = $scope . "modules";
$modules = explode(",", $this->$moduleVar);
$available = getAvailableModules($scope);
// only return available modules
$ret = array();
for ($i = 0; $i < sizeof($modules); $i++) {
if (in_array($modules[$i], $available)) $ret[] = $modules[$i];
}
$this->$moduleVar = implode(",", $ret);
}
return true;
}
/** Saves preferences to config file */
function save() {
$conffile = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/config/" . $this->file . ".conf";
if (is_file($conffile) == True) {
$file = fopen($conffile, "r");
$file_array = array();
// read config file
while (!feof($file)) {
array_push($file_array, fgets($file, 1024));
}
fclose($file);
// generate new configuration file
$saved = array(); // includes all settings which have been saved
$mod_saved = array(); // includes all module settings which have been saved
for ($i = 0; $i < sizeof($file_array); $i++) {
$line = trim($file_array[$i]);
if (($line == "")||($line[0] == "#")) continue; // ignore comments and empty lines
// search for keywords
for ($k = 0; $k < sizeof($this->settings); $k++) {
$keyword = $this->settings[$k];
$keylen = strlen($keyword);
if (strtolower(substr($line, 0, $keylen + 1)) == strtolower($keyword . ":")) {
// module settings
if (strtolower(substr($line, 0, $keylen + 2)) == "modules: ") {
$option = substr($line, $keylen + 2, strlen($line) - $keylen - 2);
$pos = strpos($option, ":");
$name = substr($option, 0, $pos);
if (!isset($this->moduleSettings[$name])) continue;
$file_array[$i] = "modules: " . $name . ": " . implode("+::+", $this->moduleSettings[$name]) . "\n";
$mod_saved[] = $name; // mark keyword as saved
}
// general settings
else {
$file_array[$i] = $keyword . ": " . $this->$keyword . "\n";
$saved[] = $keyword; // mark keyword as saved
}
break;
}
}
}
// check if we have to add new entries (e.g. if user upgraded LAM and has an old config file)
if (!in_array("ServerURL", $saved)) array_push($file_array, "\n\n# server address (e.g. ldap://localhost:389 or ldaps://localhost:636)\n" . "serverURL: " . $this->ServerURL . "\n");
if (!in_array("Passwd", $saved)) array_push($file_array, "\n\n# password to change these preferences via webfrontend\n" . "passwd: " . $this->Passwd . "\n");
if (!in_array("Admins", $saved)) array_push($file_array, "\n\n# list of users who are allowed to use LDAP Account Manager\n" .
"# names have to be seperated by semicolons\n" .
"# e.g. admins: cn=admin,dc=yourdomain,dc=org;cn=root,dc=yourdomain,dc=org\n" . "admins: " . $this->Admins . "\n");
if (!in_array("usersuffix", $saved)) array_push($file_array, "\n\n# suffix of users\n" .
"# e.g. ou=People,dc=yourdomain,dc=org\n" . "usersuffix: " . $this->usersuffix . "\n");
if (!in_array("groupsuffix", $saved)) array_push($file_array, "\n\n# suffix of groups\n" .
"# e.g. ou=Groups,dc=yourdomain,dc=org\n" . "groupsuffix: " . $this->groupsuffix . "\n");
if (!in_array("hostsuffix", $saved)) array_push($file_array, "\n\n# suffix of Samba hosts\n" .
"# e.g. ou=machines,dc=yourdomain,dc=org\n" . "hostsuffix: " . $this->hostsuffix . "\n");
if (!in_array("domainsuffix", $saved)) array_push($file_array, "\n\n# suffix of Samba 3 domains\n" .
"# e.g. ou=domains,dc=yourdomain,dc=org\n" . "domainsuffix: " . $this->domainsuffix . "\n");
if (!in_array("userlistAttributes", $saved)) array_push($file_array, "\n\n# list of attributes to show in user list\n# entries can either be predefined values (e.g. '#cn' or '#uid')" .
"\n# or individual ones (e.g. 'uid:User ID' or 'host:Host Name')\n# values have to be seperated by semicolons\n" . "userlistAttributes: " . $this->userlistAttributes . "\n");
if (!in_array("grouplistAttributes", $saved)) array_push($file_array, "\n\n# list of attributes to show in group list\n# entries can either be predefined values (e.g. '#cn' or '#gidNumber')" .
"\n# or individual ones (e.g. 'cn:Group Name')\n# values have to be seperated by semicolons\n" . "grouplistAttributes: " . $this->grouplistAttributes . "\n");
if (!in_array("hostlistAttributes", $saved)) array_push($file_array, "\n\n# list of attributes to show in host list\n# entries can either be predefined values (e.g. '#cn' or '#uid')" .
"\n# or individual ones (e.g. 'cn:Host Name')\n# values have to be seperated by semicolons\n" . "hostlistAttributes: " . $this->hostlistAttributes . "\n");
if (!in_array("maxlistentries", $saved)) array_push($file_array, "\n\n# maximum number of rows to show in user/group/host lists\n" . "maxlistentries: " . $this->maxlistentries . "\n");
if (!in_array("defaultLanguage", $saved)) array_push($file_array, "\n\n# default language (a line from config/language)\n" . "defaultLanguage: " . $this->defaultLanguage . "\n");
if (!in_array("scriptPath", $saved)) array_push($file_array, "\n\n# Path to external Script\n" . "scriptPath: " . $this->scriptPath . "\n");
if (!in_array("scriptServer", $saved)) array_push($file_array, "\n\n# Server of external Script\n" . "scriptServer: " . $this->scriptServer . "\n");
if (!in_array("cachetimeout", $saved)) array_push($file_array, "\n\n# Number of minutes LAM caches LDAP searches.\n" . "cacheTimeout: " . $this->cachetimeout . "\n");
if (!in_array("usermodules", $saved)) array_push($file_array, "\n\n# List of used user modules\n" . "usermodules: " . $this->usermodules . "\n");
if (!in_array("groupmodules", $saved)) array_push($file_array, "\n\n# List of used group modules\n" . "groupmodules: " . $this->groupmodules . "\n");
if (!in_array("hostmodules", $saved)) array_push($file_array, "\n\n# List of used host modules\n" . "hostmodules: " . $this->hostmodules . "\n");
// check if all module settings were added
$m_settings = array_keys($this->moduleSettings);
for ($i = 0; $i < sizeof($m_settings); $i++) {
if (!in_array($m_settings[$i], $mod_saved)) {
array_push($file_array, "modules: " . $m_settings[$i] . ": " . implode("+::+", $this->moduleSettings[$m_settings[$i]]) . "\n");
}
}
$file = fopen($conffile, "w");
if ($file) {
for ($i = 0; $i < sizeof($file_array); $i++) fputs($file, $file_array[$i]);
fclose($file);
@chmod ($conffile, 0600);
}
else {
StatusMessage("ERROR", "", _("Cannot open config file!") . " (" . $conffile . ")");
exit;
}
}
}
/** Prints current preferences */
function printconf() {
echo "<b>" . _("Server address") . ": </b>" . $this->ServerURL . "<br>\n";
echo "<b>" . _("Cache timeout") . ": </b>" . $this->cachetimeout . "<br>\n";
echo "<b>" . _("UserSuffix") . ": </b>" . $this->usersuffix . "<br>\n";
echo "<b>" . _("GroupSuffix") . ": </b>" . $this->groupsuffix . "<br>\n";
echo "<b>" . _("HostSuffix") . ": </b>" . $this->hostsuffix . "<br>\n";
echo "<b>" . _("DomainSuffix") . ": </b>" . $this->domainsuffix . "<br>\n";
echo "<b>" . _("Attributes in User List") . ": </b>" . $this->userlistAttributes . "<br>\n";
echo "<b>" . _("Attributes in Group List") . ": </b>" . $this->grouplistAttributes . "<br>\n";
echo "<b>" . _("Attributes in Host List") . ": </b>" . $this->hostlistAttributes . "<br>\n";
echo "<b>" . _("Maximum list entries") . ": </b>" . $this->maxlistentries . "<br>\n";
echo "<b>" . _("Default language") . ": </b>" . $this->defaultLanguage . "<br>\n";
echo "<b>" . _("Path to external script") . ": </b>" . $this->scriptPath . "<br>\n";
echo "<b>" . _("Server of external script") . ": </b>" . $this->scriptServer . "<br>\n";
echo "<b>" . _("List of valid users") . ": </b>" . $this->Admins . "<br>\n";
echo "<b>" . _("User modules") . ": </b>" . $this->usermodules . "<br>\n";
echo "<b>" . _("Group modules") . ": </b>" . $this->groupmodules . "<br>\n";
echo "<b>" . _("Host modules") . ": </b>" . $this->hostmodules . "<br><br>\n";
echo "<b>" . _("Module settings") . ": </b><br>\n";
echo "<ul>\n";
$names = array_keys($this->moduleSettings);
$descriptions = getConfigDescriptions();
$descriptions = $descriptions['descriptions'];
for ($i = 0; $i < sizeof($names); $i++) {
echo "<li><b>";
// print description if available
if (isset($descriptions[$names[$i]])) echo $descriptions[$names[$i]];
else echo $names[$i];
echo ": </b>" . implode(", ", $this->moduleSettings[$names[$i]]) . "</li>\n";
}
echo "</ul>\n";
}
// functions to read/write preferences
/**
* Returns the server address as string
*
* @return string server address
*/
function get_ServerURL() {
return $this->ServerURL;
}
/**
* Sets the server address
*
* @param string $value new server address
* @return boolean true if $value has correct format
*/
function set_ServerURL($value) {
if (is_string($value)) $this->ServerURL = $value;
else return false;
return true;
}
/**
* Returns an array of string with all admin names
*
* @return array the admin names
*/
function get_Admins() {
return explode(";", $this->Admins);
}
/**
* Returns all admin users seperated by semicolons
*
* @return string the admin string
*/
function get_Adminstring() {
return $this->Admins;
}
/**
* Sets the admin string
*
* @param string $value new admin string that contains all admin users seperated by semicolons
* @return boolean true if $value has correct format
*/
function set_Adminstring($value) {
if (is_string($value) &&
eregi("^[^;]+(;[^;]+)*$", $value)) {
$this->Admins = $value;
}
else return false;
return true;
}
/**
* Returns the password to access the preferences wizard
*
* @return string the password
*/
function get_Passwd() {
return $this->Passwd;
}
/**
* Sets the preferences wizard password
*
* @param string $value new password
* @return boolean true if $value has correct format
*/
function set_Passwd($value) {
if (is_string($value)) $this->Passwd = $value;
else return false;
return true;
}
/**
* Returns the LDAP suffix where users are saved
*
* @return string the user suffix
*/
function get_UserSuffix() {
return $this->usersuffix;
}
/**
* Sets the LDAP suffix where users are saved
*
* @param string $value new user suffix
* @return boolean true if $value has correct format
*/
function set_UserSuffix($value) {
if (is_string($value)) {
$this->usersuffix = $value;
}
else return false;
return true;
}
/**
* returns the LDAP suffix where groups are saved
*
* @return string the group suffix
*/
function get_GroupSuffix() {
return $this->groupsuffix;
}
/**
* Sets the LDAP suffix where groups are saved
*
* @param string $value new group suffix
* @return boolean true if $value has correct format
*/
function set_GroupSuffix($value) {
if (is_string($value)) {
$this->groupsuffix = $value;
}
else return false;
return true;
}
/**
* returns the LDAP suffix where hosts are saved
*
* @return string the host suffix
*/
function get_HostSuffix() {
return $this->hostsuffix;
}
/**
* Sets the LDAP suffix where hosts are saved
*
* @param string $value new host suffix
* @return boolean true if $value has correct format
*/
function set_HostSuffix($value) {
if (! $value) $this->hostsuffix = "";
elseif (is_string($value)) {
$this->hostsuffix = $value;
}
else return false;
return true;
}
/**
* Returns the LDAP suffix where domains are saved
*
* @return string the domain suffix
*/
function get_DomainSuffix() {
return $this->domainsuffix;
}
/**
* Sets the LDAP suffix where domains are saved
*
* @param string $value new domain suffix
* @return boolean true if $value has correct format
*/
function set_DomainSuffix($value) {
if (!$value) $this->domainsuffix = "";
elseif (is_string($value)) {
$this->domainsuffix = $value;
}
else return false;
return true;
}
/**
* Returns the list of attributes to show in user list
*
* @return string the attribute list
*/
function get_userlistAttributes() {
return $this->userlistAttributes;
}
/**
* Sets the list of attributes to show in user list
*
* @param string $value new attribute string
* @return boolean true if $value has correct format
*/
function set_userlistAttributes($value) {
if (is_string($value) && eregi("^((#[^:;]+)|([^:;]*:[^:;]+))(;((#[^:;]+)|([^:;]*:[^:;]+)))*$", $value)) {
$this->userlistAttributes = $value;
}
else return false;
return true;
}
/**
* Returns the list of attributes to show in group list
*
* @return string the attribute list
*/
function get_grouplistAttributes() {
return $this->grouplistAttributes;
}
/**
* Sets the list of attributes to show in group list
*
* @param string $value new attribute string
* @return boolean true if $value has correct format
*/
function set_grouplistAttributes($value) {
if (is_string($value) && eregi("^((#[^:;]+)|([^:;]*:[^:;]+))(;((#[^:;]+)|([^:;]*:[^:;]+)))*$", $value)) {
$this->grouplistAttributes = $value;
}
else return false;
return true;
}
/**
* Returns the list of attributes to show in host list
*
* @return string the attribute list
*/
function get_hostlistAttributes() {
return $this->hostlistAttributes;
}
/**
* Sets the list of attributes to show in host list
*
* @param string $value new attribute string
* @return boolean true if $value has correct format
*/
function set_hostlistAttributes($value) {
if (! $value && ($this->hostsuffix == "")) $this->hostlistAttributes = "";
elseif (is_string($value) && eregi("^((#[^:;]+)|([^:;]*:[^:;]+))(;((#[^:;]+)|([^:;]*:[^:;]+)))*$", $value)) {
$this->hostlistAttributes = $value;
}
else return false;
return true;
}
/**
* Returns the maximum number of rows in user/group/host lists
*
* @return integer maximum number
*/
function get_MaxListEntries() {
return $this->maxlistentries;
}
/**
* Sets the maximum number of rows in user/group/host lists
*
* @param integer $value new maximum value
* @return boolean true if $value has correct format
*/
function set_MaxListEntries ($value) {
if (is_numeric($value)) $this->maxlistentries = $value;
else return false;
return true;
}
/**
* Returns the default language string
*
* @return string default language
*/
function get_defaultLanguage() {
return $this->defaultLanguage;
}
/**
* Sets the default language string
*
* @param string $value new default language
* @return boolean true if $value has correct format
*/
function set_defaultLanguage($value) {
if (is_string($value)) $this->defaultLanguage = $value;
else return false;
return true;
}
/**
* Returns the path to the external script
*
* @return string script path
*/
function get_scriptPath() {
return $this->scriptPath;
}
/**
* Sets the path to the external script
*
* @param string $value new script path
* @return boolean true if $value has correct format
*/
function set_scriptPath($value) {
if (!$value) $this->scriptPath = ""; // optional parameter
elseif (is_string($value) && eregi("^/([a-z0-9_\\-])+(/([a-z0-9_\\.\\-])+)+$", $value)) $this->scriptPath = $value;
else return false;
return true;
}
/**
* Returns the server of the external script
*
* @return string script server
*/
function get_scriptServer() {
return $this->scriptServer;
}
/**
* Sets the server of the external script
*
* @param string $value new script server
* @return boolean true if $value has correct format
*/
function set_scriptServer($value) {
if (!$value) $this->scriptServer = ""; // optional parameter
elseif (is_string($value) && eregi("^[a-z0-9\\-]+(\\.[a-z0-9\\-]+)*$", $value)) {
$this->scriptServer = $value;
}
else return false;
return true;
}
/**
* Returns the LDAP cache timeout in minutes
*
* @return integer cache time
*/
function get_cacheTimeout() {
if (isset($this->cachetimeout)) return $this->cachetimeout;
else return 5;
}
/**
* Returns the LDAP cache timeout in seconds
*
* @return integer cache time
*/
function get_cacheTimeoutSec() {
return $this->cachetimeout * 60;
}
/**
* Sets the LDAP cache timeout in minutes (0,1,2,5,10,15)
*
* @param integer $value new cache timeout
* @return boolean true if $value has correct format
*/
function set_cacheTimeout($value) {
if (is_numeric($value) && ($value > -1)) {
$this->cachetimeout = $value;
}
else return false;
return true;
}
/**
* Returns an array of all selected account modules
*
* @param string $scope account type
* @return array user modules
*/
function get_AccountModules($scope) {
switch ($scope) {
case 'user':
return explode(",", $this->usermodules);
break;
case 'group':
return explode(",", $this->groupmodules);
break;
case 'host':
return explode(",", $this->hostmodules);
break;
default:
return array();
break;
}
}
/**
* Sets the selected account modules
*
* @param array $modules array with module names (not aliases!)
* @param string $scope account type
* @return boolean true if $modules has correct format
*/
function set_AccountModules($modules, $scope) {
if (! is_array($modules)) return false;
// check module names
$available = getAvailableModules($scope);
for ($i = 0; $i < sizeof($modules); $i++) {
if (! in_array($modules[$i], $available)) return false;
}
// check depends/conflicts
if (check_module_conflicts($modules, getModulesDependencies($scope)) != false) return false;
if (check_module_depends($modules, getModulesDependencies($scope)) != false) return false;
switch ($scope) {
case 'user':
$this->usermodules = implode(",", $modules);
break;
case 'group':
$this->groupmodules = implode(",", $modules);
break;
case 'host':
$this->hostmodules = implode(",", $modules);
break;
default:
break;
}
return true;
}
/**
* Sets the settings for the account modules.
*
* @param array $settings list of module setting array(name => value)
* @return boolean true if $settings has correct format
*/
function set_moduleSettings($settings) {
if (!is_array($settings)) return false;
$this->moduleSettings = $settings;
return true;
}
/**
* Returns a list of saved module settings
*
* @return array list of settings: array(name => value)
*/
function get_moduleSettings() {
return $this->moduleSettings;
}
}
/**
* This class manages config.cfg.
*
* @package configuration
*/
class CfgMain {
/** Default profile */
var $default;
/** Password to change config.cfg */
var $password;
/**
* Loads preferences from config file
*/
function CfgMain() {
$this->reload();
}
/**
* Reloads preferences from config file config.cfg
*
* @return boolean true if file was readable
*/
function reload() {
$conffile = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/config/config.cfg";
if (is_file($conffile) == True) {
$file = @fopen($conffile, "r");
if (!$file) return false; // abort if file is not readable
while (!feof($file)) {
$line = fgets($file, 1024);
$line = trim($line); // remove spaces at the beginning and end
if (($line == "")||($line[0] == "#")) continue; // ignore comments
// search keywords
if (substr($line, 0, 10) == "password: ") {
$this->password = substr($line, 10, strlen($line)-10);
continue;
}
if (substr($line, 0, 9) == "default: ") {
$this->default = substr($line, 9, strlen($line)-9);
continue;
}
}
fclose($file);
}
return true;
}
/**
* Saves preferences to config file config.cfg
*/
function save() {
$conffile = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/config/config.cfg";
if (is_file($conffile) == True) {
// booleans to check if value was already saved
$save_password = $save_default = False;
$file = fopen($conffile, "r");
$file_array = array();
// read config file
while (!feof($file)) {
array_push($file_array, fgets($file, 1024));
}
fclose($file);
// generate new configuration file
for ($i = 0; $i < sizeof($file_array); $i++) {
if (($file_array[$i] == "\n")||($file_array[$i][0] == "#")) continue; // ignore comments
// search for keywords
if (substr($file_array[$i], 0, 10) == "password: ") {
$file_array[$i] = "password: " . $this->password . "\n";
$save_password = True;
continue;
}
if (substr($file_array[$i], 0, 9) == "default: ") {
$file_array[$i] = "default: " . $this->default . "\n";
$save_default = True;
continue;
}
}
}
// check if we have to add new entries (e.g. if user upgraded LAM and has an old config file)
if (!$save_password == True) array_push($file_array, "\n\n# password to add/delete/rename configuration profiles\n" . "password: " . $this->password);
if (!$save_default == True) array_push($file_array, "\n\n# default profile, without \".conf\"\n" . "default: " . $this->default);
$file = fopen($conffile, "w");
if ($file) {
for ($i = 0; $i < sizeof($file_array); $i++) fputs($file, $file_array[$i]);
fclose($file);
}
else {
StatusMessage("ERROR", "", _("Cannot open config file!") . " (" . $conffile . ")");
exit;
}
}
}
?>

View File

@ -1,519 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2004 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This class provides functions to calculate Samba NT and LM hashes.
*
* The code is a conversion from createntlm.pl (Benjamin Kuit) and smbdes.c/md4.c (Andrew Tridgell).
*
* @author Roland Gruber
*
* @package modules
*/
/**
* Calculates NT and LM hashes.
*
* The important functions are lmhash($password) and nthash($password).
*
* @package modules
*/
class smbHash {
# Contants used in lanlam hash calculations
# Ported from SAMBA/source/libsmb/smbdes.c:perm1[56]
var $perm1 = array(57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4);
# Ported from SAMBA/source/libsmb/smbdes.c:perm2[48]
var $perm2 = array(14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32);
# Ported from SAMBA/source/libsmb/smbdes.c:perm3[64]
var $perm3 = array(58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7);
# Ported from SAMBA/source/libsmb/smbdes.c:perm4[48]
var $perm4 = array(32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1);
# Ported from SAMBA/source/libsmb/smbdes.c:perm5[32]
var $perm5 = array(16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25);
# Ported from SAMBA/source/libsmb/smbdes.c:perm6[64]
var $perm6 = array(40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25);
# Ported from SAMBA/source/libsmb/smbdes.c:sc[16]
var $sc = array(1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1);
# Ported from SAMBA/source/libsmb/smbdes.c:sbox[8][4][16]
# Side note, I used cut and paste for all these numbers, I did NOT
# type them all in =)
var $sbox = array(array(array(14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7),
array( 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8),
array( 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0),
array(15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13)),
array(array(15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10),
array( 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5),
array( 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15),
array(13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9)),
array(array(10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8),
array(13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1),
array(13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7),
array( 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12)),
array(array( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15),
array(13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9),
array(10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4),
array( 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14)),
array(array( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9),
array(14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6),
array( 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14),
array(11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3)),
array(array(12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11),
array(10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8),
array( 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6),
array( 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13)),
array(array( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1),
array(13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6),
array( 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2),
array( 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12)),
array(array(13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7),
array( 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2),
array( 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8),
array( 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)));
/**
* @param integer count
* @param array $data
* @return array
*/
function lshift($count, $data) {
$ret = array();
for ($i = 0; $i < sizeof($data); $i++) {
$ret[$i] = $data[($i + $count)%sizeof($data)];
}
return $ret;
}
/**
* @param array in input data
* @param array p permutation
* @return array
*/
function permute($in, $p, $n) {
$ret = array();
for ($i = 0; $i < $n; $i++) {
$ret[$i] = $in[$p[$i] - 1]?1:0;
}
return $ret;
}
/**
* @param array $in1
* @param array $in2
* @return array
*/
function mxor($in1, $in2) {
$ret = array();
for ($i = 0; $i < sizeof($in1); $i++) {
$ret[$i] = $in1[$i] ^ $in2[$i];
}
return $ret;
}
/**
* @param array $in
* @param array $key
* @param boolean $forw
* @return array
*/
function doHash($in, $key, $forw) {
$ki = array();
$pk1 = $this->permute($key, $this->perm1, 56);
$c = array();
$d = array();
for ($i = 0; $i < 28; $i++) {
$c[$i] = $pk1[$i];
$d[$i] = $pk1[28 + $i];
}
for ($i = 0; $i < 16; $i++) {
$c = $this->lshift($this->sc[$i], $c);
$d = $this->lshift($this->sc[$i], $d);
$cd = $c;
for ($k = 0; $k < sizeof($d); $k++) $cd[] = $d[$k];
$ki[$i] = $this->permute($cd, $this->perm2, 48);
}
$pd1 = $this->permute($in, $this->perm3, 64);
$l = array();
$r = array();
for ($i = 0; $i < 32; $i++) {
$l[$i] = $pd1[$i];
$r[$i] = $pd1[32 + $i];
}
for ($i = 0; $i < 16; $i++) {
$er = $this->permute($r, $this->perm4, 48);
if ($forw) $erk = $this->mxor($er, $ki[$i]);
else $erk = $this->mxor($er, $ki[15 - $i]);
for ($j = 0; $j < 8; $j++) {
for ($k = 0; $k < 6; $k++) {
$b[$j][$k] = $erk[($j * 6) + $k];
}
}
for ($j = 0; $j < 8; $j++) {
$m = array();
$n = array();
$m = ($b[$j][0] << 1) | $b[$j][5];
$n = ($b[$j][1] << 3) | ($b[$j][2] << 2) | ($b[$j][3] << 1) | $b[$j][4];
for ($k = 0; $k < 4; $k++) {
$b[$j][$k]=($this->sbox[$j][$m][$n] & (1 << (3-$k)))?1:0;
}
}
for ($j = 0; $j < 8; $j++) {
for ($k = 0; $k < 4; $k++) {
$cb[($j * 4) + $k] = $b[$j][$k];
}
}
$pcb = $this->permute($cb, $this->perm5, 32);
$r2 = $this->mxor($l, $pcb);
for ($k = 0; $k < 32; $k++) $l[$k] = $r[$k];
for ($k = 0; $k < 32; $k++) $r[$k] = $r2[$k];
}
$rl = $r;
for ($i = 0; $i < sizeof($l); $i++) $rl[] = $l[$i];
return $this->permute($rl, $this->perm6, 64);
}
function str_to_key($str) {
$key[0] = $this->unsigned_shift_r($str[0], 1);
$key[1] = (($str[0]&0x01)<<6) | $this->unsigned_shift_r($str[1], 2);
$key[2] = (($str[1]&0x03)<<5) | $this->unsigned_shift_r($str[2], 3);
$key[3] = (($str[2]&0x07)<<4) | $this->unsigned_shift_r($str[3], 4);
$key[4] = (($str[3]&0x0F)<<3) | $this->unsigned_shift_r($str[4], 5);
$key[5] = (($str[4]&0x1F)<<2) | $this->unsigned_shift_r($str[5], 6);
$key[6] = (($str[5]&0x3F)<<1) | $this->unsigned_shift_r($str[6], 7);
$key[7] = $str[6]&0x7F;
for ($i = 0; $i < 8; $i++) {
$key[$i] = ($key[$i] << 1);
}
return $key;
}
function smb_hash($in, $key, $forw){
$key2 = $this->str_to_key($key);
for ($i = 0; $i < 64; $i++) {
$inb[$i] = ($in[$i/8] & (1<<(7-($i%8)))) ? 1:0;
$keyb[$i] = ($key2[$i/8] & (1<<(7-($i%8)))) ? 1:0;
$outb[$i] = 0;
}
$outb = $this->dohash($inb, $keyb, $forw);
for ($i = 0; $i < 8; $i++) {
$out[$i] = 0;
}
for ($i = 0; $i < 65; $i++) {
if ( $outb[$i] ) {
$out[$i/8] |= (1<<(7-($i%8)));
}
}
return $out;
}
function E_P16($in) {
$p14 = array_values(unpack("C*",$in));
$sp8 = array(0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25);
$p14_1 = array();
$p14_2 = array();
for ($i = 0; $i < 7; $i++) {
$p14_1[$i] = $p14[$i];
$p14_2[$i] = $p14[$i + 7];
}
$p16_1 = $this->smb_hash($sp8, $p14_1, true);
$p16_2 = $this->smb_hash($sp8, $p14_2, true);
$p16 = $p16_1;
for ($i = 0; $i < sizeof($p16_2); $i++) {
$p16[] = $p16_2[$i];
}
return $p16;
}
/**
* Calculates the LM hash of a given password.
*
* @param string $password password
* @return string hash value
*/
function lmhash($password = "") {
$password = strtoupper($password);
$password = substr($password,0,14);
$password = str_pad($password, 14, chr(0));
$p16 = $this->E_P16($password);
for ($i = 0; $i < sizeof($p16); $i++) {
$p16[$i] = sprintf("%02X", $p16[$i]);
}
return join("", $p16);
}
/**
* Calculates the NT hash of a given password.
*
* @param string $password password
* @return string hash value
*/
function nthash($password = "") {
$password = substr($password,0,128);
$password2 = "";
for ($i = 0; $i < strlen($password); $i++) $password2 .= $password[$i] . chr(0);
$password = $password2;
$hex = $this->mdfour($password);
for ($i = 0; $i < sizeof($hex); $i++) {
$hex[$i] = sprintf("%02X", $hex[$i]);
}
return join("", $hex);
}
# Support functions
# Ported from SAMBA/source/lib/md4.c:F,G and H respectfully
function F($X, $Y, $Z) {
return ($X&$Y) | ((~$X)&$Z);
}
function G($X, $Y, $Z) {
return ($X&$Y) | ($X&$Z) | ($Y&$Z);
}
function H($X, $Y, $Z) {
return $X^$Y^$Z;
}
# Ported from SAMBA/source/lib/md4.c:mdfour
function mdfour($in) {
$in = unpack("C*",$in);
$in = array_values($in);
$b = sizeof($in) * 8;
$A = array(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
while (sizeof($in) > 64 ) {
$M = $this->copy64($in);
$this->mdfour64($A[0], $A[1], $A[2], $A[3], $M);
$new_in = array();
for ($i = 64; $i < sizeof($in); $i++) $new_in[] = $in[$i];
$in = $new_in;
}
$buf = $in;
$buf[] = 0x80;
for ($i = sizeof($buf) - 1; $i < 127; $i++) $buf[] = 0;
if ( sizeof($in) <= 55 ) {
$temp = $this->copy4($b);
$buf[56] = $temp[0];
$buf[57] = $temp[1];
$buf[58] = $temp[2];
$buf[59] = $temp[3];
$M = $this->copy64($buf);
$this->mdfour64($A[0], $A[1], $A[2], $A[3], $M);
}
else {
$temp = $this->copy4($b);
$buf[120] = $temp[0];
$buf[121] = $temp[1];
$buf[122] = $temp[2];
$buf[123] = $temp[3];
$M = $this->copy64($buf);
$this->mdfour64($A[0], $A[1], $A[2], $A[3], $M);
$temp = array();
for ($i = 64; $i < sizeof($buf); $i++) $temp[] = $buf[$i];
$M = $this->copy64($temp);
$this->mdfour64($A[0], $A[1], $A[2], $A[3], $M);
}
$out = array();
$temp = $this->copy4($A[0]);
for ($i = 0; $i < 4; $i++) $out[] = $temp[$i];
$temp = $this->copy4($A[1]);
for ($i = 0; $i < 4; $i++) $out[] = $temp[$i];
$temp = $this->copy4($A[2]);
for ($i = 0; $i < 4; $i++) $out[] = $temp[$i];
$temp = $this->copy4($A[3]);
for ($i = 0; $i < 4; $i++) $out[] = $temp[$i];
return $out;
}
# Ported from SAMBA/source/lib/md4.c:copy4
function copy4($x) {
$out = array();
$out[0] = $x&0xFF;
$out[1] = $this->unsigned_shift_r($x, 8)&0xFF;
$out[2] = $this->unsigned_shift_r($x, 16)&0xFF;
$out[3] = $this->unsigned_shift_r($x, 24)&0xFF;
return $out;
}
# Ported from SAMBA/source/lib/md4.c:copy64
function copy64($in) {
for ($i = 0; $i < 16; $i++) {
$M[$i] = ($in[$i*4+3]<<24) | ($in[$i*4+2]<<16) | ($in[$i*4+1]<<8) | ($in[$i*4+0]<<0);
}
return $M;
}
# Ported from SAMBA/source/lib/md4.c:mdfour64
function mdfour64(&$A, &$B, &$C, &$D, $M) {
$X = array();
for ($i = 0; $i < 16; $i++) $X[] = $M[$i];
$AA=$A;
$BB=$B;
$CC=$C;
$DD=$D;
$this->ROUND1($A,$B,$C,$D, 0, 3, $X);
$this->ROUND1($D,$A,$B,$C, 1, 7, $X);
$this->ROUND1($C,$D,$A,$B, 2, 11, $X);
$this->ROUND1($B,$C,$D,$A, 3, 19, $X);
$this->ROUND1($A,$B,$C,$D, 4, 3, $X); $this->ROUND1($D,$A,$B,$C, 5, 7, $X);
$this->ROUND1($C,$D,$A,$B, 6, 11, $X); $this->ROUND1($B,$C,$D,$A, 7, 19, $X);
$this->ROUND1($A,$B,$C,$D, 8, 3, $X); $this->ROUND1($D,$A,$B,$C, 9, 7, $X);
$this->ROUND1($C,$D,$A,$B, 10, 11, $X); $this->ROUND1($B,$C,$D,$A, 11, 19, $X);
$this->ROUND1($A,$B,$C,$D, 12, 3, $X); $this->ROUND1($D,$A,$B,$C, 13, 7, $X);
$this->ROUND1($C,$D,$A,$B, 14, 11, $X); $this->ROUND1($B,$C,$D,$A, 15, 19, $X);
$this->ROUND2($A,$B,$C,$D, 0, 3, $X); $this->ROUND2($D,$A,$B,$C, 4, 5, $X);
$this->ROUND2($C,$D,$A,$B, 8, 9, $X); $this->ROUND2($B,$C,$D,$A, 12, 13, $X);
$this->ROUND2($A,$B,$C,$D, 1, 3, $X); $this->ROUND2($D,$A,$B,$C, 5, 5, $X);
$this->ROUND2($C,$D,$A,$B, 9, 9, $X); $this->ROUND2($B,$C,$D,$A, 13, 13, $X);
$this->ROUND2($A,$B,$C,$D, 2, 3, $X); $this->ROUND2($D,$A,$B,$C, 6, 5, $X);
$this->ROUND2($C,$D,$A,$B, 10, 9, $X); $this->ROUND2($B,$C,$D,$A, 14, 13, $X);
$this->ROUND2($A,$B,$C,$D, 3, 3, $X); $this->ROUND2($D,$A,$B,$C, 7, 5, $X);
$this->ROUND2($C,$D,$A,$B, 11, 9, $X); $this->ROUND2($B,$C,$D,$A, 15, 13, $X);
$this->ROUND3($A,$B,$C,$D, 0, 3, $X); $this->ROUND3($D,$A,$B,$C, 8, 9, $X);
$this->ROUND3($C,$D,$A,$B, 4, 11, $X); $this->ROUND3($B,$C,$D,$A, 12, 15, $X);
$this->ROUND3($A,$B,$C,$D, 2, 3, $X); $this->ROUND3($D,$A,$B,$C, 10, 9, $X);
$this->ROUND3($C,$D,$A,$B, 6, 11, $X); $this->ROUND3($B,$C,$D,$A, 14, 15, $X);
$this->ROUND3($A,$B,$C,$D, 1, 3, $X); $this->ROUND3($D,$A,$B,$C, 9, 9, $X);
$this->ROUND3($C,$D,$A,$B, 5, 11, $X); $this->ROUND3($B,$C,$D,$A, 13, 15, $X);
$this->ROUND3($A,$B,$C,$D, 3, 3, $X); $this->ROUND3($D,$A,$B,$C, 11, 9, $X);
$this->ROUND3($C,$D,$A,$B, 7, 11, $X); $this->ROUND3($B,$C,$D,$A, 15, 15, $X);
$A = $this->add32(array($A, $AA)); $B = $this->add32(array($B, $BB));
$C = $this->add32(array($C, $CC)); $D = $this->add32(array($D, $DD));
}
# Needed? because perl seems to choke on overflowing when doing bitwise
# operations on numbers larger than 32 bits. Well, it did on my machine =)
function add32($v) {
for ($i = 0; $i < sizeof($v); $i++) {
$v[$i] = array($this->unsigned_shift_r(($v[$i]&0xffff0000), 16), ($v[$i]&0xffff));
}
for ($i = 0; $i < sizeof($v); $i++) {
$sum[0] += $v[$i][0];
$sum[1] += $v[$i][1];
}
$sum[0] += ($sum[1]&0xffff0000)>>16;
$sum[1] &= 0xffff;
$sum[0] &= 0xffff;
$ret = ($sum[0]<<16) | $sum[1];
return $ret;
}
# Ported from SAMBA/source/lib/md4.c:ROUND1
function ROUND1(&$a,$b,$c,$d,$k,$s,$X) {
$a = $this->md4lshift($this->add32(array($a, $this->F($b,$c,$d), $X[$k])), $s);
return $a;
}
# Ported from SAMBA/source/lib/md4.c:ROUND2
function ROUND2(&$a,$b,$c,$d,$k,$s,$X) {
$a = $this->md4lshift($this->add32(array($a, $this->G($b,$c,$d), $X[$k] + 0x5A827999)), $s);
return $a;
}
# Ported from SAMBA/source/lib/md4.c:ROUND3
function ROUND3(&$a,$b,$c,$d,$k,$s,$X) {
$a = $this->md4lshift($this->add32(array($a + $this->H($b,$c,$d) + $X[$k] + 0x6ED9EBA1)), $s);
return $a;
}
# Ported from SAMBA/source/lib/md4.c:lshift
# Renamed to prevent clash with SAMBA/source/libsmb/smbdes.c:lshift
function md4lshift($x, $s) {
$x &= 0xFFFFFFFF;
return ((($x<<$s)&0xFFFFFFFF) | $this->unsigned_shift_r($x, (32-$s)));
}
/**
* Unsigned shift operation for 32bit values.
*
* PHP 4 only supports signed shifts by default.
*/
function unsigned_shift_r($a, $b) {
$z = 0x80000000;
if ($z & $a) {
$a = ($a >> 1);
$a &= (~$z);
$a |= 0x40000000;
$a = ($a >> ($b - 1));
}
else {
$a = ($a >> $b);
}
return $a;
}
}
?>

View File

@ -1,14 +0,0 @@
<?php
/**
* Courier font for PDF pages.
*
* @package PDF
*/
for($i=0;$i<=255;$i++)
$fpdf_charwidths['courier'][chr($i)]=600;
$fpdf_charwidths['courierB']=$fpdf_charwidths['courier'];
$fpdf_charwidths['courierI']=$fpdf_charwidths['courier'];
$fpdf_charwidths['courierBI']=$fpdf_charwidths['courier'];
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* HelveticaA font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['helvetica']=array(
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* HelveticaB font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['helveticaB']=array(
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* HelveticaBI font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['helveticaBI']=array(
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* HelveticaAI font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['helveticaI']=array(
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* Symbol font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['symbol']=array(
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549,
','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722,
'B'=>667,'C'=>722,'D'=>612,'E'=>611,'F'=>763,'G'=>603,'H'=>722,'I'=>333,'J'=>631,'K'=>722,'L'=>686,'M'=>889,'N'=>722,'O'=>722,'P'=>768,'Q'=>741,'R'=>556,'S'=>592,'T'=>611,'U'=>690,'V'=>439,'W'=>768,
'X'=>645,'Y'=>795,'Z'=>611,'['=>333,'\\'=>863,']'=>333,'^'=>658,'_'=>500,'`'=>500,'a'=>631,'b'=>549,'c'=>549,'d'=>494,'e'=>439,'f'=>521,'g'=>411,'h'=>603,'i'=>329,'j'=>603,'k'=>549,'l'=>549,'m'=>576,
'n'=>521,'o'=>549,'p'=>549,'q'=>521,'r'=>549,'s'=>603,'t'=>439,'u'=>576,'v'=>713,'w'=>686,'x'=>493,'y'=>686,'z'=>494,'{'=>480,'|'=>200,'}'=>480,'~'=>549,chr(127)=>0,chr(128)=>0,chr(129)=>0,chr(130)=>0,chr(131)=>0,
chr(132)=>0,chr(133)=>0,chr(134)=>0,chr(135)=>0,chr(136)=>0,chr(137)=>0,chr(138)=>0,chr(139)=>0,chr(140)=>0,chr(141)=>0,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>750,chr(161)=>620,chr(162)=>247,chr(163)=>549,chr(164)=>167,chr(165)=>713,chr(166)=>500,chr(167)=>753,chr(168)=>753,chr(169)=>753,chr(170)=>753,chr(171)=>1042,chr(172)=>987,chr(173)=>603,chr(174)=>987,chr(175)=>603,
chr(176)=>400,chr(177)=>549,chr(178)=>411,chr(179)=>549,chr(180)=>549,chr(181)=>713,chr(182)=>494,chr(183)=>460,chr(184)=>549,chr(185)=>549,chr(186)=>549,chr(187)=>549,chr(188)=>1000,chr(189)=>603,chr(190)=>1000,chr(191)=>658,chr(192)=>823,chr(193)=>686,chr(194)=>795,chr(195)=>987,chr(196)=>768,chr(197)=>768,
chr(198)=>823,chr(199)=>768,chr(200)=>768,chr(201)=>713,chr(202)=>713,chr(203)=>713,chr(204)=>713,chr(205)=>713,chr(206)=>713,chr(207)=>713,chr(208)=>768,chr(209)=>713,chr(210)=>790,chr(211)=>790,chr(212)=>890,chr(213)=>823,chr(214)=>549,chr(215)=>250,chr(216)=>713,chr(217)=>603,chr(218)=>603,chr(219)=>1042,
chr(220)=>987,chr(221)=>603,chr(222)=>987,chr(223)=>603,chr(224)=>494,chr(225)=>329,chr(226)=>790,chr(227)=>790,chr(228)=>786,chr(229)=>713,chr(230)=>384,chr(231)=>384,chr(232)=>384,chr(233)=>384,chr(234)=>384,chr(235)=>384,chr(236)=>494,chr(237)=>494,chr(238)=>494,chr(239)=>494,chr(240)=>0,chr(241)=>329,
chr(242)=>274,chr(243)=>686,chr(244)=>686,chr(245)=>686,chr(246)=>384,chr(247)=>384,chr(248)=>384,chr(249)=>384,chr(250)=>384,chr(251)=>384,chr(252)=>494,chr(253)=>494,chr(254)=>494,chr(255)=>0);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* Times font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['times']=array(
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>408,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>180,'('=>333,')'=>333,'*'=>500,'+'=>564,
','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>564,'='=>564,'>'=>564,'?'=>444,'@'=>921,'A'=>722,
'B'=>667,'C'=>667,'D'=>722,'E'=>611,'F'=>556,'G'=>722,'H'=>722,'I'=>333,'J'=>389,'K'=>722,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>556,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>722,'W'=>944,
'X'=>722,'Y'=>722,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>469,'_'=>500,'`'=>333,'a'=>444,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>333,'s'=>389,'t'=>278,'u'=>500,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>480,'|'=>200,'}'=>480,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
chr(132)=>444,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>889,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>444,chr(148)=>444,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>980,
chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>200,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>564,chr(173)=>333,chr(174)=>760,chr(175)=>333,
chr(176)=>400,chr(177)=>564,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>453,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>444,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>564,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>722,chr(222)=>556,chr(223)=>500,chr(224)=>444,chr(225)=>444,chr(226)=>444,chr(227)=>444,chr(228)=>444,chr(229)=>444,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>564,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>500,chr(254)=>500,chr(255)=>500);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* TimesB font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['timesB']=array(
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>555,'#'=>500,'$'=>500,'%'=>1000,'&'=>833,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570,
','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>930,'A'=>722,
'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>778,'I'=>389,'J'=>500,'K'=>778,'L'=>667,'M'=>944,'N'=>722,'O'=>778,'P'=>611,'Q'=>778,'R'=>722,'S'=>556,'T'=>667,'U'=>722,'V'=>722,'W'=>1000,
'X'=>722,'Y'=>722,'Z'=>667,'['=>333,'\\'=>278,']'=>333,'^'=>581,'_'=>500,'`'=>333,'a'=>500,'b'=>556,'c'=>444,'d'=>556,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>333,'k'=>556,'l'=>278,'m'=>833,
'n'=>556,'o'=>500,'p'=>556,'q'=>556,'r'=>444,'s'=>389,'t'=>333,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>394,'|'=>220,'}'=>394,'~'=>520,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>667,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>300,chr(171)=>500,chr(172)=>570,chr(173)=>333,chr(174)=>747,chr(175)=>333,
chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>556,chr(182)=>540,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>330,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>570,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>722,chr(222)=>611,chr(223)=>556,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556,
chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* TimesBI font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['timesBI']=array(
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>389,'"'=>555,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570,
','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>832,'A'=>667,
'B'=>667,'C'=>667,'D'=>722,'E'=>667,'F'=>667,'G'=>722,'H'=>778,'I'=>389,'J'=>500,'K'=>667,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>611,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>667,'W'=>889,
'X'=>667,'Y'=>611,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>570,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
'n'=>556,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>556,'v'=>444,'w'=>667,'x'=>500,'y'=>444,'z'=>389,'{'=>348,'|'=>220,'}'=>348,'~'=>570,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>389,chr(159)=>611,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>266,chr(171)=>500,chr(172)=>606,chr(173)=>333,chr(174)=>747,chr(175)=>333,
chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>576,chr(182)=>500,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>300,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
chr(198)=>944,chr(199)=>667,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>570,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>611,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556,
chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>444,chr(254)=>500,chr(255)=>444);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* TimesI font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['timesI']=array(
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>420,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>214,'('=>333,')'=>333,'*'=>500,'+'=>675,
','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>675,'='=>675,'>'=>675,'?'=>500,'@'=>920,'A'=>611,
'B'=>611,'C'=>667,'D'=>722,'E'=>611,'F'=>611,'G'=>722,'H'=>722,'I'=>333,'J'=>444,'K'=>667,'L'=>556,'M'=>833,'N'=>667,'O'=>722,'P'=>611,'Q'=>722,'R'=>611,'S'=>500,'T'=>556,'U'=>722,'V'=>611,'W'=>833,
'X'=>611,'Y'=>556,'Z'=>556,'['=>389,'\\'=>278,']'=>389,'^'=>422,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>278,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>444,'l'=>278,'m'=>722,
'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>500,'v'=>444,'w'=>667,'x'=>444,'y'=>444,'z'=>389,'{'=>400,'|'=>275,'}'=>400,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
chr(132)=>556,chr(133)=>889,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>500,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>556,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>556,chr(148)=>556,chr(149)=>350,chr(150)=>500,chr(151)=>889,chr(152)=>333,chr(153)=>980,
chr(154)=>389,chr(155)=>333,chr(156)=>667,chr(157)=>350,chr(158)=>389,chr(159)=>556,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>275,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>675,chr(173)=>333,chr(174)=>760,chr(175)=>333,
chr(176)=>400,chr(177)=>675,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>523,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>611,chr(193)=>611,chr(194)=>611,chr(195)=>611,chr(196)=>611,chr(197)=>611,
chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>667,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>675,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
chr(220)=>722,chr(221)=>556,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>675,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>444,chr(254)=>500,chr(255)=>444);
?>

View File

@ -1,22 +0,0 @@
<?php
/**
* Zapfdingbats font for PDF pages.
*
* @package PDF
*/
$fpdf_charwidths['zapfdingbats']=array(
chr(0)=>0,chr(1)=>0,chr(2)=>0,chr(3)=>0,chr(4)=>0,chr(5)=>0,chr(6)=>0,chr(7)=>0,chr(8)=>0,chr(9)=>0,chr(10)=>0,chr(11)=>0,chr(12)=>0,chr(13)=>0,chr(14)=>0,chr(15)=>0,chr(16)=>0,chr(17)=>0,chr(18)=>0,chr(19)=>0,chr(20)=>0,chr(21)=>0,
chr(22)=>0,chr(23)=>0,chr(24)=>0,chr(25)=>0,chr(26)=>0,chr(27)=>0,chr(28)=>0,chr(29)=>0,chr(30)=>0,chr(31)=>0,' '=>278,'!'=>974,'"'=>961,'#'=>974,'$'=>980,'%'=>719,'&'=>789,'\''=>790,'('=>791,')'=>690,'*'=>960,'+'=>939,
','=>549,'-'=>855,'.'=>911,'/'=>933,'0'=>911,'1'=>945,'2'=>974,'3'=>755,'4'=>846,'5'=>762,'6'=>761,'7'=>571,'8'=>677,'9'=>763,':'=>760,';'=>759,'<'=>754,'='=>494,'>'=>552,'?'=>537,'@'=>577,'A'=>692,
'B'=>786,'C'=>788,'D'=>788,'E'=>790,'F'=>793,'G'=>794,'H'=>816,'I'=>823,'J'=>789,'K'=>841,'L'=>823,'M'=>833,'N'=>816,'O'=>831,'P'=>923,'Q'=>744,'R'=>723,'S'=>749,'T'=>790,'U'=>792,'V'=>695,'W'=>776,
'X'=>768,'Y'=>792,'Z'=>759,'['=>707,'\\'=>708,']'=>682,'^'=>701,'_'=>826,'`'=>815,'a'=>789,'b'=>789,'c'=>707,'d'=>687,'e'=>696,'f'=>689,'g'=>786,'h'=>787,'i'=>713,'j'=>791,'k'=>785,'l'=>791,'m'=>873,
'n'=>761,'o'=>762,'p'=>762,'q'=>759,'r'=>759,'s'=>892,'t'=>892,'u'=>788,'v'=>784,'w'=>438,'x'=>138,'y'=>277,'z'=>415,'{'=>392,'|'=>392,'}'=>668,'~'=>668,chr(127)=>0,chr(128)=>390,chr(129)=>390,chr(130)=>317,chr(131)=>317,
chr(132)=>276,chr(133)=>276,chr(134)=>509,chr(135)=>509,chr(136)=>410,chr(137)=>410,chr(138)=>234,chr(139)=>234,chr(140)=>334,chr(141)=>334,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>0,chr(161)=>732,chr(162)=>544,chr(163)=>544,chr(164)=>910,chr(165)=>667,chr(166)=>760,chr(167)=>760,chr(168)=>776,chr(169)=>595,chr(170)=>694,chr(171)=>626,chr(172)=>788,chr(173)=>788,chr(174)=>788,chr(175)=>788,
chr(176)=>788,chr(177)=>788,chr(178)=>788,chr(179)=>788,chr(180)=>788,chr(181)=>788,chr(182)=>788,chr(183)=>788,chr(184)=>788,chr(185)=>788,chr(186)=>788,chr(187)=>788,chr(188)=>788,chr(189)=>788,chr(190)=>788,chr(191)=>788,chr(192)=>788,chr(193)=>788,chr(194)=>788,chr(195)=>788,chr(196)=>788,chr(197)=>788,
chr(198)=>788,chr(199)=>788,chr(200)=>788,chr(201)=>788,chr(202)=>788,chr(203)=>788,chr(204)=>788,chr(205)=>788,chr(206)=>788,chr(207)=>788,chr(208)=>788,chr(209)=>788,chr(210)=>788,chr(211)=>788,chr(212)=>894,chr(213)=>838,chr(214)=>1016,chr(215)=>458,chr(216)=>748,chr(217)=>924,chr(218)=>748,chr(219)=>918,
chr(220)=>927,chr(221)=>928,chr(222)=>928,chr(223)=>834,chr(224)=>873,chr(225)=>828,chr(226)=>924,chr(227)=>924,chr(228)=>917,chr(229)=>930,chr(230)=>931,chr(231)=>463,chr(232)=>883,chr(233)=>836,chr(234)=>836,chr(235)=>867,chr(236)=>867,chr(237)=>696,chr(238)=>696,chr(239)=>874,chr(240)=>0,chr(241)=>874,
chr(242)=>760,chr(243)=>946,chr(244)=>771,chr(245)=>865,chr(246)=>771,chr(247)=>888,chr(248)=>967,chr(249)=>888,chr(250)=>831,chr(251)=>873,chr(252)=>927,chr(253)=>970,chr(254)=>918,chr(255)=>0);
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,130 +0,0 @@
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// functions for row checking and mouseOver effects
// mouseOver function
function user_over(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','userlist-over', 0);
}
// mouseOut function
function user_out(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','userlist', 0);
}
// onClick function
function user_click(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == true) {
cbox.checked = false;
list.setAttribute('class','userlist-over', 0);
}
else {
cbox.checked = true;
list.setAttribute('class','userlist-checked', 0);
}
}
// mouseOver function
function group_over(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','grouplist-over', 0);
}
// mouseOut function
function group_out(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','grouplist', 0);
}
// onClick function
function group_click(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == true) {
cbox.checked = false;
list.setAttribute('class','grouplist-over', 0);
}
else {
cbox.checked = true;
list.setAttribute('class','grouplist-checked', 0);
}
}
// mouseOver function
function host_over(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','hostlist-over', 0);
}
// mouseOut function
function host_out(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','hostlist', 0);
}
// onClick function
function host_click(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == true) {
cbox.checked = false;
list.setAttribute('class','hostlist-over', 0);
}
else {
cbox.checked = true;
list.setAttribute('class','hostlist-checked', 0);
}
}
// mouseOver function
function domain_over(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','domainlist-over', 0);
}
// mouseOut function
function domain_out(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == false) list.setAttribute('class','domainlist', 0);
}
// onClick function
function domain_click(list, box) {
cbox = document.getElementsByName(box)[0];
if (cbox.checked == true) {
cbox.checked = false;
list.setAttribute('class','domainlist-over', 0);
}
else {
cbox.checked = true;
list.setAttribute('class','domainlist-checked', 0);
}
}

View File

@ -1,58 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2003 Tilo Lutz
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
LDAP Account Manager displays table for creating or modifying accounts in LDAP
*/
// Get Lampath, needed 4 includes
$lampath_include = str_replace('account', '', str_replace('templates', '', realpath('.'))); // Save full path to lam in session
$lampath_include = ereg_replace ( '[/]+', '/', $lampath_include);
include_once($lampath_include.'lib/config.inc'); // File with configure-functions
include_once($lampath_include.'lib/profiles.inc'); // functions to load and save profiles
include_once($lampath_include.'lib/status.inc'); // Return error-message
include_once($lampath_include.'lib/pdf.inc'); // Return a pdf-file
include_once($lampath_include.'lib/ldap.inc'); // LDAP-functions
include_once($lampath_include.'lib/modules.inc'); // LDAP-functions
include_once($lampath_include.'lib/cache.inc');
include_once($lampath_include.'lib/account.inc');
// Start session
session_save_path($lampath_include.'sess');
@session_start();
// Redirect to startpage if user is not loged in
if (!isset($_SESSION['loggedIn'])) {
metaRefresh("../../login.php");
exit;
}
// Set correct language, codepages, ....
setlanguage();
if (!isset($_SESSION['cache'])) {
$_SESSION['cache'] = new cache();
}
$_SESSION['scope'] = array ('user', 'group', 'host', 'domain');
?>

View File

@ -1,91 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2004 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This file includes functions to control lamdaemon.
*
* @author Tilo Lutz
* @author Roland Gruber
*
* @package modules
*/
/**
* Sends commands to lamdaemon script.
*
* @param array $commands List of command lines
* @return array Output of lamdaemon
*
*/
function lamdaemon($commands) {
// get username and password of the current lam-admin
$ldap_q = $_SESSION['ldap']->decrypt_login();
/* $towrite has the following syntax:
* admin-username, admin-password, owner of homedir, 'home', operation='add'
* use escapeshellarg to make exec() shell-safe
*/
$towrite = escapeshellarg($_SESSION['config']->scriptServer)." ".escapeshellarg($_SESSION['config']->scriptPath)." ".
escapeshellarg($ldap_q[0]).' '.escapeshellarg($ldap_q[1]);
$userstring = implode ("\n", $commands);
if (function_exists(proc_open)) {
// New Code, requires PHP 4.3
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stout
2 => array("file", "/dev/null", "a") // sterr
);
$process = proc_open(escapeshellarg($_SESSION['lampath']."lib/lamdaemon.pl")." ".$towrite,
$descriptorspec,
$pipes);
if (is_resource($process)) {
/* perl-script is running
* $pipes[0] is writeable handle to child stdin
* $pipes[1] is readable handle to child stdout
* any error is send to /dev/null
*/
// Write to stdin
fwrite($pipes[0], $userstring);
}
fclose($pipes[0]);
while (!feof($pipes[1])) {
$output = fgets($pipes[1], 1024);
if ($output!='') $output_array[] = $output;
}
fclose($pipes[1]);
proc_close($process);
}
else { // PHP 4.3>
$command = escapeshellarg($_SESSION['lampath']."lib/lamdaemon.pl")." ".$towrite;
$pipe = popen("echo \"$userstring\"|$command" , 'r');
while(!feof($pipe)) {
//$output .= fread($pipe, 1024);
$output = fgets($pipe, 1024);
if ($output!='') $output_array[] = $output;
}
pclose($pipe);
}
return $output_array;
}
?>

View File

@ -1,228 +0,0 @@
#! /usr/bin/perl
# $Id$
#
# This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
# Copyright (C) 2003 Tilo Lutz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# LDAP Account Manager daemon to create and delete homedirecotries and quotas
#use strict; # Use strict for security reasons
@quota_grp;
@quota_usr; # Filesystems with enabled userquotas
# vals = DN, PAssword, user, home, (add|rem),
# quota, (set|get),(u|g), (mountpoint,blocksoft,blockhard,filesoft,filehard)+
# chown options
$|=1; # Disable buffering
sub get_fs { # Load mountpoints from mtab if enabled quotas
Quota::setmntent();
my $i=0;
my @args;
while (my @temp = Quota::getmntent()) {
$args[$i][0] = $temp[0];
$args[$i][1] = $temp[1];
$args[$i][2] = $temp[2];
$args[$i][3] = $temp[3];
$i++;
}
Quota::endmntent();
my $j=0; my $k=0; $i=0;
while ($args[$i][0]) {
if ( $args[$i][3] =~ m/usrquota/ ) {
$quota_usr[$j][0] = $args[$i][0];
$quota_usr[$j][1] = $args[$i][1];
$quota_usr[$j][2] = $args[$i][2];
$quota_usr[$j][3] = $args[$i][3];
$j++;
}
if ( $args[$i][3] =~ m/grpquota/ ) {
$quota_grp[$k][0] = $args[$i][0];
$quota_grp[$k][1] = $args[$i][1];
$quota_grp[$k][2] = $args[$i][2];
$quota_grp[$k][3] = $args[$i][3];
$k++;
}
$i++;
}
}
# ***************** Check values
if ($( == 0 ) { # we are root
# Drop root Previleges
($<, $>) = ($>, $<);
if ($ARGV[0] eq "*test") {
use Quota; # Needed to get and set quotas
print "Perl quota module successfully installed.\n";
print "If you haven't seen any errors lamdaemon.pl was set up successfully.\n";
}
else {
# loop for every transmitted user
my $string = do {local $/;<STDIN>};
@input = split ("\n", $string );
for ($i=0; $i<=$#input; $i++) {
$return = "";
@vals = split (' ', $input[$i]);
switch: {
# Get user information
if (($vals[3] eq 'user') || ($vals[1] eq 'home')) { @user = getpwnam($vals[0]); }
else { @user = getgrnam($vals[0]); }
$vals[1] eq 'home' && do {
switch2: {
$vals[2] eq 'add' && do {
# split homedir to set all directories below the last dir. to 755
my $path = $user[7];
$path =~ s,/(?:[^/]*)$,,;
($<, $>) = ($>, $<); # Get root privileges
if (! -e $path) {
system 'mkdir', '-m 755', '-p', $path; # Create paths to homedir
}
if (! -e $user[7]) {
system 'mkdir', '-m 755', $user[7]; # Create himdir itself
system "cp -a /etc/skel/* /etc/skel/.[^.]* $user[7]"; # Copy /etc/sekl into homedir
system 'chown', '-R', "$user[2]:$user[3]" , $user[7]; # Change owner to new user
if (-e '/usr/sbin/useradd.local') {
system '/usr/sbin/useradd.local', $user[0]; # run useradd-script
}
}
else {
$return = "ERROR,Lamdaemon,Homedirectory already exists.:$return";
}
($<, $>) = ($>, $<); # Give up root previleges
last switch2;
};
$vals[2] eq 'rem' && do {
($<, $>) = ($>, $<); # Get root previliges
if (-d $user[7]) {
# Fixme, only delete files owned by user.
system 'rm', '-R', $user[7]; # Delete Homedirectory
if (-e '/usr/sbin/userdel.local') {
system '/usr/sbin/userdel.local', $user[0];
}
}
else {
$return = "ERROR,Lamdaemon,Homedirectory doesn't exists.:$return";
}
($<, $>) = ($>, $<); # Give up root previleges
last switch2;
};
}
# Show error if undfined command is used
$return = "ERROR,Lamdaemon,Unknown command $vals[2].:$return";
last switch;
};
$vals[1] eq 'quota' && do {
use Quota; # Needed to get and set quotas
get_fs(); # Load list of devices with enabled quotas
# Store quota information in array
@quota_temp1 = split (':', $vals[4]);
$group=0;
$i=0;
while ($quota_temp1[$i]) {
$j=0;
@temp = split (',', $quota_temp1[$i]);
while ($temp[$j]) {
$quota[$i][$j] = $temp[$j];
$j++;
}
$i++;
}
if ($vals[3] eq 'user') { $group=false; }
else {
$group=1;
@quota_usr = @quota_grp;
}
switch2: {
$vals[2] eq 'rem' && do {
$i=0;
($<, $>) = ($>, $<); # Get root privileges
while ($quota_usr[$i][0]) {
$dev = Quota::getqcarg($quota_usr[$i][1]);
$return = Quota::setqlim($dev,$user[2],0,0,0,0,1,$group);
$i++;
}
($<, $>) = ($>, $<); # Give up root previleges
last switch2;
};
$vals[2] eq 'set' && do {
$i=0;
($<, $>) = ($>, $<); # Get root privileges
while ($quota_usr[$i][0]) {
$dev = Quota::getqcarg($quota[$i][0]);
$return = Quota::setqlim($dev,$user[2],$quota[$i][1],$quota[$i][2],$quota[$i][3],$quota[$i][4],1,$group);
$i++;
}
($<, $>) = ($>, $<); # Give up root previleges
last switch2;
};
$vals[2] eq 'get' && do {
$i=0;
($<, $>) = ($>, $<); # Get root privileges
while ($quota_usr[$i][0]) {
if ($vals[0]ne'+') {
$dev = Quota::getqcarg($quota_usr[$i][1]);
@temp = Quota::query($dev,$user[2],$group);
if ($temp[0]ne'') {
$return = "$quota_usr[$i][1],$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6],$temp[7]:$return";
}
else { $return = "$quota_usr[$i][1],0,0,0,0,0,0,0,0:$return"; }
}
else { $return = "$quota_usr[$i][1],0,0,0,0,0,0,0,0:$return"; }
$i++;
}
($<, $>) = ($>, $<); # Give up root previleges
last switch2;
};
$return = "ERROR,Lamdaemon,Unknown command $vals[2].:$return";
}
};
last switch;
$return = "ERROR,Lamdaemon,Unknown command $vals[1].:$return";
};
print "$return\n";
}
}
}
else {
$hostname = shift @ARGV;
$remotepath = shift @ARGV;
use Net::SSH::Perl;
if ($ARGV[2] eq "*test") { print "Net::SSH::Perl successfully installed.\n"; }
@username = split (',', $ARGV[0]);
$username[0] =~ s/uid=//;
$password = $ARGV[1];
# Put all transfered lines in one string
if ($ARGV[2] ne "*test") {
$string = do {local $/;<STDIN>};
}
else { $argv = "*test\n"; }
my $ssh = Net::SSH::Perl->new($hostname, options=>[
"UserKnownHostsFile /dev/null"],
protocol => "2,1" );
$ssh->login($username[0], $password);
# Change needed to prevent buffer overrun
@string2 = split ("\n", $string);
for ($i=0; $i<=$#string2; $i++) {
($stdout2, $stderr, $exit) = $ssh->cmd("sudo $remotepath $argv", $string2[$i]);
$stdout .= $stdout2;
}
#($stdout, $stderr, $exit) = $ssh->cmd("sudo $remotepath $argv", $string);
print $stdout;
}

Some files were not shown because too many files have changed in this diff Show More