mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
This commit was generated by cvs2svn to compensate for changes in r4,
which included commits to RCS files with non-trunk default branches.
(This used to be commit c8a46aca03
)
This commit is contained in:
commit
0db2ec0e94
339
COPYING
Normal file
339
COPYING
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, 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
|
||||
|
||||
Appendix: 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.
|
111
README
Normal file
111
README
Normal file
@ -0,0 +1,111 @@
|
||||
This is version 1.9 of Samba, the free SMB client and server for unix.
|
||||
|
||||
>>>> Please read THE WHOLE of this file as it gives important information
|
||||
>>>> about the configuration and use of Samba.
|
||||
|
||||
This software is freely distributable under the GNU public license, a
|
||||
copy of which you should have received with this software (in a file
|
||||
called COPYING).
|
||||
|
||||
WHAT CAN SAMBA DO?
|
||||
==================
|
||||
|
||||
Here is a very short list of what samba includes, and what it does
|
||||
|
||||
- a SMB server, to provide LanManager style file and print services to PCs
|
||||
|
||||
- a Netbios (rfc1001/1002) nameserver
|
||||
|
||||
- a ftp-like SMB client so you can access PC resources (disks and
|
||||
printers) from unix
|
||||
|
||||
- a tar extension to the client for backing up PCs
|
||||
|
||||
Related packages include:
|
||||
|
||||
- ksmbfs, a linux-only filesystem allowing you to mount remote SMB
|
||||
filesystems from PCs on your linux box
|
||||
|
||||
- tcpdump-smb, a extension to tcpdump to allow you to investigate SMB
|
||||
networking problems over netbeui and tcp/ip
|
||||
|
||||
|
||||
CONTRIBUTIONS
|
||||
=============
|
||||
|
||||
If you want to contribute to the development of the software then
|
||||
please join the mailing list. I accept patches (preferably in
|
||||
"diff -u" format) and am always glad to receive feedback or suggestions.
|
||||
|
||||
You could also send hardware/software/money/jewelry or pizza
|
||||
vouchers directly to me. The pizza vouchers would be especially
|
||||
welcome :-)
|
||||
|
||||
If you like a particular feature then look through the change-log and
|
||||
see who added it, then send them an email.
|
||||
|
||||
Remember that free software of this kind lives or dies by the response
|
||||
we get. If noone tells us they like it then we'll probably move onto
|
||||
something else.
|
||||
|
||||
Andrew Tridgell
|
||||
Email: samba-bugs@anu.edu.au
|
||||
|
||||
3 Ballow Crescent
|
||||
Macgregor, A.C.T.
|
||||
2615 Australia
|
||||
|
||||
|
||||
MORE INFO
|
||||
=========
|
||||
|
||||
DOCUMENTATION
|
||||
-------------
|
||||
|
||||
There is quite a bit of documentation included with the package,
|
||||
including man pages, and lots of .txt files with hints and useful
|
||||
info.
|
||||
|
||||
FTP SITE
|
||||
--------
|
||||
|
||||
The main anonymous ftp distribution site for this software is
|
||||
nimbus.anu.edu.au in the directory pub/tridge/samba/.
|
||||
|
||||
MAILING LIST
|
||||
------------
|
||||
|
||||
There is a mailing list for discussion of Samba. To subscribe send
|
||||
mail to listproc@anu.edu.au with a body of "subscribe samba Your Name"
|
||||
|
||||
To send mail to everyone on the list mail to samba@listproc.anu.edu.au
|
||||
|
||||
There is also an announcement mailing list where I announce new
|
||||
versions. To subscribe send mail to listproc@anu.edu.au with a body
|
||||
of "subscribe samba-announce Your Name". All announcements also go to
|
||||
the samba list.
|
||||
|
||||
|
||||
NEWS GROUP
|
||||
----------
|
||||
|
||||
You might also like to look at the usenet news group
|
||||
comp.protocols.smb as it often contains lots of useful info and is
|
||||
frequented by lots of Samba users. The newsgroup was initially setup
|
||||
by people on the Samba mailing list. It is not, however, exclusive to
|
||||
Samba, it is a forum for discussing the SMB protocol (which Samba
|
||||
implements).
|
||||
|
||||
|
||||
WEB SITE
|
||||
--------
|
||||
|
||||
A Samba WWW site has been setup with lots of useful info. Connect to:
|
||||
|
||||
http://lake.canberra.edu.au/pub/samba/
|
||||
|
||||
It is maintained by Paul Blackman (thanks Paul!). You can contact him
|
||||
at ictinus@lake.canberra.edu.au.
|
||||
|
||||
|
||||
|
119
docs/THANKS
Normal file
119
docs/THANKS
Normal file
@ -0,0 +1,119 @@
|
||||
=====================================================================
|
||||
This file is for thanks to individuals or organisations who have
|
||||
helped with the development of Samba, other than by coding or bug
|
||||
reports. Their contributions are gratefully acknowledged.
|
||||
|
||||
Please refer to the manual pages and change-log for a list of those
|
||||
who have contributed in the form of patches, bug fixes or other
|
||||
direct changes to the package.
|
||||
|
||||
Contributions of any kind are welcomed. If you want to help then
|
||||
please contact Andrew.Tridgell@anu.edu.au, or via normal mail at
|
||||
|
||||
Andrew Tridgell
|
||||
3 Ballow Crescent
|
||||
Macgregor, A.C.T
|
||||
2615 Australia
|
||||
=====================================================================
|
||||
|
||||
|
||||
Lee Fisher (leefi@microsoft.com)
|
||||
Charles Fox (cfox@microsoft.com)
|
||||
Dan Perry (danp@exchnge.microsoft.com)
|
||||
|
||||
These Microsoft people have been very helpful and supportive of
|
||||
the development of Samba.
|
||||
|
||||
Lee very kindly supplied me with a copy of the X/Open SMB
|
||||
specs. These have been invaluable in getting the details of the
|
||||
implementation right. They will become even more important as we move
|
||||
towards a Lanman 2.1 compliant server. Lee has provided very
|
||||
useful advice on several aspects of the server.
|
||||
Lee has also provided me with copies of Windows NTAS 3.1, Visual C
|
||||
and a developers CD-ROM. Being able to run NT at home is a
|
||||
great help.
|
||||
|
||||
Charles has helped out in numerous ways with the provision of SMB
|
||||
specifications and helpful advice. He has been following the
|
||||
discussion of Samba on the mailing list and has stepped in
|
||||
regularly to clarify points and to offer help.
|
||||
|
||||
Dan has put me in touch with NT developers to help sort out bugs and
|
||||
compatability issues. He has also supplied me with a copy of the
|
||||
NT browsing spec, which will help a lot in the development of the
|
||||
Samba browser code.
|
||||
|
||||
|
||||
Bruce Perens (bruce@pixar.com)
|
||||
|
||||
In appreciation of his effort on Samba we have sent Andrew copies of
|
||||
various Pixar computer-graphics software products. Pixar is best known
|
||||
for its "Renderman" product, the 3-D renderer used by ILM to make special
|
||||
effects for "Terminator II" and "Jurassic Park". We won the first Oscar
|
||||
given to a computer graphic animated feature for our short film "Tin Toy".
|
||||
Our retail products "Typestry" and "Showplace", incorporate the same
|
||||
renderer used on the films, and are available on Windows and the
|
||||
Macintosh.
|
||||
|
||||
|
||||
|
||||
Henry Lee (hyl@microplex.co)
|
||||
|
||||
Henry sent me a M202 ethernet print server, making my little lan
|
||||
one of the few home networks to have it's own print server!
|
||||
|
||||
``Microplex Systems Ltd. is a manufacturer of local and wide area
|
||||
network communications equipment based in beautiful Vancouver, British
|
||||
Columbia, Canada. Microplex's first products were synchronous wide
|
||||
area network devices used in the mainframe communication networks. In
|
||||
August 1991 Microplex introduced its first LAN product, the M200 print
|
||||
server, the first high performance print server under US$1,000.''
|
||||
|
||||
|
||||
Tom Haapanen (tomh@metrics.com)
|
||||
|
||||
Tom sent me two 16 bit SMC ethernet cards to replace my ancient 8
|
||||
bit ones. The performance is much better!
|
||||
|
||||
Software Metrics Inc. is a small custom software development and
|
||||
consulting firm located in Waterloo, Ontario, Canada. We work
|
||||
with a variety of environments (such as Windows, Windows NT and
|
||||
Unix), tools and application areas, and can provide assistance for
|
||||
development work ranging from a few days to to multiple man-year
|
||||
projects. You can find more information at http://www.metrics.com/.
|
||||
|
||||
|
||||
Steve Kennedy (steve@gbnet.net)
|
||||
|
||||
Steve sent me 16Mb of ram so that I could install/test
|
||||
NT3.5. I previous had only 8Mb ram in my test machine, which
|
||||
wasn't enough to install a properly functioning copy of
|
||||
NTAS. Being able to directly test NT3.5 allowed me to solve
|
||||
several long standing NT<->Samba problems. Thanks Steve!
|
||||
|
||||
John Terpstra (jht@aquasoft.com.au)
|
||||
|
||||
Aquasoft are a speciaist consulting company whose Samba using
|
||||
customers span the world.
|
||||
|
||||
Aquasoft have been avid supporters of the Samba project. As a
|
||||
token of appreciation Aquasoft have donated a 486DX2/66 PC with
|
||||
a 540MB EIDE drive and 20MB RAM.
|
||||
|
||||
John has helped to isolate quite a few little glitches over time
|
||||
and has managed to implement some very interesting installations
|
||||
of Samba.
|
||||
|
||||
The donation of the new PC will make it possible to more fully
|
||||
diagnose and observe the behaviour of Samba in conjuction with
|
||||
other SMB protocol utilising systems.
|
||||
|
||||
|
||||
Timothy F. Sipples (tsipple@vnet.IBM.COM)
|
||||
Steve Withers (swithers@vnet.IBM.COM)
|
||||
|
||||
Tim and Steve from IBM organised a copy of the OS/2 developers
|
||||
connection CD set for me, and gave lots of help in getting
|
||||
OS/2 Warp installed. I hope this will allow me to finally fix
|
||||
up those annoying OS/2 related Samba bugs that I have been
|
||||
receiving reports of.
|
129
docs/announce
Normal file
129
docs/announce
Normal file
@ -0,0 +1,129 @@
|
||||
Announcing Samba version 1.9
|
||||
============================
|
||||
|
||||
What is Samba?
|
||||
--------------
|
||||
|
||||
Samba is a Unix based SMB file server. This allows a Unix host to
|
||||
act as a file and print server for SMB clients. This includes
|
||||
Lan-Manager compatible clients such as LanManager for DOS, Windows for
|
||||
Workgroups, Windows NT, Windows 95, OS/2, Pathworks and many more.
|
||||
|
||||
The package also includes a Unix SMB client and a netbios nameserver.
|
||||
|
||||
What can it do for me?
|
||||
----------------------
|
||||
|
||||
If you have any PCs running SMB clients, such as a PC running Windows
|
||||
for Workgroups, then you can mount file space or printers from a unix
|
||||
host, so that directories, files and printers on the unix host are
|
||||
available on the PC.
|
||||
|
||||
The client part of the package will also allow you to attach to other
|
||||
SMB-based servers (such as windows NT and windows for workgroups) so
|
||||
that you can copy files to and from your unix host. The client also
|
||||
allows you to access a SMB printer (such as one attached to an OS/2 or
|
||||
WfWg server) from Unix, using an entry in /etc/printcap, or by
|
||||
explicitly specifying the command used to print files.
|
||||
|
||||
What are it's features?
|
||||
------------------------
|
||||
|
||||
Samba supports many features that are not supported in other SMB
|
||||
implementations (all of which are commercial). Some of it's features
|
||||
include host as well as username/password security, a unix client,
|
||||
automatic home directory exporting, automatic printer exporting, dead
|
||||
connection timeouts, umask support, guest connections, name mangling
|
||||
and hidden and system attribute mapping. Look at the man pages
|
||||
included with the package for a full list of features.
|
||||
|
||||
What's new since 1.8?
|
||||
---------------------
|
||||
|
||||
Lots of stuff. See the change log and man pages for details.
|
||||
|
||||
Where can I get a client for my PC?
|
||||
-----------------------------------
|
||||
|
||||
There is a free client for MS-DOS based PCs available from
|
||||
ftp.microsoft.com in the directory bussys/Clients/MSCLIENT/. Please
|
||||
read the licencing information before downloading. The built in
|
||||
Windows for Workgroups client is also very good.
|
||||
|
||||
What network protocols are supported?
|
||||
-------------------------------------
|
||||
|
||||
Currently only TCP/IP is supported. There has been some discussion
|
||||
about ports to other protocols but nothing is yet available.
|
||||
|
||||
There is a free TCP/IP implementation for Windows for Workgroups
|
||||
available from ftp.microsoft.com (it's small, fast and quite reliable).
|
||||
|
||||
How much does it cost?
|
||||
----------------------
|
||||
|
||||
Samba software is free software. It is available under the
|
||||
GNU Public licence in source code form at no cost. Please read the
|
||||
file COPYING that comes with the package for more information.
|
||||
|
||||
What flavours of unix does it support?
|
||||
---------------------------------------
|
||||
|
||||
The code has been written to be as portable as possible. It has been
|
||||
"ported" to many unixes, which mostly required changing only a few
|
||||
lines of code. It has been run (to my knowledge) on at least these
|
||||
unixes:
|
||||
|
||||
Linux, SunOS, Solaris, SVR4, Ultrix, OSF1, AIX, BSDI, NetBSD,
|
||||
Sequent, HP-UX, SGI, FreeBSD, NeXT, ISC, A/UX, SCO, Intergraph,
|
||||
Domain/OS and DGUX.
|
||||
|
||||
Some of these have received more testing than others. If it doesn't
|
||||
work with your unix then it should be easy to fix.
|
||||
|
||||
Who wrote it?
|
||||
-------------
|
||||
|
||||
Many people on the internet have contributed to the development of
|
||||
Samba. The maintainer and original author is Andrew Tridgell, but
|
||||
large parts of the package were contributed by several people from all
|
||||
over the world. Please look at the file `change-log' for information
|
||||
on who did what bits.
|
||||
|
||||
Where can I get it?
|
||||
-------------------
|
||||
|
||||
The package is available via anonymous ftp from nimbus.anu.edu.au in
|
||||
the directory pub/tridge/samba/.
|
||||
|
||||
What about SMBServer?
|
||||
---------------------
|
||||
|
||||
Samba used to be known as SMBServer, until it was pointed out that
|
||||
Syntax, who make a commercial Unix SMB based server, have trademarked
|
||||
that name. The name was then changed to Samba. Also, in 1992 a very
|
||||
early incarnation of Samba was distributed as nbserver.
|
||||
|
||||
If you see any copies of nbserver or smbserver on ftp sites please let
|
||||
me or the ftp archive maintainer know, as I want to get them deleted.
|
||||
|
||||
Where can I get more info?
|
||||
---------------------------
|
||||
|
||||
Please join the mailing list if you want to discuss the development or
|
||||
use of Samba. To join the mailing list send mail to
|
||||
listproc@listproc.anu.edu.au with a body of "subscribe samba Your
|
||||
Name".
|
||||
|
||||
There is also an announcement mailing list for new version
|
||||
announcements. Subscribe as above but with "subscribe samba-announce
|
||||
Your Name".
|
||||
|
||||
There is also often quite a bit of discussion about Samba on the
|
||||
newsgroup comp.protocols.smb.
|
||||
|
||||
A WWW site with lots of Samba info can be found at
|
||||
http://lake.canberra.edu.au/pub/samba/
|
||||
|
||||
Andrew Tridgell (Contact: samba-bugs@anu.edu.au)
|
||||
January 1995
|
165
docs/history
Normal file
165
docs/history
Normal file
@ -0,0 +1,165 @@
|
||||
Note: This file is now quite out of date - but perhaps that's
|
||||
appropriate?
|
||||
|
||||
|
||||
=========
|
||||
|
||||
This is a short history of this project. It's not supposed to be
|
||||
comprehensive, just enough so that new users can get a feel for where
|
||||
this project has come from and maybe where it's going to.
|
||||
|
||||
The whole thing really started in December 1991. I was (and still am)
|
||||
a PhD student in the Computer Sciences Laboratory at the Australian
|
||||
Netional University, in Canberra, Australia. We had just got a
|
||||
beta copy of eXcursion from Digital, and I was testing it on my PC. At
|
||||
this stage I was a MS-DOS user, dabbling in windows.
|
||||
|
||||
eXcursion ran (at the time) only with Dec's `Pathworks' network for
|
||||
DOS. I had up till then been using PC-NFS to connect to our local sun
|
||||
workstations, and was reasonably happy with it. In order to run
|
||||
pathworks I had to stop using PC-NFS and try using pathworks to mount
|
||||
disk space. Unfortunately pathworks was only available for digital
|
||||
workstations running VMS or Ultrix so I couldn't mount from the suns
|
||||
anymore.
|
||||
|
||||
I had access to a a decstation 3100 running Ultrix that I used to
|
||||
administer, and I got the crazy notion that the protocol that
|
||||
pathworks used to talk to ultrix couldn't be that hard, and maybe I
|
||||
could work it out. I had never written a network program before, and
|
||||
certainly didn't know what a socket was.
|
||||
|
||||
In a few days, after looking at some example code for sockets, I
|
||||
discovered it was pretty easy to write a program to "spy" on the file
|
||||
sharing protocol. I wrote and installed this program (the sockspy.c
|
||||
program supplied with this package) and captured everything that the
|
||||
pathworks client said to the pathworks server.
|
||||
|
||||
I then tried writing short C programs (using Turbo C under DOS) to do
|
||||
simple file operations on the network drive (open, read, cd etc) and
|
||||
looked at the packets that the server and client exchanged. From this
|
||||
I worked out what some of the bytes in the packets meant, and started
|
||||
to write my own program to do the same thing on a sun.
|
||||
|
||||
After a day or so more I had my first successes and actually managed
|
||||
to get a connection and to read a file. From there it was all
|
||||
downhill, and a week later I was happily (if a little unreliably)
|
||||
mounting disk space from a sun to my PC running pathworks. The server
|
||||
code had a lot of `magic' values in it, which seemed to be always
|
||||
present with the ultrix server. It was not till 2 years later that I
|
||||
found out what all these values meant.
|
||||
|
||||
Anyway, I thought other people might be interested in what I had done,
|
||||
so I asked a few people at uni, and noone seemed much interested. I
|
||||
also spoke to a person at Digital in Canberra (the person who had
|
||||
organised a beta test of eXcursion) and asked if I could distribute
|
||||
what I'd done, or was it illegal. It was then that I first heard the
|
||||
word "netbios" when he told me that he thought it was all covered by a
|
||||
spec of some sort (the netbios spec) and thus what I'd done was not
|
||||
only legal, but silly.
|
||||
|
||||
I found the netbios spec after asking around a bit (the RFC1001 and
|
||||
RFC1002 specs) and found they looked nothing like what I'd written, so
|
||||
I thought maybe the Digital person was mistaken. I didn't realise RFCs
|
||||
referred to the name negotiation and packet encapsulation over TCP/IP,
|
||||
and what I'd written was really a SMB implementation.
|
||||
|
||||
Anyway, he encouraged me to release it so I put out "Server 0.1" in
|
||||
January 1992. I got quite a good response from people wanting to use
|
||||
pathworks with non-digital unix workstations, and I soon fixed a few
|
||||
bugs, and released "Server 0.5" closely followed by "Server 1.0". All
|
||||
three releases came out within about a month of each other.
|
||||
|
||||
At this point I got an X Terminal on my desk, and I no longer needed eXcursion
|
||||
and I prompty forgot about the whole project, apart from a few people
|
||||
who e-mailed me occasionally about it.
|
||||
|
||||
Nearly two years then passed with just occasional e-mails asking about
|
||||
new versions and bugs. I even added a note to the ftp site asking for
|
||||
a volunteer to take over the code as I no longer used it. No one
|
||||
volunteered.
|
||||
|
||||
During this time I did hear from a couple of people who said it should
|
||||
be possible to use my code with Lanmanager, but I never got any
|
||||
definite confirmation.
|
||||
|
||||
One e-mail I got about the code did, however, make an impression. It
|
||||
was from Dan Shearer at the university of South Australia, and he said
|
||||
this:
|
||||
|
||||
|
||||
I heard a hint about a free Pathworks server for Unix in the
|
||||
Net channel of the Linux list. After quite a bit of chasing
|
||||
(and lots of interested followups from other Linux people) I
|
||||
got hold of a release news article from you, posted in Jan 92,
|
||||
from someone in the UK.
|
||||
|
||||
Can you tell me what the latest status is? I think you might
|
||||
suddenly find a whole lot of interested hackers in the Linux
|
||||
world at least, which is a place where things tend to happen
|
||||
fast (and even some reliable code gets written, BION!)
|
||||
|
||||
I asked him what Linux was, and he told me it was a free Unix for PCs.
|
||||
This was in November 1992 and a few months later I was a Linux
|
||||
convert! I still didn't need a pathworks server though, so I didn't do
|
||||
the port, but I think Dan did.
|
||||
|
||||
At about this time I got an e-mail from Digital, from a person working
|
||||
on the Alpha software distribution. He asked if I would mind if they
|
||||
included my server with the "contributed" cd-rom. This was a bit of a
|
||||
shock to me as I never expected Dec to ask me if they could use my
|
||||
code! I wrote back saying it was OK, but never heard from him again. I
|
||||
don't know if it went on the cd-rom.
|
||||
|
||||
Anyway, the next big event was in December 1993, when Dan again sent
|
||||
me an e-mail saying my server had "raised it's ugly head" on
|
||||
comp.protocols.tcpip.ibmpc. I had a quick look on the group, and was
|
||||
surprised to see that there were people interested in this thing.
|
||||
|
||||
At this time a person from our computer center offered me a couple of
|
||||
cheap ethernet cards (3c505s for $15 each) and coincidentially someone
|
||||
announced on one of the Linux channels that he had written a 3c505
|
||||
driver for Linux. I bought the cards, hacked the driver a little and
|
||||
setup a home network between my wifes PC and my Linux box. I then
|
||||
needed some way to connect the two, and I didn't own PC-NFS at home,
|
||||
so I thought maybe my server could be useful. On the newsgroup among
|
||||
the discussions of my server someone had mentioned that there was a
|
||||
free client that might work with my server that Microsoft had put up
|
||||
for ftp. I downloaded it and found to my surprise that it worked first
|
||||
time with my `pathworks' server!
|
||||
|
||||
Well, I then did a bit of hacking, asked around a bit and found (I
|
||||
think from Dan) that the spec I needed was for the "SMB" protocol, and
|
||||
that it was available via ftp. I grabbed it and started removing all
|
||||
those ugly constants from the code, now that all was explained.
|
||||
|
||||
On December 1st 1993 I announced the start of the "Netbios for Unix"
|
||||
project, seeding the mailing list with all the people who had e-mailed
|
||||
me over the years asking about the server.
|
||||
|
||||
About 35 versions (and two months) later I wrote a short history of
|
||||
the project, which you have just read. There are now over a hundred
|
||||
people on the mailing list, and lots of people report that they use
|
||||
the code and like it. In a few days I will be announcing the release
|
||||
of version 1.6 to some of the more popular (and relevant) newsgroups.
|
||||
|
||||
|
||||
Andrew Tridgell
|
||||
6th February 1994
|
||||
|
||||
---------------------
|
||||
|
||||
It is now May 1995 and there are about 1400 people on the mailing
|
||||
list. I got downloads from the main Samba ftp site from around 5000
|
||||
unique hosts in a two month period. There are several mirror
|
||||
sites as well. The current version number is 1.9.13.
|
||||
|
||||
---------------------
|
||||
|
||||
|
||||
---------------------
|
||||
It's now March 1996 and version 1.9.16alpha1 has just been
|
||||
released. There have been lots of changes recently with master browser
|
||||
support and the ability to do domain logons etc. Samba has also been
|
||||
ported to OS/2, the amiga and NetWare. There are now 3000 people on
|
||||
the samba mailing list.
|
||||
---------------------
|
175
docs/htmldocs/wfw_slip.htm
Normal file
175
docs/htmldocs/wfw_slip.htm
Normal file
@ -0,0 +1,175 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Peter Karrer Announces SLIP for WFW</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1><I>Winserve</I></H1>
|
||||
<HR>
|
||||
<H2><I>Peter Karrer Announces SLIP for WFW</I></H2>
|
||||
[NEW 03-22-95)
|
||||
<HR>
|
||||
<B>Hello,</B>
|
||||
<P>
|
||||
I've discovered a way to run WfW's TCP/IP-32 over a SLIP packet driver. This
|
||||
allows WfW users to do Windows networking over dialup lines just like it is
|
||||
possible with NT and the Windows 95 beta!
|
||||
<P>
|
||||
For instance, you can mount Microsoft's FTP server as a network drive in File
|
||||
Manager or connect to an MS Mail post office over the Internet. Of course,
|
||||
the usual Internet stuff works as well. Another interesting site is
|
||||
WINSERVE.001; check out www.winserve.com.
|
||||
<HR>
|
||||
This method should work with any class 1 (Ethernet II) packet driver. However,
|
||||
I'm not in a position to try anything else than SLIPPER/CSLIPPER.
|
||||
<HR>
|
||||
<H3>Files you need:</H3>
|
||||
<B>WFWT32.EXE:</B> ftp://ftp.microsoft.com/bussys/msclient/wfw/wfwt32.exe
|
||||
<P>
|
||||
Microsoft's free TCP/IP for WfW. It's a self-extracting archive which
|
||||
should be executed in an empty directory.
|
||||
<P>
|
||||
<B>SLIPPER.EXE:</B> ftp://biocserver.bioc.cwru.edu/pub/dos/slipper/slippr15.zip
|
||||
<P>
|
||||
Peter Tattam's SLIP packet driver. CSLIPPER.EXE is a variant which supports
|
||||
VJ header compression.
|
||||
<P>
|
||||
<B>PDETHER.EXE:</B> ftp://sjf-lwp.idz.sjf.novell.com/odi/pdether/pde105.zip
|
||||
<P>
|
||||
Don Provan's ODI-over-Packet Driver shim. This *must* be version 1.05 (or
|
||||
above).
|
||||
<P>
|
||||
<B>LSL.COM:</B>
|
||||
<P>
|
||||
Novell's LAN Support Layer. If you're an owner of Windows 3.10, you'll
|
||||
have it on one of your install disks. Use "expand a:lsl.co_ lsl.com" to
|
||||
expand it. Microsoft has stopped bundling LSL.COM with WfW 3.11, though.
|
||||
The newest version of LSL.COM can be downloaded as part of
|
||||
ftp://ftp.novell.com/pub/netware/nwos/dosclnt12/vlms/vlmup2.exe.
|
||||
However, it's not clear if this one may be legally used outside Netware
|
||||
environments.
|
||||
<P>
|
||||
<B>NET.CFG:</B>
|
||||
<P>
|
||||
A configuration file for LSL and PDETHER. It should contain the following
|
||||
text:
|
||||
<P>
|
||||
<PRE>
|
||||
Link Support
|
||||
Buffers 8 1600
|
||||
Link Driver PDETHER
|
||||
Int 60
|
||||
Frame Ethernet_II
|
||||
Protocol IP 800 Ethernet_II
|
||||
Protocol ARP 806 Ethernet_II
|
||||
Protocol RARP 8035 Ethernet_II
|
||||
</PRE>
|
||||
<P>
|
||||
<B>DISCOMX.COM:</B>
|
||||
<P>
|
||||
A little hack of mine to disable the COM port used by the SLIP packet driver.
|
||||
Usage is e.g. "discomx 2" to disable COM2. This should be run before
|
||||
starting WfW, otherwise you'll get "device conflict" messages. Here it is:
|
||||
<P><PRE>
|
||||
begin 644 discomx.com
|
||||
F,=N)V8H.@`"P(+^!`/.N3XH="=MT!DN`XP/1XS')!R:)CP`$S2``
|
||||
`
|
||||
end
|
||||
</PRE>
|
||||
(Save this text to disk as <I>filename</I>, then run "uudecode <I>filename</I>".
|
||||
uudecode can be found, for instance, at
|
||||
ftp://ftp.switch.ch/mirror/simtel/msdos/starter/uudecode.com )
|
||||
<P>
|
||||
<B>LMHOSTS:</B>
|
||||
<P>
|
||||
An optional file which should be stored in your Windows subdirectory. It is
|
||||
used to map NetBIOS computer names to IP addresses. Example:
|
||||
<P>
|
||||
<PRE>
|
||||
198.105.232.1 ftp #PRE # ftp.microsoft.com
|
||||
204.118.34.11 winserve.001 #PRE # Winserve
|
||||
</PRE>
|
||||
<HR>
|
||||
<H3>How to install it:</H3>
|
||||
<P>
|
||||
<UL>
|
||||
<LI>Put the files mentioned above into a directory, e.g. C:\SLIP.
|
||||
<P>
|
||||
<LI>Put the following lines into AUTOEXEC.BAT:
|
||||
<P><PRE>
|
||||
cd \slip
|
||||
slipper com1 vec=60 baud=57600 ether (may vary with your modem setup)
|
||||
lsl
|
||||
pdether
|
||||
discomx 1 (must correspond to SLIPPER's COM port)
|
||||
</PRE>
|
||||
(If you use another vec= setting, you must update that in NET.CFG as well.)
|
||||
Use CSLIPPER instead of SLIPPER if your SLIP provider supports VJC.
|
||||
<P>
|
||||
<LI>Start WfW.
|
||||
<UL>
|
||||
<LI>Under Windows Setup, choose "Change Network Settings".
|
||||
<LI>Select "Install Microsoft Windows Network".
|
||||
<LI>In "Drivers...", choose "Add Adapter"
|
||||
and install the "IPXODI Support driver (Ethernet) [ODI/NDIS3]".
|
||||
<LI>In "Add Protocols...", select "Unlisted or Updated Protocol". When asked for a
|
||||
driver disk, enter the directory where you expanded WFWT32.EXE.
|
||||
<LI>Configure TCP/IP (IP address, enable LMHOSTS lookup, try 204.118.34.11 as primary
|
||||
WINS server). Remove all other protocols (NetBEUI, IPX/SPX).
|
||||
</UL>
|
||||
<P>
|
||||
<LI>Windows will probably update the first lines of AUTOEXEC.BAT with
|
||||
<P>
|
||||
<PRE>
|
||||
c:\windows\net start
|
||||
c:\windows\odihlp.exe.
|
||||
</PRE>
|
||||
The "odihlp" line must be moved behind the "pdether" line.
|
||||
<P>
|
||||
<LI>Windows will also update NET.CFG with some "Frame" lines. These must
|
||||
be removed (except "Frame Ethernet_II").
|
||||
<P>
|
||||
<LI>Somehow, you will have to dial in to your SLIP provider. I do it manually
|
||||
before slipper (or cslipper) gets loaded, using a DOS-based terminal program.
|
||||
But there are some automatic dialers around. I've seen recommendations for
|
||||
ftp://mvmpc9.ciw.uni-karlsruhe.de/x-slip/slip_it.exe.
|
||||
<P>
|
||||
<LI>To connect to Microsoft's FTP server (or Winserve) go into File Manager,
|
||||
choose "Connect Network drive" and enter "\\ftp" or "\\winserve.001" into
|
||||
the "Path:" field.
|
||||
</UL>
|
||||
<HR>
|
||||
<H3>How it works:</H3>
|
||||
<P>
|
||||
Microsoft's TCP/IP-32 requires an NDIS3 interface. NDIS is Microsoft's way
|
||||
to interface with a network.
|
||||
<P>
|
||||
WfW also contains an NDIS3-over-ODI "shim", whose real mode component is
|
||||
ODIHLP.EXE. ODI is Novell's way to interface with a network.
|
||||
<P>
|
||||
SLIPPER is a Packet Driver (PD) for use over serial lines. PDs are everybody
|
||||
else's way to interface with a network. SLIPPER's "ether" option makes it
|
||||
look like an Ethernet PD to applications using it.
|
||||
<P>
|
||||
A "shim" is a program which simulates a network application programming
|
||||
interface on top of another.
|
||||
<P>
|
||||
There is no NDIS SLIP driver which would work with WfW.
|
||||
<P>
|
||||
There is no NDIS-over-PD shim.
|
||||
<P>
|
||||
However, there's an ODI-over-PD shim (PDETHER) and an NDIS-over-ODI shim
|
||||
(ODIHLP etc.)
|
||||
<P>
|
||||
OK, so let's do NDIS-over-ODI-over-PD!
|
||||
<P>
|
||||
This should have worked all the time; however, a non-feature in PDETHER
|
||||
versions < 1.05 has prevented the method from functioning until now.
|
||||
<HR>
|
||||
<B>Questions, suggestions etc. please to
|
||||
<P>
|
||||
<PRE>
|
||||
Peter Karrer pkarrer@ife.ee.ethz.ch
|
||||
</PRE>
|
||||
</B>
|
||||
</BODY>
|
||||
</HTML>
|
491
docs/manpages/nmbd.8
Normal file
491
docs/manpages/nmbd.8
Normal file
@ -0,0 +1,491 @@
|
||||
.TH NMBD 8 17/1/1995 nmbd nmbd
|
||||
.SH NAME
|
||||
nmbd \- provide netbios nameserver support to clients
|
||||
.SH SYNOPSIS
|
||||
.B nmbd
|
||||
[
|
||||
.B -B
|
||||
.I broadcast address
|
||||
] [
|
||||
.B -I
|
||||
.I IP address
|
||||
] [
|
||||
.B -D
|
||||
] [
|
||||
.B -C comment string
|
||||
] [
|
||||
.B -G
|
||||
.I group name
|
||||
] [
|
||||
.B -H
|
||||
.I netbios hosts file
|
||||
] [
|
||||
.B -N
|
||||
.I netmask
|
||||
] [
|
||||
.B -d
|
||||
.I debuglevel
|
||||
] [
|
||||
.B -l
|
||||
.I log basename
|
||||
] [
|
||||
.B -n
|
||||
.I netbios name
|
||||
] [
|
||||
.B -p
|
||||
.I port number
|
||||
] [
|
||||
.B -s
|
||||
.I config file name
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
This program is part of the Samba suite.
|
||||
|
||||
.B nmbd
|
||||
is a server that understands and can reply to netbios
|
||||
name service requests, like those produced by LanManager
|
||||
clients. It also controls browsing.
|
||||
|
||||
LanManager clients, when they start up, may wish to locate a LanManager server.
|
||||
That is, they wish to know what IP number a specified host is using.
|
||||
|
||||
This program simply listens for such requests, and if its own name is specified
|
||||
it will respond with the IP number of the host it is running on. "Its own name"
|
||||
is by default the name of the host it is running on, but this can be overriden
|
||||
with the
|
||||
.B -n
|
||||
option (see "OPTIONS" below). Using the
|
||||
.B -S
|
||||
option (see "OPTIONS" below), it can also be instructed to respond with IP
|
||||
information about other hosts, provided they are locatable via the
|
||||
gethostbyname() call, or they are in a netbios hosts file.
|
||||
|
||||
Nmbd can also be used as a WINS (Windows Internet Name Server)
|
||||
server. It will do this automatically by default. What this basically
|
||||
means is that it will respond to all name requests that it receives
|
||||
that are not broadcasts, as long as it can resolve the name.
|
||||
.SH OPTIONS
|
||||
.B -B
|
||||
|
||||
.RS 3
|
||||
On some systems, the server is unable to determine the broadcast address to
|
||||
use for name registration requests. If your system has this difficulty, this
|
||||
parameter may be used to specify an appropriate broadcast address. The
|
||||
address should be given in standard "a.b.c.d" notation.
|
||||
|
||||
Only use this parameter if you are sure that the server cannot properly
|
||||
determine the proper broadcast address.
|
||||
|
||||
The default broadcast address is determined by the server at run time. If it
|
||||
encounters difficulty doing so, it makes a guess based on the local IP
|
||||
number.
|
||||
.RE
|
||||
.B -I
|
||||
|
||||
.RS 3
|
||||
On some systems, the server is unable to determine the correct IP
|
||||
address to use. This allows you to override the default choice.
|
||||
.RE
|
||||
|
||||
.B -D
|
||||
|
||||
.RS 3
|
||||
If specified, this parameter causes the server to operate as a daemon. That is,
|
||||
it detaches itself and runs in the background, fielding requests on the
|
||||
appropriate port.
|
||||
|
||||
By default, the server will NOT operate as a daemon.
|
||||
.RE
|
||||
|
||||
.B -C comment string
|
||||
|
||||
.RS 3
|
||||
This allows you to set the "comment string" that is shown next to the
|
||||
machine name in browse listings.
|
||||
|
||||
A %v will be replaced with the Samba version number.
|
||||
|
||||
A %h will be replaced with the hostname.
|
||||
|
||||
It defaults to "Samba %v".
|
||||
.RE
|
||||
|
||||
.B -G
|
||||
|
||||
.RS 3
|
||||
This option allows you to specify a netbios group (also known as
|
||||
lanmanager domain) that the server should be part of. You may include
|
||||
several of these on the command line if you like. Alternatively you
|
||||
can use the -H option to load a netbios hosts file containing domain names.
|
||||
|
||||
At startup, unless the -R switch has been used, the server will
|
||||
attempt to register all group names in the hosts file and on the
|
||||
command line (from the -G option).
|
||||
|
||||
The server will also respond to queries on this name.
|
||||
.RE
|
||||
|
||||
.B -H
|
||||
|
||||
.RS 3
|
||||
It may be useful in some situations to be able to specify a list of
|
||||
netbios names for which the server should send a reply if
|
||||
queried. This option allows that. The syntax is similar to the
|
||||
standard /etc/hosts file format, but has some extensions.
|
||||
|
||||
The file contains three columns. Lines beginning with a # are ignored
|
||||
as comments. The first column is an IP address, or a hostname. If it
|
||||
is a hostname then it is interpreted as the IP address returned by
|
||||
gethostbyname() when read. Any IP address of 0.0.0.0 will be
|
||||
interpreted as the servers own IP address.
|
||||
|
||||
The second column is a netbios name. This is the name that the server
|
||||
will respond to. It must be less than 20 characters long.
|
||||
|
||||
The third column is optional, and is intended for flags. Currently the
|
||||
only flags supported are G, S and M. A G indicates that the name is a
|
||||
group (also known as domain) name.
|
||||
|
||||
At startup all groups known to the server (either from this file or
|
||||
from the -G option) are registered on the network (unless the -R
|
||||
option has been selected).
|
||||
|
||||
A S or G means that the specified address is a broadcast address of a
|
||||
network that you want people to be able to browse you from. Nmbd will
|
||||
search for a master browser in that domain and will send host
|
||||
announcements to that machine, informing it that the specifed somain
|
||||
is available.
|
||||
|
||||
A M means that this name is the default netbios name for this
|
||||
machine. This has the same affect as specifying the -n option to nmbd.
|
||||
|
||||
After startup the server waits for queries, and will answer queries to
|
||||
any name known to it. This includes all names in the netbios hosts
|
||||
file (if any), it's own name, and any names given with the -G option.
|
||||
|
||||
The primary intention of the -H option is to allow a mapping from
|
||||
netbios names to internet domain names, and to allow the specification
|
||||
of groups that the server should be part of.
|
||||
|
||||
.B Example:
|
||||
|
||||
# This is a sample netbios hosts file
|
||||
|
||||
# DO NOT USE THIS FILE AS-IS
|
||||
# YOU MAY INCONVENIENCE THE OWNERS OF THESE IPs
|
||||
# if you want to include a name with a space in it then
|
||||
# use double quotes.
|
||||
|
||||
# first put ourselves in the group LANGROUP
|
||||
0.0.0.0 LANGROUP G
|
||||
|
||||
# next add a netbios alias for a faraway host
|
||||
arvidsjaur.anu.edu.au ARVIDSJAUR
|
||||
|
||||
# finally put in an IP for a hard to find host
|
||||
130.45.3.213 FREDDY
|
||||
|
||||
# now we want another subnet to be able to browse
|
||||
# us in the workgroup UNIXSERV
|
||||
192.0.2.255 UNIXSERV G
|
||||
|
||||
.RE
|
||||
|
||||
.B -M
|
||||
.I workgroup name
|
||||
|
||||
.RS 3
|
||||
If this parameter is given, the server will look for a master browser
|
||||
for the specified workgroup name, report success or failure, then
|
||||
exit. If successful, the IP address of the name located will be
|
||||
reported.
|
||||
|
||||
If you use the workgroup name "-" then nmbd will search for a master
|
||||
browser for any workgroup by using the name __MSBROWSE__.
|
||||
|
||||
This option is meant to be used interactively on the command line, not
|
||||
as a daemon or in inetd.
|
||||
|
||||
.RE
|
||||
.B -N
|
||||
|
||||
.RS 3
|
||||
On some systems, the server is unable to determine the netmask. If
|
||||
your system has this difficulty, this parameter may be used to specify
|
||||
an appropriate netmask. The mask should be given in standard
|
||||
"a.b.c.d" notation.
|
||||
|
||||
Only use this parameter if you are sure that the server cannot properly
|
||||
determine the proper netmask.
|
||||
|
||||
The default netmask is determined by the server at run time. If it
|
||||
encounters difficulty doing so, it makes a guess based on the local IP
|
||||
number.
|
||||
.RE
|
||||
|
||||
.B -d
|
||||
.I debuglevel
|
||||
.RS 3
|
||||
|
||||
debuglevel is an integer from 0 to 5.
|
||||
|
||||
The default value if this parameter is not specified is zero.
|
||||
|
||||
The higher this value, the more detail will be logged to the log files about
|
||||
the activities of the server. At level 0, only critical errors and serious
|
||||
warnings will be logged. Level 1 is a reasonable level for day to day running
|
||||
- it generates a small amount of information about operations carried out.
|
||||
|
||||
Levels above 1 will generate considerable amounts of log data, and should
|
||||
only be used when investigating a problem. Levels above 3 are designed for
|
||||
use only by developers and generate HUGE amounts of log data, most of which
|
||||
is extremely cryptic.
|
||||
.RE
|
||||
|
||||
.B -l
|
||||
.I log file
|
||||
|
||||
.RS 3
|
||||
If specified,
|
||||
.I logfile
|
||||
specifies a base filename into which operational data from the running server
|
||||
will be logged.
|
||||
|
||||
The default base name is specified at compile time.
|
||||
|
||||
The base name is used to generate actual log file names. For example, if the
|
||||
name specified was "log", the following files would be used for log data:
|
||||
|
||||
.RS 3
|
||||
log.nmb (containing debugging information)
|
||||
|
||||
log.nmb.in (containing inbound transaction data)
|
||||
|
||||
log.nmb.out (containing outbound transaction data)
|
||||
.RE
|
||||
|
||||
The log files generated are never removed by the server.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.I netbios name
|
||||
|
||||
.RS 3
|
||||
This parameter tells the server what netbios name to respond with when
|
||||
queried. The same name is also registered on startup unless the -R
|
||||
parameter was specified.
|
||||
|
||||
The default netbios name used if this parameter is not specified is the
|
||||
name of the host on which the server is running.
|
||||
.RE
|
||||
|
||||
.B -p
|
||||
.I port number
|
||||
.RS 3
|
||||
|
||||
port number is a positive integer value.
|
||||
|
||||
The default value if this parameter is not specified is 137.
|
||||
|
||||
This number is the port number that will be used when making connections to
|
||||
the server from client software. The standard (well-known) port number for the
|
||||
server is 137, hence the default. If you wish to run the server as an ordinary
|
||||
user rather than as root, most systems will require you to use a port number
|
||||
greater than 1024 - ask your system administrator for help if you are in this
|
||||
situation.
|
||||
|
||||
Note that the name server uses UDP, not TCP!
|
||||
|
||||
This parameter is not normally specified except in the above situation.
|
||||
.RE
|
||||
.SH FILES
|
||||
|
||||
.B /etc/inetd.conf
|
||||
|
||||
.RS 3
|
||||
If the server is to be run by the inetd meta-daemon, this file must contain
|
||||
suitable startup information for the meta-daemon. See the section
|
||||
"INSTALLATION" below.
|
||||
.RE
|
||||
|
||||
.B /etc/rc.d/rc.inet2
|
||||
|
||||
.RS 3
|
||||
(or whatever initialisation script your system uses)
|
||||
|
||||
If running the server as a daemon at startup, this file will need to contain
|
||||
an appropriate startup sequence for the server. See the section "Installation"
|
||||
below.
|
||||
.RE
|
||||
|
||||
.B /etc/services
|
||||
|
||||
.RS 3
|
||||
If running the server via the meta-daemon inetd, this file must contain a
|
||||
mapping of service name (eg., netbios-ns) to service port (eg., 137) and
|
||||
protocol type (eg., udp). See the section "INSTALLATION" below.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
Not applicable.
|
||||
|
||||
.SH INSTALLATION
|
||||
The location of the server and its support files is a matter for individual
|
||||
system administrators. The following are thus suggestions only.
|
||||
|
||||
It is recommended that the server software be installed under the /usr/local
|
||||
hierarchy, in a directory readable by all, writeable only by root. The server
|
||||
program itself should be executable by all, as users may wish to run the
|
||||
server themselves (in which case it will of course run with their privileges).
|
||||
The server should NOT be setuid or setgid!
|
||||
|
||||
The server log files should be put in a directory readable and writable only
|
||||
by root, as the log files may contain sensitive information.
|
||||
|
||||
The remaining notes will assume the following:
|
||||
|
||||
.RS 3
|
||||
nmbd (the server program) installed in /usr/local/smb
|
||||
|
||||
log files stored in /var/adm/smblogs
|
||||
.RE
|
||||
|
||||
The server may be run either as a daemon by users or at startup, or it may
|
||||
be run from a meta-daemon such as inetd upon request. If run as a daemon, the
|
||||
server will always be ready, so starting sessions will be faster. If run from
|
||||
a meta-daemon some memory will be saved and utilities such as the tcpd
|
||||
TCP-wrapper may be used for extra security.
|
||||
|
||||
When you've decided, continue with either "Running the server as a daemon" or
|
||||
"Running the server on request".
|
||||
.SH RUNNING THE SERVER AS A DAEMON
|
||||
To run the server as a daemon from the command line, simply put the "-D" option
|
||||
on the command line. There is no need to place an ampersand at the end of the
|
||||
command line - the "-D" option causes the server to detach itself from the
|
||||
tty anyway.
|
||||
|
||||
Any user can run the server as a daemon (execute permissions permitting, of
|
||||
course). This is useful for testing purposes.
|
||||
|
||||
To ensure that the server is run as a daemon whenever the machine is started,
|
||||
you will need to modify the system startup files. Wherever appropriate (for
|
||||
example, in /etc/rc.d/rc.inet2), insert the following line, substituting
|
||||
values appropriate to your system:
|
||||
|
||||
.RS 3
|
||||
/usr/local/smb/nmbd -D -l/var/adm/smblogs/log
|
||||
.RE
|
||||
|
||||
(The above should appear in your initialisation script as a single line.
|
||||
Depending on your terminal characteristics, it may not appear that way in
|
||||
this man page. If the above appears as more than one line, please treat any
|
||||
newlines or indentation as a single space or TAB character.)
|
||||
|
||||
If the options used at compile time are appropriate for your system, all
|
||||
parameters except the desired debug level and "-D" may be omitted. See the
|
||||
section on "Options" above.
|
||||
.SH RUNNING THE SERVER ON REQUEST
|
||||
If your system uses a meta-daemon such as inetd, you can arrange to have the
|
||||
SMB name server started whenever a process attempts to connect to it. This
|
||||
requires several changes to the startup files on the host machine. If you are
|
||||
experimenting as an ordinary user rather than as root, you will need the
|
||||
assistance of your system administrator to modify the system files.
|
||||
|
||||
First, ensure that a port is configured in the file /etc/services. The
|
||||
well-known port 137 should be used if possible, though any port may be used.
|
||||
|
||||
Ensure that a line similar to the following is in /etc/services:
|
||||
|
||||
.RS 3
|
||||
netbios-ns 137/udp
|
||||
.RE
|
||||
|
||||
Note for NIS/YP users: You may need to rebuild the NIS service maps rather
|
||||
than alter your local /etc/services file.
|
||||
|
||||
Next, put a suitable line in the file /etc/inetd.conf (in the unlikely event
|
||||
that you are using a meta-daemon other than inetd, you are on your own). Note
|
||||
that the first item in this line matches the service name in /etc/services.
|
||||
Substitute appropriate values for your system in this line (see
|
||||
.B inetd(8)):
|
||||
|
||||
.RS 3
|
||||
netbios-ns dgram udp wait root /usr/local/smb/nmbd -l/var/adm/smblogs/log
|
||||
.RE
|
||||
|
||||
(The above should appear in /etc/inetd.conf as a single line. Depending on
|
||||
your terminal characteristics, it may not appear that way in this man page.
|
||||
If the above appears as more than one line, please treat any newlines or
|
||||
indentation as a single space or TAB character.)
|
||||
|
||||
Note that there is no need to specify a port number here, even if you are
|
||||
using a non-standard port number.
|
||||
.SH TESTING THE INSTALLATION
|
||||
If running the server as a daemon, execute it before proceeding. If
|
||||
using a meta-daemon, either restart the system or kill and restart the
|
||||
meta-daemon. Some versions of inetd will reread their configuration tables if
|
||||
they receive a HUP signal.
|
||||
|
||||
To test whether the name server is running, start up a client
|
||||
.I on a different machine
|
||||
and see whether the desired name is now present. Alternatively, run
|
||||
the nameserver
|
||||
.I on a different machine
|
||||
specifying "-L netbiosname", where "netbiosname" is the name you have
|
||||
configured the test server to respond with. The command should respond
|
||||
with success, and the IP number of the machine using the specified netbios
|
||||
name. You may need the -B parameter on some systems. See the README
|
||||
file for more information on testing nmbd.
|
||||
|
||||
.SH VERSION
|
||||
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
|
||||
of the recent patches to it. These notes will necessarily lag behind
|
||||
development of the software, so it is possible that your version of
|
||||
the server has extensions or parameter semantics that differ from or are not
|
||||
covered by this man page. Please notify these to the address below for
|
||||
rectification.
|
||||
.SH SEE ALSO
|
||||
.B inetd(8),
|
||||
.B smbd(8),
|
||||
.B smb.conf(5),
|
||||
.B smbclient(1),
|
||||
.B testparm(1),
|
||||
.B testprns(1)
|
||||
|
||||
.SH DIAGNOSTICS
|
||||
[This section under construction]
|
||||
|
||||
Most diagnostics issued by the server are logged in the specified log file. The
|
||||
log file name is specified at compile time, but may be overridden on the
|
||||
command line.
|
||||
|
||||
The number and nature of diagnostics available depends on the debug level used
|
||||
by the server. If you have problems, set the debug level to 3 and peruse the
|
||||
log files.
|
||||
|
||||
Most messages are reasonably self-explanatory. Unfortunately, at time of
|
||||
creation of this man page the source code is still too fluid to warrant
|
||||
describing each and every diagnostic. At this stage your best bet is still
|
||||
to grep the source code and inspect the conditions that gave rise to the
|
||||
diagnostics you are seeing.
|
||||
|
||||
.SH BUGS
|
||||
None known.
|
||||
.SH CREDITS
|
||||
The original Samba software and related utilities were created by
|
||||
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
|
||||
of the Source for this project.
|
||||
|
||||
This man page written by Karl Auer (Karl.Auer@anu.edu.au)
|
||||
|
||||
See
|
||||
.B smb.conf(5) for a full list of contributors and details on how to
|
||||
submit bug reports, comments etc.
|
||||
|
||||
|
||||
|
||||
|
||||
|
190
docs/manpages/samba.7
Normal file
190
docs/manpages/samba.7
Normal file
@ -0,0 +1,190 @@
|
||||
.TH SAMBA 7 29/3/95 Samba Samba
|
||||
.SH NAME
|
||||
Samba \- a LanManager like fileserver for Unix
|
||||
.SH SYNOPSIS
|
||||
.B Samba
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B Samba
|
||||
software suite is a collection of programs that implements the SMB
|
||||
protocol for unix systems. This protocol is sometimes also referred to
|
||||
as the LanManager or Netbios protocol.
|
||||
|
||||
.SH COMPONENTS
|
||||
|
||||
The Samba suite is made up of several components. Each component is
|
||||
described in a separate manual page. It is strongly recommended that
|
||||
you read the documentation that comes with Samba and the manual pages
|
||||
of those components that you use. If the manual pages aren't clear
|
||||
enough then please send me a patch!
|
||||
|
||||
The smbd(8) daemon provides the file and print services to SMB clents,
|
||||
such as Windows for Workgroups, Windows NT or LanManager. The
|
||||
configuration file for this daemon is described in smb.conf(5).
|
||||
|
||||
The nmbd(8) daemon provides Netbios nameserving and browsing
|
||||
support. It can also be run interactively to query other name service
|
||||
daemons.
|
||||
|
||||
The smbclient(1) program implements a simple ftp-like client. This is
|
||||
useful for accessing SMB shares on other compatible servers (such as
|
||||
WfWg), and can also be used to allow a unix box to print to a printer
|
||||
attached to any SMB server (such as a PC running WfWg).
|
||||
|
||||
The testparm(1) utility allows you to test your smb.conf(5)
|
||||
configuration file.
|
||||
|
||||
The smbstatus(1) utility allows you to tell who is currently using the
|
||||
smbd(8) server.
|
||||
|
||||
.SH AVAILABILITY
|
||||
|
||||
The Samba software suite is licensed under the Gnu Public License. A
|
||||
copy of that license should have come with the package. You are
|
||||
encouraged to distribute copies of the Samba suite, but please keep it
|
||||
intact.
|
||||
|
||||
The latest version of the Samba suite can be obtained via anonymous
|
||||
ftp from nimbus.anu.edu.au in the directory pub/tridge/samba/. It is
|
||||
also available on several mirror sites worldwide.
|
||||
|
||||
You may also find useful information about Samba on the newsgroup
|
||||
comp.protocols.smb and the Samba mailing list. Details on how to join
|
||||
the mailing list are given in the README file that comes with Samba.
|
||||
|
||||
If you have access to a WWW viewer (such as Netscape or Mosaic) then
|
||||
you will also find lots of useful information, including back issues
|
||||
of the Samba mailing list, at http://lake.canberra.edu.au/pub/samba/
|
||||
|
||||
.SH AUTHOR
|
||||
|
||||
The main author of the Samba suite is Andrew Tridgell. He may be
|
||||
contacted via e-mail at samba-bugs@anu.edu.au.
|
||||
|
||||
There have also been an enourmous number of contributors to Samba from
|
||||
all over the world. A partial list of these contributors is included
|
||||
in the CREDITS section below. The list is, however, badly out of
|
||||
date. More up to date info may be obtained from the change-log that
|
||||
comes with the Samba source code.
|
||||
|
||||
.SH CONTRIBUTIONS
|
||||
|
||||
If you wish to contribute to the Samba project, then I suggest you
|
||||
join the Samba mailing list.
|
||||
|
||||
If you have patches to submit or bugs to report then you may mail them
|
||||
directly to samba-bugs@anu.edu.au. Note, however, that due to the
|
||||
enourmous popularity of this package I may take some time to repond to
|
||||
mail. I prefer patches in "diff -u" format.
|
||||
|
||||
.SH CREDITS
|
||||
|
||||
Contributors to the project are (in alphabetical order by email address):
|
||||
|
||||
(NOTE: This list is very out of date)
|
||||
|
||||
Adams, Graham
|
||||
(gadams@ddrive.demon.co.uk)
|
||||
Allison, Jeremy
|
||||
(jeremy@netcom.com)
|
||||
Andrus, Ross
|
||||
(ross@augie.insci.com)
|
||||
Auer, Karl
|
||||
(Karl.Auer@anu.edu.au)
|
||||
Bogstad, Bill
|
||||
(bogstad@cs.jhu.edu)
|
||||
Boreham, Bryan
|
||||
(Bryan@alex.com)
|
||||
Boreham, David
|
||||
(davidb@ndl.co.uk)
|
||||
Butler, Michael
|
||||
(imb@asstdc.scgt.oz.au)
|
||||
???
|
||||
(charlie@edina.demon.co.uk)
|
||||
Chua, Michael
|
||||
(lpc@solomon.technet.sg)
|
||||
Cochran, Marc
|
||||
(mcochran@wellfleet.com)
|
||||
Dey, Martin N
|
||||
(mnd@netmgrs.co.uk)
|
||||
Errath, Maximilian
|
||||
(errath@balu.kfunigraz.ac.at)
|
||||
Fisher, Lee
|
||||
(leefi@microsoft.com)
|
||||
Foderaro, Sean
|
||||
(jkf@frisky.Franz.COM)
|
||||
Greer, Brad
|
||||
(brad@cac.washington.edu)
|
||||
Griffith, Michael A
|
||||
(grif@cs.ucr.edu)
|
||||
Grosen, Mark
|
||||
(MDGrosen@spectron.COM)
|
||||
????
|
||||
(gunjkoa@dep.sa.gov.au)
|
||||
Haapanen, Tom
|
||||
(tomh@metrics.com)
|
||||
Hench, Mike
|
||||
(hench@cae.uwm.edu)
|
||||
Horstman, Mark A
|
||||
(mh2620@sarek.sbc.com)
|
||||
Hudson, Tim
|
||||
(tim.hudson@gslmail.mincom.oz.au)
|
||||
Hulthen, Erik Magnus
|
||||
(magnus@axiom.se)
|
||||
???
|
||||
(imb@asstdc.scgt.oz.au)
|
||||
Iversen, Per Steinar
|
||||
(iversen@dsfys1.fi.uib.no)
|
||||
Kaara, Pasi
|
||||
(ppk@atk.tpo.fi)
|
||||
Karman, Merik
|
||||
(merik@blackadder.dsh.oz.au)
|
||||
Kiff, Martin
|
||||
(mgk@newton.npl.co.uk)
|
||||
Kiick, Chris
|
||||
(cjkiick@flinx.b11.ingr.com)
|
||||
Kukulies, Christoph
|
||||
(kuku@acds.physik.rwth-aachen.de)
|
||||
???
|
||||
(lance@fox.com)
|
||||
Lendecke, Volker
|
||||
(lendecke@namu01.gwdg.de)
|
||||
???
|
||||
(lonnie@itg.ti.com)
|
||||
Mahoney, Paul Thomas
|
||||
(ptm@xact1.xact.com)
|
||||
Mauelshagen, Heinz
|
||||
(mauelsha@ez.da.telekom.de)
|
||||
Merrick, Barry G
|
||||
(bgm@atml.co.uk)
|
||||
Mol, Marcel
|
||||
(marcel@fanout.et.tudeflt.nl)
|
||||
???
|
||||
(njw@cpsg.com.au)
|
||||
???
|
||||
(noses@oink.rhein.de)
|
||||
Owens, John
|
||||
(john@micros.com)
|
||||
Pierson, Jacques
|
||||
(pierson@ketje.enet.dec.com)
|
||||
Powell, Mark
|
||||
(mark@scot1.ucsalf.ac.uk)
|
||||
Reiz, Steven
|
||||
(sreiz@aie.nl)
|
||||
Schlaeger, Joerg
|
||||
(joergs@toppoint.de)
|
||||
S{rkel{, Vesa
|
||||
(vesku@rankki.kcl.fi)
|
||||
Tridgell, Andrew
|
||||
(samba-bugs@anu.edu.au)
|
||||
Troyer, Dean
|
||||
(troyer@saifr00.ateng.az.honeywell.com)
|
||||
Wakelin, Ross
|
||||
(rossw@march.co.uk)
|
||||
Wessels, Stefan
|
||||
(SWESSELS@dos-lan.cs.up.ac.za)
|
||||
Young, Ian A
|
||||
(iay@threel.co.uk)
|
||||
van der Zwan, Paul
|
||||
(paulzn@olivetti.nl)
|
||||
|
2719
docs/manpages/smb.conf.5
Normal file
2719
docs/manpages/smb.conf.5
Normal file
File diff suppressed because it is too large
Load Diff
1133
docs/manpages/smbclient.1
Normal file
1133
docs/manpages/smbclient.1
Normal file
File diff suppressed because it is too large
Load Diff
407
docs/manpages/smbd.8
Normal file
407
docs/manpages/smbd.8
Normal file
@ -0,0 +1,407 @@
|
||||
.TH SMBD 8 17/1/1995 smbd smbd
|
||||
.SH NAME
|
||||
smbd \- provide SMB (aka LanManager) services to clients
|
||||
.SH SYNOPSIS
|
||||
.B smbd
|
||||
[
|
||||
.B -D
|
||||
] [
|
||||
.B -a
|
||||
] [
|
||||
.B -d
|
||||
.I debuglevel
|
||||
] [
|
||||
.B -l
|
||||
.I log file
|
||||
] [
|
||||
.B -p
|
||||
.I port number
|
||||
] [
|
||||
.B -O
|
||||
.I socket options
|
||||
] [
|
||||
.B -s
|
||||
.I configuration file
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
This program is part of the Samba suite.
|
||||
|
||||
.B smbd
|
||||
is a server that can provide most SMB services. The
|
||||
server provides filespace and printer services to clients using the SMB
|
||||
protocol. This is compatible with the LanManager protocol, and can
|
||||
service LanManager clients.
|
||||
|
||||
An extensive description of the services that the server can provide is given
|
||||
in the man page for the configuration file controlling the attributes of those
|
||||
services (see
|
||||
.B smb.conf(5)). This man page will not describe the services, but
|
||||
will concentrate on the administrative aspects of running the server.
|
||||
|
||||
Please note that there are significant security implications to running this
|
||||
server, and
|
||||
.B smb.conf(5) should be regarded as mandatory reading before proceeding with
|
||||
installation.
|
||||
|
||||
A session is created whenever a client requests one. Each client gets a copy
|
||||
of the server for each session. This copy then services all connections made
|
||||
by the client during that session. When all connections from its client are
|
||||
are closed, the copy of the server for that client terminates.
|
||||
|
||||
The configuration file is automatically reloaded if it changes. You
|
||||
can force a reload by sending a SIGHUP to the server.
|
||||
|
||||
.SH OPTIONS
|
||||
.B -D
|
||||
|
||||
.RS 3
|
||||
If specified, this parameter causes the server to operate as a daemon. That is,
|
||||
it detaches itself and runs in the background, fielding requests on the
|
||||
appropriate port.
|
||||
|
||||
By default, the server will NOT operate as a daemon.
|
||||
.RE
|
||||
|
||||
.B -a
|
||||
|
||||
.RS 3
|
||||
If this parameter is specified, the log files will be overwritten with each
|
||||
new connection. By default, the log files will be appended to.
|
||||
.RE
|
||||
|
||||
.B -d
|
||||
.I debuglevel
|
||||
.RS 3
|
||||
|
||||
debuglevel is an integer from 0 to 5.
|
||||
|
||||
The default value if this parameter is not specified is zero.
|
||||
|
||||
The higher this value, the more detail will be logged to the log files about
|
||||
the activities of the server. At level 0, only critical errors and serious
|
||||
warnings will be logged. Level 1 is a reasonable level for day to day running
|
||||
- it generates a small amount of information about operations carried out.
|
||||
|
||||
Levels above 1 will generate considerable amounts of log data, and should
|
||||
only be used when investigating a problem. Levels above 3 are designed for
|
||||
use only by developers and generate HUGE amounts of log data, most of which
|
||||
is extremely cryptic.
|
||||
.RE
|
||||
|
||||
.B -l
|
||||
.I log file
|
||||
|
||||
.RS 3
|
||||
If specified,
|
||||
.I logfile
|
||||
specifies a base filename into which operational data from the running server
|
||||
will be logged.
|
||||
|
||||
The default base name is specified at compile time.
|
||||
|
||||
The base name is used to generate actual log file names. For example, if the
|
||||
name specified was "log", the following files would be used for log data:
|
||||
|
||||
.RS 3
|
||||
log.debug (containing debugging information)
|
||||
|
||||
log.in (containing inbound transaction data)
|
||||
|
||||
log.out (containing outbound transaction data)
|
||||
.RE
|
||||
|
||||
The log files generated are never removed by the server.
|
||||
.RE
|
||||
|
||||
.B -O
|
||||
.I socket options
|
||||
.RS 3
|
||||
|
||||
See the socket options section of smb.conf(5) for details
|
||||
|
||||
.RE
|
||||
.B -p
|
||||
.I port number
|
||||
.RS 3
|
||||
|
||||
port number is a positive integer value.
|
||||
|
||||
The default value if this parameter is not specified is 139.
|
||||
|
||||
This number is the port number that will be used when making connections to
|
||||
the server from client software. The standard (well-known) port number for the
|
||||
server is 139, hence the default. If you wish to run the server as an ordinary
|
||||
user rather than as root, most systems will require you to use a port number
|
||||
greater than 1024 - ask your system administrator for help if you are in this
|
||||
situation.
|
||||
|
||||
This parameter is not normally specified except in the above situation.
|
||||
.RE
|
||||
|
||||
.B -s
|
||||
.I configuration file
|
||||
|
||||
.RS 3
|
||||
The default configuration file name is determined at compile time.
|
||||
|
||||
The file specified contains the configuration details required by the server.
|
||||
The information in this file includes server-specific information such as
|
||||
what printcap file to use, as well as descriptions of all the services that the
|
||||
server is to provide. See
|
||||
.B smb.conf(5) for more information.
|
||||
.RE
|
||||
|
||||
.SH FILES
|
||||
|
||||
.B /etc/inetd.conf
|
||||
|
||||
.RS 3
|
||||
If the server is to be run by the inetd meta-daemon, this file must contain
|
||||
suitable startup information for the meta-daemon. See the section
|
||||
"INSTALLATION" below.
|
||||
.RE
|
||||
|
||||
.B /etc/rc
|
||||
|
||||
.RS 3
|
||||
(or whatever initialisation script your system uses)
|
||||
|
||||
If running the server as a daemon at startup, this file will need to contain
|
||||
an appropriate startup sequence for the server. See the section "INSTALLATION"
|
||||
below.
|
||||
.RE
|
||||
|
||||
.B /etc/services
|
||||
|
||||
.RS 3
|
||||
If running the server via the meta-daemon inetd, this file must contain a
|
||||
mapping of service name (eg., netbios-ssn) to service port (eg., 139) and
|
||||
protocol type (eg., tcp). See the section "INSTALLATION" below.
|
||||
.RE
|
||||
|
||||
.B /usr/local/smb/smb.conf
|
||||
|
||||
.RS 3
|
||||
This file describes all the services the server is to make available to
|
||||
clients. See
|
||||
.B smb.conf(5) for more information.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.SH LIMITATIONS
|
||||
|
||||
On some systems smbd cannot change uid back to root after a setuid() call.
|
||||
Such systems are called "trapdoor" uid systems. If you have such a system,
|
||||
you will be unable to connect from a client (such as a PC) as two different
|
||||
users at once. Attempts to connect the second user will result in "access
|
||||
denied" or similar.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
|
||||
.B PRINTER
|
||||
|
||||
.RS 3
|
||||
If no printer name is specified to printable services, most systems will
|
||||
use the value of this variable (or "lp" if this variable is not defined)
|
||||
as the name of the printer to use. This is not specific to the server,
|
||||
however.
|
||||
.RE
|
||||
|
||||
.SH INSTALLATION
|
||||
The location of the server and its support files is a matter for individual
|
||||
system administrators. The following are thus suggestions only.
|
||||
|
||||
It is recommended that the server software be installed under the
|
||||
/usr/local hierarchy, in a directory readable by all, writeable only
|
||||
by root. The server program itself should be executable by all, as
|
||||
users may wish to run the server themselves (in which case it will of
|
||||
course run with their privileges). The server should NOT be
|
||||
setuid. On some systems it may be worthwhile to make smbd setgid to an
|
||||
empty group. This is because some systems may have a security hole where
|
||||
daemon processes that become a user can be attached to with a
|
||||
debugger. Making the smbd file setgid to an empty group may prevent
|
||||
this hole from being exploited. This secrity hole and the suggested
|
||||
fix has only been confirmed on Linux at the time this was written. It
|
||||
is possible that this hole only exists in Linux, as testing on other
|
||||
systems has thus far shown them to be immune.
|
||||
|
||||
The server log files should be put in a directory readable and writable only
|
||||
by root, as the log files may contain sensitive information.
|
||||
|
||||
The configuration file should be placed in a directory readable and writable
|
||||
only by root, as the configuration file controls security for the services
|
||||
offered by the server. The configuration file can be made readable by all if
|
||||
desired, but this is not necessary for correct operation of the server and
|
||||
is not recommended. A sample configuration file "smb.conf.sample" is supplied
|
||||
with the source to the server - this may be renamed to "smb.conf" and
|
||||
modified to suit your needs.
|
||||
|
||||
The remaining notes will assume the following:
|
||||
|
||||
.RS 3
|
||||
smbd (the server program) installed in /usr/local/smb
|
||||
|
||||
smb.conf (the configuration file) installed in /usr/local/smb
|
||||
|
||||
log files stored in /var/adm/smblogs
|
||||
.RE
|
||||
|
||||
The server may be run either as a daemon by users or at startup, or it may
|
||||
be run from a meta-daemon such as inetd upon request. If run as a daemon, the
|
||||
server will always be ready, so starting sessions will be faster. If run from
|
||||
a meta-daemon some memory will be saved and utilities such as the tcpd
|
||||
TCP-wrapper may be used for extra security.
|
||||
|
||||
When you've decided, continue with either "RUNNING THE SERVER AS A DAEMON" or
|
||||
"RUNNING THE SERVER ON REQUEST".
|
||||
.SH RUNNING THE SERVER AS A DAEMON
|
||||
To run the server as a daemon from the command line, simply put the "-D" option
|
||||
on the command line. There is no need to place an ampersand at the end of the
|
||||
command line - the "-D" option causes the server to detach itself from the
|
||||
tty anyway.
|
||||
|
||||
Any user can run the server as a daemon (execute permissions permitting, of
|
||||
course). This is useful for testing purposes, and may even be useful as a
|
||||
temporary substitute for something like ftp. When run this way, however, the
|
||||
server will only have the privileges of the user who ran it.
|
||||
|
||||
To ensure that the server is run as a daemon whenever the machine is started,
|
||||
and to ensure that it runs as root so that it can serve multiple clients, you
|
||||
will need to modify the system startup files. Wherever appropriate (for
|
||||
example, in /etc/rc), insert the following line, substituting
|
||||
port number, log file location, configuration file location and debug level as
|
||||
desired:
|
||||
|
||||
.RS 3
|
||||
/usr/local/smb/smbd -D -l /var/adm/smblogs/log -s /usr/local/smb/smb.conf
|
||||
.RE
|
||||
|
||||
(The above should appear in your initialisation script as a single line.
|
||||
Depending on your terminal characteristics, it may not appear that way in
|
||||
this man page. If the above appears as more than one line, please treat any
|
||||
newlines or indentation as a single space or TAB character.)
|
||||
|
||||
If the options used at compile time are appropriate for your system, all
|
||||
parameters except the desired debug level and "-D" may be omitted. See the
|
||||
section "OPTIONS" above.
|
||||
.SH RUNNING THE SERVER ON REQUEST
|
||||
If your system uses a meta-daemon such as inetd, you can arrange to have the
|
||||
smbd server started whenever a process attempts to connect to it. This requires
|
||||
several changes to the startup files on the host machine. If you are
|
||||
experimenting as an ordinary user rather than as root, you will need the
|
||||
assistance of your system administrator to modify the system files.
|
||||
|
||||
You will probably want to set up the name server
|
||||
.B nmbd
|
||||
at the same time as
|
||||
the smbd - refer to the man page
|
||||
.B nmbd(8).
|
||||
|
||||
First, ensure that a port is configured in the file /etc/services. The
|
||||
well-known port 139 should be used if possible, though any port may be used.
|
||||
|
||||
Ensure that a line similar to the following is in /etc/services:
|
||||
|
||||
.RS 3
|
||||
netbios-ssn 139/tcp
|
||||
.RE
|
||||
|
||||
Note for NIS/YP users - you may need to rebuild the NIS service maps rather
|
||||
than alter your local /etc/services file.
|
||||
|
||||
Next, put a suitable line in the file /etc/inetd.conf (in the unlikely event
|
||||
that you are using a meta-daemon other than inetd, you are on your own). Note
|
||||
that the first item in this line matches the service name in /etc/services.
|
||||
Substitute appropriate values for your system in this line (see
|
||||
.B inetd(8)):
|
||||
|
||||
.RS 3
|
||||
netbios-ssn stream tcp nowait root /usr/local/smb/smbd -d1
|
||||
-l/var/adm/smblogs/log -s/usr/local/smb/smb.conf
|
||||
.RE
|
||||
|
||||
(The above should appear in /etc/inetd.conf as a single line. Depending on
|
||||
your terminal characteristics, it may not appear that way in this man page.
|
||||
If the above appears as more than one line, please treat any newlines or
|
||||
indentation as a single space or TAB character.)
|
||||
|
||||
Note that there is no need to specify a port number here, even if you are
|
||||
using a non-standard port number.
|
||||
|
||||
Lastly, edit the configuration file to provide suitable services. To start
|
||||
with, the following two services should be all you need:
|
||||
|
||||
.RS 3
|
||||
[homes]
|
||||
.RS 3
|
||||
writable = yes
|
||||
.RE
|
||||
|
||||
[printers]
|
||||
.RS 3
|
||||
writable = no
|
||||
printable = yes
|
||||
path = /tmp
|
||||
public = yes
|
||||
.RE
|
||||
.RE
|
||||
|
||||
This will allow you to connect to your home directory and print to any printer
|
||||
supported by the host (user privileges permitting).
|
||||
.SH TESTING THE INSTALLATION
|
||||
If running the server as a daemon, execute it before proceeding. If
|
||||
using a meta-daemon, either restart the system or kill and restart the
|
||||
meta-daemon. Some versions of inetd will reread their configuration tables if
|
||||
they receive a HUP signal.
|
||||
|
||||
If your machine's name is "fred" and your name is "mary", you should now be
|
||||
able to connect to the service "\\\\fred\\mary".
|
||||
|
||||
To properly test and experiment with the server, we recommend using the
|
||||
smbclient program (see
|
||||
.B smbclient(1)).
|
||||
.SH VERSION
|
||||
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
|
||||
of the recent patches to it. These notes will necessarily lag behind
|
||||
development of the software, so it is possible that your version of
|
||||
the server has extensions or parameter semantics that differ from or are not
|
||||
covered by this man page. Please notify these to the address below for
|
||||
rectification.
|
||||
.SH SEE ALSO
|
||||
.B hosts_access(5),
|
||||
.B inetd(8),
|
||||
.B nmbd(8),
|
||||
.B smb.conf(5),
|
||||
.B smbclient(1),
|
||||
.B testparm(1),
|
||||
.B testprns(1)
|
||||
|
||||
.SH DIAGNOSTICS
|
||||
[This section under construction]
|
||||
|
||||
Most diagnostics issued by the server are logged in a specified log file. The
|
||||
log file name is specified at compile time, but may be overridden on the
|
||||
command line.
|
||||
|
||||
The number and nature of diagnostics available depends on the debug level used
|
||||
by the server. If you have problems, set the debug level to 3 and peruse the
|
||||
log files.
|
||||
|
||||
Most messages are reasonably self-explanatory. Unfortunately, at time of
|
||||
creation of this man page the source code is still too fluid to warrant
|
||||
describing each and every diagnostic. At this stage your best bet is still
|
||||
to grep the source code and inspect the conditions that gave rise to the
|
||||
diagnostics you are seeing.
|
||||
|
||||
.SH BUGS
|
||||
None known.
|
||||
.SH CREDITS
|
||||
The original Samba software and related utilities were created by
|
||||
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
|
||||
of the Source for this project.
|
||||
|
||||
This man page written by Karl Auer (Karl.Auer@anu.edu.au)
|
||||
|
||||
See
|
||||
.B smb.conf(5) for a full list of contributors and details on how to
|
||||
submit bug reports, comments etc.
|
70
docs/manpages/smbrun.1
Normal file
70
docs/manpages/smbrun.1
Normal file
@ -0,0 +1,70 @@
|
||||
.TH SMBRUN 1 17/1/1995 smbrun smbrun
|
||||
.SH NAME
|
||||
smbrun \- interface program between smbd and external programs
|
||||
.SH SYNOPSIS
|
||||
.B smbrun
|
||||
.I shell-command
|
||||
.SH DESCRIPTION
|
||||
This program is part of the Samba suite.
|
||||
|
||||
.B smbrun
|
||||
is a very small 'glue' program, which runs shell commands for
|
||||
the
|
||||
.B smbd
|
||||
daemon (see
|
||||
.B smbd(8)).
|
||||
|
||||
It first changes to the highest effective user and group ID that it can,
|
||||
then runs the command line provided using the system() call. This program is
|
||||
necessary to allow some operating systems to run external programs as non-root.
|
||||
.SH OPTIONS
|
||||
.I shell-command
|
||||
|
||||
.RS 3
|
||||
The shell command to execute.
|
||||
|
||||
The command should have a fully-qualified path.
|
||||
.RE
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
The PATH variable set for the environment in which
|
||||
.B smbrun
|
||||
is executed will affect what executables are located and executed if a
|
||||
fully-qualified path is not given in the command.
|
||||
|
||||
.SH INSTALLATION
|
||||
The location of the server and its support files is a matter for individual
|
||||
system administrators. The following are thus suggestions only.
|
||||
|
||||
It is recommended that the
|
||||
.B smbrun
|
||||
program be installed under the /usr/local hierarchy, in a directory readable
|
||||
by all, writeable only by root. The program should be executable by all.
|
||||
The program should NOT be setuid or setgid!
|
||||
.SH VERSION
|
||||
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
|
||||
of the recent patches to it. These notes will necessarily lag behind
|
||||
development of the software, so it is possible that your version of
|
||||
the program has extensions or parameter semantics that differ from or are not
|
||||
covered by this man page. Please notify these to the address below for
|
||||
rectification.
|
||||
.SH SEE ALSO
|
||||
.B smbd(8),
|
||||
.B smb.conf(8)
|
||||
.SH DIAGNOSTICS
|
||||
If smbrun cannot be located or cannot be executed by
|
||||
.B smbd
|
||||
then appropriate messages will be found in the smbd logs. Other diagnostics are
|
||||
dependent on the shell-command being run. It is advisable for your shell
|
||||
commands to issue suitable diagnostics to aid trouble-shooting.
|
||||
.SH BUGS
|
||||
None known.
|
||||
.SH CREDITS
|
||||
The original Samba software and related utilities were created by
|
||||
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
|
||||
of the Source for this project.
|
||||
|
||||
This man page was written by Karl Auer (Karl.Auer@anu.edu.au)
|
||||
|
||||
See
|
||||
.B smb.conf(5) for a full list of contributors and details of how to
|
||||
submit bug reports, comments etc.
|
52
docs/manpages/smbstatus.1
Normal file
52
docs/manpages/smbstatus.1
Normal file
@ -0,0 +1,52 @@
|
||||
.TH SMBSTATUS 1 17/1/1995 smbstatus smbstatus
|
||||
.SH NAME
|
||||
smbstatus \- report on current Samba connections
|
||||
.SH SYNOPSIS
|
||||
.B smbstatus
|
||||
[-d]
|
||||
[-s
|
||||
.I configuration file
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
This program is part of the Samba suite.
|
||||
|
||||
.B smbstatus
|
||||
is a very simple program to list the current Samba connections
|
||||
|
||||
Just run the program and the output is self explanatory. You can offer
|
||||
a configuration filename to override the default. The default is
|
||||
CONFIGFILE from the Makefile.
|
||||
|
||||
Option
|
||||
.I -d
|
||||
gives verbose output.
|
||||
|
||||
.I -p
|
||||
print a list of smbd processes and exit. Useful for scripting.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
Not applicable.
|
||||
|
||||
.SH INSTALLATION
|
||||
The location of the server and its support files is a matter for individual
|
||||
system administrators. The following are thus suggestions only.
|
||||
|
||||
It is recommended that the
|
||||
.B smbstatus
|
||||
program be installed under the /usr/local hierarchy, in a directory readable
|
||||
by all, writeable only by root. The program itself should be executable by all.
|
||||
|
||||
.SH VERSION
|
||||
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
|
||||
of the recent patches to it. These notes will necessarily lag behind
|
||||
development of the software, so it is possible that your version of
|
||||
the program has extensions or parameter semantics that differ from or are not
|
||||
covered by this man page. Please notify these to the address below for
|
||||
rectification.
|
||||
.SH SEE ALSO
|
||||
.B smb.conf(5),
|
||||
.B smbd(8)
|
||||
|
||||
See
|
||||
.B smb.conf(5) for a full list of contributors and details on how to
|
||||
submit bug reports, comments etc.
|
167
docs/manpages/smbtar.1
Normal file
167
docs/manpages/smbtar.1
Normal file
@ -0,0 +1,167 @@
|
||||
.TH SMBTAR 1 18/2/96 smbtar smbtar
|
||||
.SH NAME
|
||||
smbtar \- shell script for backing up SMB shares directly to UNIX tape drive
|
||||
.SH SYNOPSIS
|
||||
.B smbtar
|
||||
.B \-s
|
||||
.I server
|
||||
.B [ \-p
|
||||
.I password
|
||||
.B ]
|
||||
.B [ \-x
|
||||
.I service
|
||||
.B ]
|
||||
.B [ \-X ]
|
||||
.B [ \-d
|
||||
.I directory
|
||||
.B ]
|
||||
.B [ \-u
|
||||
.I user
|
||||
.B ]
|
||||
.B [ \-t
|
||||
.I tape
|
||||
.B ]
|
||||
.B [ \-b
|
||||
.I blocksize
|
||||
.B ]
|
||||
.B [ \-N
|
||||
.I filename
|
||||
.B ]
|
||||
.B [ \-i ]
|
||||
.B [ \-r ]
|
||||
.B [ \-l ]
|
||||
.B [ \-v ]
|
||||
.I filenames...
|
||||
|
||||
.SH DESCRIPTION
|
||||
This program is an extension to the Samba suite.
|
||||
|
||||
.B smbtar
|
||||
is a very small shell script on top of smbclient, which dumps SMB
|
||||
shares directly to tape.
|
||||
|
||||
.SH OPTIONS
|
||||
.B \-s
|
||||
.I server
|
||||
.RS 3
|
||||
The PC that the share resides upon.
|
||||
.RE
|
||||
|
||||
.B \-x
|
||||
.I service
|
||||
.RS 3
|
||||
The share name on the PC to connect to. Default:
|
||||
.I backup.
|
||||
.RE
|
||||
|
||||
.B \-X
|
||||
.RS 3
|
||||
Exclude mode. Exclude
|
||||
.I filenames...
|
||||
from tar create or restore.
|
||||
.RE
|
||||
|
||||
.B \-d
|
||||
.I directory
|
||||
.RS 3
|
||||
Change to initial
|
||||
.I directory
|
||||
before restoring / backing up files.
|
||||
.RE
|
||||
|
||||
.B \-v
|
||||
.RS 3
|
||||
Verbose mode.
|
||||
.RE
|
||||
|
||||
.B \-p
|
||||
.I password
|
||||
|
||||
.RS 3
|
||||
The password to use to access a share. Default: none
|
||||
.RE
|
||||
|
||||
.B \-u
|
||||
.I user
|
||||
.RS 3
|
||||
The user id to connect as. Default: UNIX login name.
|
||||
.RE
|
||||
|
||||
.B \-t
|
||||
.I tape
|
||||
.RS 3
|
||||
Tape device. May be regular file or tape device. Default: Tape environmental
|
||||
variable; if not set, a file called
|
||||
.I tar.out.
|
||||
.RE
|
||||
|
||||
.B \-b
|
||||
.I blocksize
|
||||
.RS 3
|
||||
Blocking factor. Defaults to 20. See tar(1) for a fuller explanation.
|
||||
.RE
|
||||
|
||||
.B \-N
|
||||
.I filename
|
||||
.RS 3
|
||||
Backup only files newer than filename. Could be used (for example) on a log
|
||||
file to implement incremental backups.
|
||||
.RE
|
||||
|
||||
.B \-i
|
||||
.RS 3
|
||||
Incremental mode; tar files are only backed up if they have the
|
||||
archive bit set. The archive bit is reset after each file is read.
|
||||
.RE
|
||||
|
||||
.B \-r
|
||||
.RS 3
|
||||
Restore. Files are restored to the share from the tar file.
|
||||
.RE
|
||||
|
||||
.B \-l
|
||||
.RS 3
|
||||
Debug level. Corresponds to -d flag on smbclient(1).
|
||||
.RE
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
The TAPE variable specifies the default tape device to write to. May
|
||||
be overidden with the -t option.
|
||||
|
||||
.SH BUGS
|
||||
The smbtar script has different options from ordinary tar and tar
|
||||
called from smbclient.
|
||||
|
||||
.SH CAVEATS
|
||||
Sites that are more careful about security may not like the way
|
||||
the script handles PC passwords. Backup and restore work on entire shares,
|
||||
should work on file lists.
|
||||
|
||||
.SH VERSION
|
||||
This man page is correct for version 1.9.15p8 of the Samba suite.
|
||||
|
||||
.SH SEE ALSO
|
||||
.B smbclient
|
||||
(8),
|
||||
.B smb.conf
|
||||
(8)
|
||||
.SH DIAGNOSTICS
|
||||
See diagnostics for
|
||||
.B smbclient
|
||||
command.
|
||||
|
||||
.SH CREDITS
|
||||
The original Samba software and related utilities were created by
|
||||
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
|
||||
of the Source for this project.
|
||||
|
||||
Ricky Poulten (poultenr@logica.co.uk) wrote the tar extension and this
|
||||
man page. The smbtar script was heavily rewritten and improved by
|
||||
Martin Kraemer <Martin.Kraemer@mch.sni.de>. Many thanks to everyone
|
||||
who suggested extensions, improvements, bug fixes, etc.
|
||||
|
||||
See
|
||||
.B smb.conf
|
||||
(5) for a full list of contributors and details of how to submit bug reports,
|
||||
comments etc.
|
||||
|
104
docs/manpages/testparm.1
Normal file
104
docs/manpages/testparm.1
Normal file
@ -0,0 +1,104 @@
|
||||
.TH TESTPARM 1 17/1/1995 testparm testparm
|
||||
.SH NAME
|
||||
testparm \- check an smbd configuration file for internal correctness
|
||||
.SH SYNOPSIS
|
||||
.B testparm
|
||||
[
|
||||
.I configfilename
|
||||
[
|
||||
.I hostname
|
||||
.I hostIP
|
||||
]
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
This program is part of the Samba suite.
|
||||
|
||||
.B testparm
|
||||
is a very simple test program to check an
|
||||
.B smbd
|
||||
configuration
|
||||
file for internal correctness. If this program reports no problems, you can use
|
||||
the configuration file with confidence that smbd will successfully
|
||||
load the configuration file.
|
||||
|
||||
Note that this is NOT a guarantee that the services specified in the
|
||||
configuration file will be available or will operate as expected.
|
||||
|
||||
If the optional host name and host IP address are specified on the
|
||||
command line, this test program will run through the service entries
|
||||
reporting whether the specified host has access to each service.
|
||||
.SH OPTIONS
|
||||
.I configfilename
|
||||
|
||||
.RS 3
|
||||
This is the name of the configuration file to check.
|
||||
.RE
|
||||
|
||||
.I hostname
|
||||
|
||||
.RS 3
|
||||
This is the name of the host to check access on.
|
||||
|
||||
If this parameter is supplied, the
|
||||
.I hostIP
|
||||
parameter must also be supplied, or strange things may happen.
|
||||
.RE
|
||||
|
||||
.I hostIP
|
||||
|
||||
.RS 3
|
||||
This is the IP number of the host specified in the previous parameter.
|
||||
|
||||
This number must be supplied if the
|
||||
.I hostname
|
||||
parameter is supplied, or strange things may happen.
|
||||
.RE
|
||||
.SH FILES
|
||||
.B smb.conf
|
||||
.RS 3
|
||||
This is usually the name of the configuration file used by smbd.
|
||||
.RE
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
Not applicable.
|
||||
|
||||
.SH INSTALLATION
|
||||
The location of the server and its support files is a matter for individual
|
||||
system administrators. The following are thus suggestions only.
|
||||
|
||||
It is recommended that the
|
||||
.B testparm
|
||||
program be installed under the /usr/local hierarchy, in a directory readable
|
||||
by all, writeable only by root. The program itself should be executable by all.
|
||||
The program should NOT be setuid or setgid!
|
||||
.SH VERSION
|
||||
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
|
||||
of the recent patches to it. These notes will necessarily lag behind
|
||||
development of the software, so it is possible that your version of
|
||||
the program has extensions or parameter semantics that differ from or are not
|
||||
covered by this man page. Please notify these to the address below for
|
||||
rectification.
|
||||
.SH SEE ALSO
|
||||
.B smb.conf(5),
|
||||
.B smbd(8)
|
||||
.SH DIAGNOSTICS
|
||||
The program will issue a message saying whether the configuration file loaded
|
||||
OK or not. This message may be preceded by errors and warnings if the file
|
||||
did not load. If the file was loaded OK, the program then dumps all known
|
||||
service details to stdout.
|
||||
|
||||
If a host name is specified but no host IP number, all bets are off.
|
||||
|
||||
Other messages are self-explanatory.
|
||||
.SH BUGS
|
||||
None known.
|
||||
.SH CREDITS
|
||||
The original Samba software and related utilities were created by
|
||||
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
|
||||
of the Source for this project.
|
||||
|
||||
The testparm program and this man page were written by Karl Auer
|
||||
(Karl.Auer@anu.edu.au)
|
||||
|
||||
See
|
||||
.B samba(7) for a full list of contributors and details on how to
|
||||
submit bug reports, comments etc.
|
107
docs/manpages/testprns.1
Normal file
107
docs/manpages/testprns.1
Normal file
@ -0,0 +1,107 @@
|
||||
.TH TESTPRNS 1 17/1/1995 testprns testprns
|
||||
.SH NAME
|
||||
testprns \- check printer name for validity with smbd
|
||||
.SH SYNOPSIS
|
||||
.B testprns
|
||||
.I printername
|
||||
[
|
||||
.I printcapname
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
This program is part of the Samba suite.
|
||||
|
||||
.B testprns
|
||||
is a very simple test program to determine whether a given
|
||||
printer name is valid for use in a service to be provided by
|
||||
.B smbd.
|
||||
|
||||
"Valid" in this context means "can be found in the printcap specified". This
|
||||
program is very stupid - so stupid in fact that it would be wisest to always
|
||||
specify the printcap file to use.
|
||||
.SH OPTIONS
|
||||
.I printername
|
||||
|
||||
.RS 3
|
||||
The printer name to validate.
|
||||
|
||||
Printer names are taken from the first field in each record in the printcap
|
||||
file, single printer names and sets of aliases separated by vertical bars
|
||||
("|") are recognised. Note that no validation or checking of the printcap
|
||||
syntax is done beyond that required to extract the printer name. It may
|
||||
be that the print spooling system is more forgiving or less forgiving
|
||||
than
|
||||
.B testprns
|
||||
however if
|
||||
.B testprns
|
||||
finds the printer then smbd should do as well.
|
||||
|
||||
.RE
|
||||
|
||||
.I printcapname
|
||||
|
||||
.RS 3
|
||||
This is the name of the printcap file to search for the given printer name
|
||||
in.
|
||||
|
||||
If no printcap name is specified,
|
||||
.B testprns
|
||||
will attempt to scan the printcap file specified at compile time
|
||||
(PRINTCAP_NAME).
|
||||
.RE
|
||||
.SH FILES
|
||||
.B /etc/printcap
|
||||
.RS 3
|
||||
This is usually the default printcap file to scan. See
|
||||
.B printcap(5)).
|
||||
.RE
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
Not applicable.
|
||||
|
||||
.SH INSTALLATION
|
||||
The location of the server and its support files is a matter for individual
|
||||
system administrators. The following are thus suggestions only.
|
||||
|
||||
It is recommended that the
|
||||
.B testprns
|
||||
program be installed under the /usr/local hierarchy, in a directory readable
|
||||
by all, writeable only by root. The program should be executable by all.
|
||||
The program should NOT be setuid or setgid!
|
||||
.SH VERSION
|
||||
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
|
||||
of the recent patches to it. These notes will necessarily lag behind
|
||||
development of the software, so it is possible that your version of
|
||||
the program has extensions or parameter semantics that differ from or are not
|
||||
covered by this man page. Please notify these to the address below for
|
||||
rectification.
|
||||
.SH SEE ALSO
|
||||
.B printcap(5),
|
||||
.B smbd(8),
|
||||
.B smbclient(1)
|
||||
.SH DIAGNOSTICS
|
||||
If a printer is found to be valid, the message "Printer name <printername> is
|
||||
valid" will be displayed.
|
||||
|
||||
If a printer is found to be invalid, the message "Printer name <printername>
|
||||
is not valid" will be displayed.
|
||||
|
||||
All messages that would normally be logged during operation of smbd are
|
||||
logged by this program to the file
|
||||
.I test.log
|
||||
in the current directory. The program runs at debuglevel 3, so quite extensive
|
||||
logging information is written. The log should be checked carefully for errors
|
||||
and warnings.
|
||||
|
||||
Other messages are self-explanatory.
|
||||
.SH BUGS
|
||||
None known.
|
||||
.SH CREDITS
|
||||
The original Samba software and related utilities were created by
|
||||
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
|
||||
of the Source for this project.
|
||||
|
||||
The testprns program and this man page were written by Karl Auer
|
||||
(Karl.Auer@anu.edu.au)
|
||||
|
||||
See
|
||||
.B samba(7) for a full list of contributors and details of how to
|
||||
submit bug reports, comments etc.
|
26
docs/samba.lsm
Normal file
26
docs/samba.lsm
Normal file
@ -0,0 +1,26 @@
|
||||
Begin2
|
||||
Title = Samba
|
||||
Version = 1.8.0
|
||||
Desc1 = Samba is a SMB based file and print server for unix. It
|
||||
Desc2 = provides access to unix file and print services from
|
||||
Desc3 = SMB compatible clients such as WinNT, WfWg, OS/2
|
||||
Desc4 = and Pathworks. It also includes a ftp-style unix client
|
||||
Desc5 = and a netbios nameserver.
|
||||
Author = Andrew Tridgell
|
||||
AuthorEmail = samba-bugs@anu.edu.au
|
||||
Maintainer = Andrew Tridgell
|
||||
MaintEmail = samba-bugs@anu.edu.au
|
||||
Site1 = nimbus.anu.edu.au
|
||||
Path1 = pub/tridge/samba/
|
||||
File1 = samba-latest.tar.gz
|
||||
FileSize1 = 200K
|
||||
Required1 = Ansi-C compiler and a TCP/IP network.
|
||||
CopyPolicy1 = GNU Public License
|
||||
Keywords = LanManager, SMB, Networking
|
||||
Comment1 = To join the Samba mailing list send mail to
|
||||
Comment2 = listproc@listproc.anu.edu.au with a body of
|
||||
Comment3 = "subscribe samba Your Name"
|
||||
Entered = October 1994
|
||||
EnteredBy = Andrew Tridgell
|
||||
End
|
||||
|
145
docs/textdocs/BROWSING.txt
Normal file
145
docs/textdocs/BROWSING.txt
Normal file
@ -0,0 +1,145 @@
|
||||
BROWSING
|
||||
========
|
||||
|
||||
Samba now fully supports browsing. The browsing is supported by nmbd
|
||||
and is also controlled by options in the smb.conf file (see
|
||||
smb.conf(5)).
|
||||
|
||||
Samba can act as a browse master for a workgroup, but currently cannot
|
||||
act as a domain controller. The ability to be a domain controller will
|
||||
be added in a later version.
|
||||
|
||||
To get browsing to work you need to run nmbd as usual, but will need
|
||||
to use the "workgroup" option in smb.conf to control what workgroup
|
||||
Samba becomes a part of.
|
||||
|
||||
The -G option is most useful for simple setups where Samba is browsable
|
||||
in only one workgroup. In more complex cases the lmhosts file is
|
||||
better.
|
||||
|
||||
Be very careful setting up your lmhosts file. An incorrectly setup
|
||||
lmhosts file can have disasterous results for your net!
|
||||
|
||||
A simple lmhosts file might be:
|
||||
|
||||
# This is a simple lmhosts file
|
||||
#
|
||||
# This is a host alias. Anyone querying this name
|
||||
# will get the specified IP
|
||||
192.0.2.17 SMBDATA
|
||||
#
|
||||
# first put ourselves in workgroup MYGROUP using
|
||||
# our own net address
|
||||
0.0.0.0 MYGROUP G
|
||||
|
||||
Note in the above that I overrode what workgroup Samba is in using the
|
||||
G flag. Also note that the 0.0.0.0 address is used, which will be
|
||||
automatically replaced with the broadcast address for groups, and with
|
||||
the local IP address for other entries.
|
||||
|
||||
Samba also has a useful option for a Samba server to offer itself for
|
||||
browsing on another subnet.
|
||||
|
||||
This works by the lmhosts file specifying a broadcast address on the
|
||||
other network to use to find a browse master for the workgroup.
|
||||
|
||||
For example if you wanted yourself to appear in the workgroup STAFF on
|
||||
the network which has a broadcast of 192.0.3.255 then this entry would
|
||||
do the trick:
|
||||
|
||||
# put ourselves in the STAFF workgroup on the other subnet
|
||||
192.0.3.255 STAFF G
|
||||
|
||||
Notice the G at the end! It is very important you include this as this
|
||||
entry without the G could cause a broadcast storm!
|
||||
|
||||
If something doesn't work then hopefully the log.nmb file will
|
||||
help you track down the problem. Try a debug level of 2 or 3 for
|
||||
finding problems.
|
||||
|
||||
Note that if it doesn't work for you, then you should still be able to
|
||||
type the server name as \\SERVER in filemanager then hit enter and
|
||||
filemanager should display the list of available shares.
|
||||
|
||||
Some people find browsing fails because they don't have the global
|
||||
"guest account" set to a valid account. Remember that the IPC$
|
||||
connection that lists the shares is done as guest, and thus you must
|
||||
have a valid guest account.
|
||||
|
||||
Also, a lot of people are getting bitten by the problem of too many
|
||||
parameters on the command line of nmbd in inetd.conf. This trick is to
|
||||
not use spaces between the option and the parameter (eg: -d2 instead
|
||||
of -d 2), and to not use the -B and -N options. New versions of nmbd
|
||||
are now far more likely to correctly find your broadcast and network
|
||||
addess, so in most cases these aren't needed.
|
||||
|
||||
The other big problem people have is that their broadcast address,
|
||||
netmask or IP address is wrong (specified with the -B, -N and -I
|
||||
options to nmbd).
|
||||
|
||||
FORCING SAMBA TO BE THE MASTER
|
||||
==============================
|
||||
|
||||
Who becomes the "master browser" is determined by an election process
|
||||
using broadcasts. Each election packet contains a number of parameters
|
||||
which determine what precedence (bias) a host should have in the
|
||||
election. By default Samba uses a very low precedence and thus loses
|
||||
elections to just about anyone else.
|
||||
|
||||
If you want Samba to win elections then just set the "os level" global
|
||||
option in smb.conf to a higher number. It defaults to 0. Using 33
|
||||
would make it win all elections over every other system (except other
|
||||
samba systems!)
|
||||
|
||||
A "os level" of 2 would make it beat WfWg and Win95, but not NTAS. A
|
||||
NTAS domain controller uses level 32.
|
||||
|
||||
The maximum os level is 255
|
||||
|
||||
MAKING SAMBA THE DOMAIN MASTER
|
||||
==============================
|
||||
|
||||
The domain master is responsible for collating the browse lists of
|
||||
multiple subnets so that browsing can occur between subnets. You can
|
||||
make samba act as the domain master by setting "domain master = yes"
|
||||
in smb.conf. By default it will not be a domain master.
|
||||
|
||||
When samba is the domain master and the master browser it will listen
|
||||
for master announcements from other subnets and then contact them to
|
||||
synchronise browse lists.
|
||||
|
||||
If you want samba to be the domain master then I suggest you also set
|
||||
the "os level" high enough to make sure it wins elections.
|
||||
|
||||
NOTIFYING THE DOMAIN CONTROLLER
|
||||
===============================
|
||||
|
||||
If you have a domain controller for the domain which Samba is a part
|
||||
of then you should add the line "domain controller = address" to
|
||||
smb.conf. "address" can either be a name available via DNS or a IP
|
||||
address or a broadcast address. If it is a broadcast address then
|
||||
Samba will look for a domain controller on that network.
|
||||
|
||||
When Samba is the master browser it will regularly contact the domain
|
||||
controller to synchronise browse lists.
|
||||
|
||||
|
||||
NOTE ABOUT BROADCAST ADDRESSES
|
||||
==============================
|
||||
|
||||
If your network uses a "0" based broadcast address (for example if it
|
||||
ends in a 0) then you will strike problems. Windows for Workgroups
|
||||
does not seem to support a 0's broadcast and you will probably find
|
||||
that browsing and name lookups won't work.
|
||||
|
||||
You have a few options:
|
||||
|
||||
1) change to a 1's broadcast on your unix server. These often end in
|
||||
.255 (check with your local network guru for details)
|
||||
|
||||
2) set the nmbd broadcast to a 1's based address on the command line using
|
||||
the -B option. This only works if your network setup listens on both
|
||||
0s and 1s based broadcasts. The -B option can only control what
|
||||
address it sends to, not what it listens on.
|
||||
|
||||
|
123
docs/textdocs/BUGS.txt
Normal file
123
docs/textdocs/BUGS.txt
Normal file
@ -0,0 +1,123 @@
|
||||
This file describes how to report Samba bugs.
|
||||
|
||||
>> The email address for bug reports is samba-bugs@anu.edu.au <<
|
||||
|
||||
(NOTE: This mail may not be in place yet. If you have troubles with it
|
||||
then use samba-bugs@arvidsjaur.anu.edu.au)
|
||||
|
||||
|
||||
Please take the time to read this file before you submit a bug
|
||||
report. Also, please see if it has changed between releases, as I
|
||||
may be changing the bug reporting mechanism sometime soon.
|
||||
|
||||
Please also do as much as you can yourself to help track down the
|
||||
bug. I only develop Samba in my spare time and I receive far more mail
|
||||
about it than I can possibly answer, so you have a much higher chance
|
||||
of an answer and a fix if you send me a "developer friendly" bug
|
||||
report that lets me fix it fast.
|
||||
|
||||
Do not assume that if you post the bug to the comp.protocols.smb
|
||||
newsgroup that I will read it. I do read all postings to the samba
|
||||
mailing list (see the README). If you suspect that your problem is not
|
||||
a bug but a configuration problem then it is better to send it to the
|
||||
Samba mailing list, as there are (at last count) 1900 other users on
|
||||
that list that may be able to help you.
|
||||
|
||||
You may also like to look though the recent mailing list archives,
|
||||
which are conveniently accessible on the Samba web pages
|
||||
at http://lake.canberra.edu.au/pub/samba/
|
||||
|
||||
|
||||
GENERAL INFO
|
||||
------------
|
||||
|
||||
Before submitting a bug report check your config for silly
|
||||
errors. Look in your log files for obvious messages that tell you that
|
||||
you've misconfigured something and run testparm to test your config
|
||||
file for correct syntax.
|
||||
|
||||
If you include part of a log file with your bug report then be sure to
|
||||
annotate it with exactly what you were doing on the client at the
|
||||
time, and exactly what the results were.
|
||||
|
||||
|
||||
DEBUG LEVELS
|
||||
------------
|
||||
|
||||
If the bug has anything to do with Samba behaving incorrectly as a
|
||||
server (like refusing to open a file) then the log files will probably
|
||||
be very useful. Depending on the problem a log level of between 3 and
|
||||
10 showing the problem may be appropriate. A higher level givesmore
|
||||
detail, but may use too much disk space.
|
||||
|
||||
To set the debug level use "log level =" in your smb.conf. You may
|
||||
also find it useful to set the log level higher for just one machine
|
||||
and keep separate logs for each machine. To do this use:
|
||||
|
||||
log file = /usr/local/samba/lib/log.%m
|
||||
include = /usr/local/samba/lib/smb.conf.%m
|
||||
|
||||
then create a file "/usr/local/samba/lib/smb.conf.machine" where
|
||||
"machine" is the name of the client you wish to debug. In that file
|
||||
put any smb.conf commands you want, for example "log level=" may be
|
||||
useful. This also allows you to experiment with different security
|
||||
systems, protocol levels etc on just one machine.
|
||||
|
||||
|
||||
INTERNAL ERRORs
|
||||
---------------
|
||||
|
||||
If you get a "INTERNAL ERROR" message in your log files it means that
|
||||
Samba got an unexpected signal while running. It is probably a
|
||||
segmentation fault and almost certainly means a bug in Samba (unless
|
||||
you have faulty hardware or system software)
|
||||
|
||||
If the message came from smbd then it will probably be accompanied by
|
||||
a message which details the last SMB message received by smbd. This
|
||||
info is often very useful in tracking down the problem so please
|
||||
include it in your bug report.
|
||||
|
||||
You should also detail how to reproduce the problem, if
|
||||
possible. Please make this reasonably detailed.
|
||||
|
||||
You may also find that a core file appeared in a "corefiles"
|
||||
subdirectory of the directory where you keep your samba log
|
||||
files. This file is the most useful tool for tracking down the bug. To
|
||||
use it you do this:
|
||||
|
||||
gdb smbd core
|
||||
|
||||
adding appropriate paths to smbd and core so gdb can find them. If you
|
||||
don't have gdb then try "dbx". Then within the debugger use the
|
||||
command "where" to give a stack trace of where the problem
|
||||
occurred. Include this in your mail.
|
||||
|
||||
If you known any assembly language then do a "disass" of the routine
|
||||
where the problem occurred (if its in a library routine then
|
||||
disassemble the routine that called it) and try to work out exactly
|
||||
where the problem is by looking at the surrounding code. Even if you
|
||||
don't know assembly then incuding this info in the bug report can be
|
||||
useful.
|
||||
|
||||
|
||||
ATTACHING TO A RUNNING PROCESS
|
||||
------------------------------
|
||||
|
||||
Unfortunately some unixes (in particular some recent linux kernels)
|
||||
refuse to dump a core file if the task has changed uid (which smbd
|
||||
does often). To debug with this sort of system you could try to attach
|
||||
to the running process using "gdb smbd PID" where you get PID from
|
||||
smbstatus. Then use "c" to continue and try to cause the core dump
|
||||
using the client. The debugger should catch the fault and tell you
|
||||
where it occurred.
|
||||
|
||||
|
||||
PATCHES
|
||||
-------
|
||||
|
||||
The best sort of bug report is one that includes a fix! If you send me
|
||||
patches please use "diff -u" format if your version of diff supports
|
||||
it, otherwise use "diff -c4". Make sure your do the diff against a
|
||||
clean version of the source and let me know exactly what version you
|
||||
used.
|
||||
|
237
docs/textdocs/DIAGNOSIS.txt
Normal file
237
docs/textdocs/DIAGNOSIS.txt
Normal file
@ -0,0 +1,237 @@
|
||||
DIAGNOSING YOUR SAMBA SERVER
|
||||
============================
|
||||
|
||||
This file contains a list of tests you can perform to validate your
|
||||
Samba server. It also tells you what the likely cause of the problem
|
||||
is if it fails any one of these steps. If it passes all these tests
|
||||
then it is probably working fine.
|
||||
|
||||
You should do ALL the tests, in the order shown. I have tried to
|
||||
carefully choose them so later tests only use capabilities verified in
|
||||
the earlier tests.
|
||||
|
||||
I would welcome additions to this set of tests. Please mail them to
|
||||
samba-bugs@anu.edu.au
|
||||
|
||||
If you send me an email saying "it doesn't work" and you have not
|
||||
followed this test procedure then you should not be surprised if I
|
||||
ignore your email.
|
||||
|
||||
|
||||
ASSUMPTIONS
|
||||
-----------
|
||||
|
||||
In all of the tests I assume you have a Samba server called BIGSERVER
|
||||
and a PC called ACLIENT. I also assume the PC is running windows for
|
||||
workgroups with a recent copy of the microsoft tcp/ip stack. The
|
||||
procedure is similar for other types of clients.
|
||||
|
||||
I also assume you know the name of a available share in your
|
||||
smb.conf. I will assume this share is called "tmp". You can add a
|
||||
"tmp" share like by adding the following to smb.conf:
|
||||
|
||||
[tmp]
|
||||
comment = temporary files
|
||||
path = /tmp
|
||||
read only = yes
|
||||
|
||||
|
||||
THESE TESTS ASSUME VERSION 1.9.15 OR LATER OF THE SAMBA SUITE. SOME
|
||||
COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS
|
||||
|
||||
|
||||
TEST 1:
|
||||
-------
|
||||
|
||||
run the command "testparm". If it reports any errors then your
|
||||
smb.conf configuration file is faulty.
|
||||
|
||||
|
||||
TEST 2:
|
||||
-------
|
||||
|
||||
run the command "ping BIGSERVER" from the PC and "ping ACLIENT" from
|
||||
the unix box. If you don't get a valid response then your TCP/IP
|
||||
software is not correctly installed.
|
||||
|
||||
Note that you will need to start a "dos prompt" window on the PC to
|
||||
run ping.
|
||||
|
||||
If you get a message saying "host not found" or similar then your DNS
|
||||
software or /etc/hosts file is not correctly setup. It is possible to
|
||||
run samba without DNS entries for the server and client, but I assume
|
||||
you do have correct entries for the remainder of these tests.
|
||||
|
||||
|
||||
TEST 3:
|
||||
-------
|
||||
|
||||
run the command "smbclient -L BIGSERVER -U%" on the unix box. You
|
||||
should get a list of available shares back.
|
||||
|
||||
If you get a error message containing the string "Bad password" then
|
||||
you probably have either an incorrect "hosts allow", "hosts deny" or
|
||||
"valid users" line in your smb.conf, or your guest account is not
|
||||
valid. Check what your guest account is using "testparm" and
|
||||
temporarily remove any "hosts allow", "hosts deny", "valid users" or
|
||||
"invalid users" lines.
|
||||
|
||||
If you get a "connection refused" response then the smbd server could
|
||||
not be run. If you installed it in inetd.conf then you probably edited
|
||||
that file incorrectly. If you installed it as a daemon then check that
|
||||
it is running, and check that the netbios-ssn port is in a LISTEN
|
||||
state using "netstat -a".
|
||||
|
||||
If you get a "session request failed" then the server refused the
|
||||
connection. If it says "your server software is being unfriendly" then
|
||||
its probably because you have invalid command line parameters to smbd,
|
||||
or a similar fatal problem with the initial startup of smbd. Also
|
||||
check your config file for syntax errors with "testparm".
|
||||
|
||||
TEST 4:
|
||||
-------
|
||||
|
||||
run the command "nmblookup -B BIGSERVER __SAMBA__". You should get the
|
||||
IP address of your Samba server back.
|
||||
|
||||
If you don't then nmbd is incorrectly installed. Check your inetd.conf
|
||||
if yu run it from there, or that the daemon is running and listening
|
||||
to udp port 137.
|
||||
|
||||
One common problem is that many inetd implementations can't take many
|
||||
parameters on the command line. If this is the case then create a
|
||||
one-line script that contains the right parameters and run that from
|
||||
inetd.
|
||||
|
||||
TEST 5:
|
||||
-------
|
||||
|
||||
run the command "nmblookup -B ACLIENT '*'"
|
||||
|
||||
You should get the PCs IP address back. If you don't then the client
|
||||
software on the PC isn't installed correctly, or isn't started, or you
|
||||
got the name of the PC wrong. Note that you probably won't get a "node
|
||||
status response" from the PC due to a bug in the microsoft netbios
|
||||
nameserver implementation (it responds to the wrong port number).
|
||||
|
||||
TEST 6:
|
||||
-------
|
||||
|
||||
run the command "nmblookup -d 2 '*'"
|
||||
|
||||
This time we are trying the same as the previous test but are trying
|
||||
it via a broadcast to the default broadcast address. A number of
|
||||
Netbios/TCPIP hosts on the network should respond, although Samba may
|
||||
not catch all of the responses in the short time it listens. You
|
||||
should see "got a positive name query response" messages from several
|
||||
hosts.
|
||||
|
||||
If this doesn't give a similar result to the previous test then
|
||||
nmblookup isn't correctly getting your broadcast address through its
|
||||
automatic mechanism. In this case you should experiment with the -B
|
||||
option which allows you to manually specify the broadcast address,
|
||||
overriding the automatic detection. You should try different broadcast
|
||||
addresses until your find the one that works. It will most likely be
|
||||
something like a.b.c.255 as microsoft tcpip stacks only listen on 1's
|
||||
based broadcast addresses. If you get stuck then ask your local
|
||||
networking guru for help (and show them this paragraph).
|
||||
|
||||
If you find you do need the -B option (ie. the automatic detection
|
||||
doesn't work) then you should add the -B option with the right
|
||||
broadcast address for your network to the command line of nmbd in
|
||||
inetd.conf or in the script you use to start nmbd as a daemon. Once
|
||||
you do this go back to the "nmblookup __SAMBA__ -B BIGSERVER" test to
|
||||
make sure you have it running properly.
|
||||
|
||||
If your PC and server aren't on the same subnet then you will need to
|
||||
use the -B option to set the broadcast address to the that of the PCs
|
||||
subnet.
|
||||
|
||||
TEST 7:
|
||||
-------
|
||||
|
||||
run the command "smbclient '\\BIGSERVER\TMP'". You should then be
|
||||
prompted for a password. You should use the password of the account
|
||||
you are logged into the unix box with. If you want to test with
|
||||
another account then add the -U <accountname> option to the command
|
||||
line.
|
||||
|
||||
Once you enter the password you should get the "smb>" prompt. If you
|
||||
don't then look at the error message. If it says "invalid network
|
||||
name" then the service "tmp" is not correctly setup in your smb.conf.
|
||||
|
||||
If it says "bad password" then the likely causes are:
|
||||
|
||||
- you have shadow passords (or some other password system) but didn't
|
||||
compile in support for them in smbd
|
||||
- your "valid users" configuration is incorrect
|
||||
- you have a mixed case password and you haven't enabled the "password
|
||||
level" option at a high enough level
|
||||
- the "path =" line in smb.conf is incorrect. Check it with testparm
|
||||
|
||||
Once connected you should be able to use the commands "dir" "get"
|
||||
"put" etc. Type "help <command>" for instructions. You should
|
||||
especially check that the amount of free disk space shown is correct
|
||||
when you type "dir".
|
||||
|
||||
|
||||
TEST 8:
|
||||
-------
|
||||
|
||||
On the PC type the command "net view \\BIGSERVER". You will need to do
|
||||
this from within a "dos prompt" window. You should get back a list of
|
||||
available shares on the server.
|
||||
|
||||
If you get a "network name not found" or similar error then netbios
|
||||
name resolution is not working. This is usually caused by a problem in
|
||||
nmbd. To overcome it you could do one of the following (you only need
|
||||
to choose one of them):
|
||||
|
||||
- fixup the nmbd installation
|
||||
- add the IP address of BIGSERVER to the "wins server" box in the
|
||||
advanced tcp/ip setup on the PC.
|
||||
- enable windows name resolution via DNS in the advanced section of
|
||||
the tcp/ip setup
|
||||
- add BIGSERVER to your lmhosts file on the PC.
|
||||
|
||||
If you get a "invalid network name" or "bad password error" then the
|
||||
same fixes apply as they did for the "smbclient -L" test above. In
|
||||
particular, make sure your "hosts allow" line is correct (see the man
|
||||
pages)
|
||||
|
||||
|
||||
TEST 9:
|
||||
--------
|
||||
|
||||
run the command "net use x: \\BIGSERVER\TMP". You should be prompted
|
||||
for a password then you should get a "command completed successfully"
|
||||
message. If not then your PC software is incorrectly installed or your
|
||||
smb.conf is incorrect. make sure your "hosts allow" and other config
|
||||
lines in smb.conf are correct.
|
||||
|
||||
It's also possible that the server can't work out what user name to
|
||||
connect you as. To see if this is the problem add the line "user =
|
||||
USERNAME" to the [tmp] section of smb.conf where "USERNAME" is the
|
||||
username corresponding to the password you typed. If you find this
|
||||
fixes things you may need the username mapping option.
|
||||
|
||||
|
||||
TEST 10:
|
||||
--------
|
||||
|
||||
From file manager try to browse the server. Your samba server should
|
||||
appear in the browse list of your local workgroup (or the one you
|
||||
specified in the Makefile). You should be able to double click on the
|
||||
name of the server and get a list of shares. If you get a "invalid
|
||||
password" error when you do then you are probably running WinNT and it
|
||||
is refusing to browse a server that has no encrypted password
|
||||
capability and is in user level security mode.
|
||||
|
||||
|
||||
Still having troubles?
|
||||
----------------------
|
||||
|
||||
Try the mailing list or newsgroup, or use the tcpdump-smb utility to
|
||||
sniff the problem.
|
||||
|
||||
|
69
docs/textdocs/DNIX.txt
Normal file
69
docs/textdocs/DNIX.txt
Normal file
@ -0,0 +1,69 @@
|
||||
DNIX has a problem with seteuid() and setegid(). These routines are
|
||||
needed for Samba to work correctly, but they were left out of the DNIX
|
||||
C library for some reason.
|
||||
|
||||
For this reason Samba by default defines the macro NO_EID in the DNIX
|
||||
section of includes.h. This works around the problem in a limited way,
|
||||
but it is far from ideal, some things still won't work right.
|
||||
|
||||
To fix the problem properly you need to assemble the following two
|
||||
functions and then either add them to your C library or link them into
|
||||
Samba.
|
||||
|
||||
put this in the file setegid.s:
|
||||
|
||||
.globl _setegid
|
||||
_setegid:
|
||||
moveq #47,d0
|
||||
movl #100,a0
|
||||
moveq #1,d1
|
||||
movl 4(sp),a1
|
||||
trap #9
|
||||
bccs 1$
|
||||
jmp cerror
|
||||
1$:
|
||||
clrl d0
|
||||
rts
|
||||
|
||||
|
||||
put this in the file seteuid.s:
|
||||
|
||||
.globl _seteuid
|
||||
_seteuid:
|
||||
moveq #47,d0
|
||||
movl #100,a0
|
||||
moveq #0,d1
|
||||
movl 4(sp),a1
|
||||
trap #9
|
||||
bccs 1$
|
||||
jmp cerror
|
||||
1$:
|
||||
clrl d0
|
||||
rts
|
||||
|
||||
after creating the above files you then assemble them using
|
||||
|
||||
as seteuid.s
|
||||
as setegid.s
|
||||
|
||||
that should produce the files seteuid.o and setegid.o
|
||||
|
||||
then you need to add these to the LIBSM line in the DNIX section of
|
||||
the Samba Makefile. Your LIBSM line will then look something like this:
|
||||
|
||||
LIBSM = setegid.o seteuid.o -ln
|
||||
|
||||
You should then remove the line:
|
||||
|
||||
#define NO_EID
|
||||
|
||||
from the DNIX section of includes.h
|
||||
|
||||
Then recompile and try it out!
|
||||
|
||||
Note that this file was derived from an email from Peter Olsson
|
||||
<pol@leissner.se>. I don't have DNIX myself, so you're probably better
|
||||
off contacting Peter if you have problems.
|
||||
|
||||
Andrew
|
||||
|
68
docs/textdocs/DOMAIN.txt
Normal file
68
docs/textdocs/DOMAIN.txt
Normal file
@ -0,0 +1,68 @@
|
||||
Samba now supports domain logons and network logon scripts. The
|
||||
support is still experimental, but it seems to work.
|
||||
|
||||
The support is also not complete. Samba does not yet support the
|
||||
sharing of the SAM database with other systems yet, or remote
|
||||
administration. Support for these kind of things should be added
|
||||
sometime in the future.
|
||||
|
||||
The domain support only works for WfWg and Win95 clients. Support for
|
||||
NT and OS/2 clients is still being worked on.
|
||||
|
||||
Using these features you can make your clients verify their logon via
|
||||
the Samba server and make clients run a batch file when they logon to
|
||||
the network. The latter is particularly useful.
|
||||
|
||||
To use domain logons you need to do the following:
|
||||
|
||||
1) Setup nmbd and smbd and configure the smb.conf so that Samba is
|
||||
acting as the master browser. See INSTALL.txt and BROWSING.txt for
|
||||
details.
|
||||
|
||||
2) create a share called [netlogon] in your smb.conf. This share should
|
||||
be readable by all users, and probably should not be writeable. This
|
||||
share will hold your network logon scripts.
|
||||
|
||||
For example I have used:
|
||||
|
||||
[netlogon]
|
||||
path = /data/dos/netlogon
|
||||
writeable = no
|
||||
guest ok = yes
|
||||
|
||||
|
||||
3) in the [global] section of smb.conf set the following:
|
||||
|
||||
domain logons = yes
|
||||
logon script = %U.bat
|
||||
|
||||
the choice of batch file is, of course, up to you. The above would
|
||||
give each user a separate batch file as the %U will be changed to
|
||||
their username automatically. The other standard % macros may also be
|
||||
used. You can make the btch files come from a subdirectory by using
|
||||
soemthing like:
|
||||
|
||||
logon script = scripts\%U.bat
|
||||
|
||||
4) create the batch files to be run when the user logs in. If the batch
|
||||
file doesn't exist then no batch file will be run.
|
||||
|
||||
In the batch files you need to be careful to use DOS style cr/lf line
|
||||
endings. If you don't then DOS may get confused. I suggest you use a
|
||||
DOS editor to remotely edit the files if you don't know how to produce
|
||||
DOS style files under unix.
|
||||
|
||||
5) Use smbclient with the -U option for some users to make sure that
|
||||
the \\server\NETLOGON share is available, the batch files are visible
|
||||
and they are readable by the users.
|
||||
|
||||
6) you will probabaly find that your clients automatically mount the
|
||||
\\SERVER\NETLOGON share as drive z: while logging in. You can put some
|
||||
useful programs there to execute from the batch files.
|
||||
|
||||
|
||||
NOTE: You must be using "security = user" or "security = server" for
|
||||
domain logons to work correctly. Share level security won't work
|
||||
correctly.
|
||||
|
||||
|
333
docs/textdocs/ENCRYPTION.txt
Normal file
333
docs/textdocs/ENCRYPTION.txt
Normal file
@ -0,0 +1,333 @@
|
||||
LanManager / Samba Password Encryption.
|
||||
---------------------------------------
|
||||
|
||||
With the development of LanManager compatible password encryption for
|
||||
Samba, it is now able to validate user connections in exactly the same
|
||||
way as a LanManager or Windows NT server.
|
||||
|
||||
This document describes how the SMB password encryption algorithm
|
||||
works and what issues there are in choosing whether you want to use
|
||||
it. You should read it carefully, especially the part about security
|
||||
and the "PROS and CONS" section.
|
||||
|
||||
How does it work ?
|
||||
------------------
|
||||
|
||||
LanManager encryption is somewhat similar to UNIX password
|
||||
encryption. The server uses a file containing a hashed value of a
|
||||
users password. This is created by taking the users paintext
|
||||
password, capitalising it, and either truncating to 14 bytes (or
|
||||
padding to 14 bytes with null bytes). This 14 byte value is used as
|
||||
two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
|
||||
16 byte value which is stored by the server and client. Let this value
|
||||
be known as the *hashed password*.
|
||||
|
||||
When a client (LanManager, Windows for WorkGroups, Windows 95 or
|
||||
Windows NT) wishes to mount a Samba drive (or use a Samba resource) it
|
||||
first requests a connection and negotiates the protocol that the client
|
||||
and server will use. In the reply to this request the Samba server
|
||||
generates and appends an 8 byte, random value - this is stored in the
|
||||
Samba server after the reply is sent and is known as the *challenge*.
|
||||
|
||||
The challenge is different for every client connection.
|
||||
|
||||
The client then uses the hashed password (16 byte value described
|
||||
above), appended with 5 null bytes, as three 56 bit DES keys, each of
|
||||
which is used to encrypt the challenge 8 byte value, forming a 24 byte
|
||||
value known as the *response*.
|
||||
|
||||
In the SMB call SMBsessionsetupX (when user level security is
|
||||
selected) or the call SMBtconX (when share level security is selected)
|
||||
the 24 byte response is returned by the client to the Samba server.
|
||||
|
||||
The Samba server then reproduces the above calculation, using it's own
|
||||
stored value of the 16 byte hashed password (read from the smbpasswd
|
||||
file - described later) and the challenge value that it kept from the
|
||||
negotiate protocol reply. It then checks to see if the 24 byte value it
|
||||
calculates matches the 24 byte value returned to it from the client.
|
||||
|
||||
If these values match exactly, then the client knew the correct
|
||||
password (or the 16 byte hashed value - see security note below) and
|
||||
is this allowed access. If not then the client did not know the
|
||||
correct password and is denied access.
|
||||
|
||||
Note that the Samba server never knows or stores the cleartext of the
|
||||
users password - just the 16 byte hashed function derived from it. Also
|
||||
note that the cleartext password or 16 byte hashed value are never
|
||||
transmitted over the network - thus increasing security.
|
||||
|
||||
IMPORTANT NOTE ABOUT SECURITY
|
||||
-----------------------------
|
||||
|
||||
The unix and SMB password encryption techniques seem similar on the
|
||||
surface. This similarity is, however, only skin deep. The unix scheme
|
||||
typically sends clear text passwords over the nextwork when logging
|
||||
in. This is bad. The SMB encryption scheme never sends the cleartext
|
||||
password over the network but it does store the 16 byte hashed value
|
||||
on disk. This is also bad. Why? Because the 16 byte hashed value is a
|
||||
"password equivalent". You cannot derive the users password from it,
|
||||
but it could potentially be used in a modified client to gain access
|
||||
to a server. This would require considerable technical knowledge on
|
||||
behalf of the attacker but is perfectly possible. You should thus
|
||||
treat the smbpasswd file as though it contained the cleartext
|
||||
passwords of all your users. Its contents must be kept secret, and the
|
||||
file should be protected accordingly.
|
||||
|
||||
Ideally we would like a password scheme which neither requires plain
|
||||
text passwords on the net or on disk. Unfortunately this is not
|
||||
available as Samba is stuck with being compatible with other SMB
|
||||
systems (WinNT, WfWg, Win95 etc).
|
||||
|
||||
|
||||
PROS AND CONS
|
||||
-------------
|
||||
|
||||
There are advantages and disadvantages to both schemes.
|
||||
|
||||
Advantages of SMB Encryption:
|
||||
-----------------------------
|
||||
|
||||
- plain text passwords are not passed across the network. Someone using
|
||||
a network sniffer cannot just record passwords going to the SMB server.
|
||||
|
||||
- WinNT doesn't like talking to a server that isn't using SMB
|
||||
encrypted passwords. It will refuse to browse the server if the server
|
||||
is also in user level security mode. It will insist on promting the
|
||||
user for the password on each connection, which is very annoying. The
|
||||
only things you can do to stop this is to use SMB encryption.
|
||||
|
||||
Advantages of non-encrypted passwords:
|
||||
--------------------------------------
|
||||
|
||||
- plain text passwords are not kept on disk.
|
||||
|
||||
- uses same password file as other unix services such as login and
|
||||
ftp
|
||||
|
||||
- you are probably already using other services (such as telnet and
|
||||
ftp) which send plain text passwords over the net, so not sending them
|
||||
for SMB isn't such a big deal.
|
||||
|
||||
- the SMB encryption code in Samba is new and has only had limited
|
||||
testing. We have tried hard to make it secure but in any new
|
||||
implementation of a password scheme there is the possability of an
|
||||
error.
|
||||
|
||||
|
||||
The smbpasswd file.
|
||||
-------------------
|
||||
|
||||
In order for Samba to participate in the above protocol it must
|
||||
be able to look up the 16 byte hashed value given a user name.
|
||||
Unfortunately, as the UNIX password value is also a one way hash
|
||||
function (ie. it is impossible to retrieve the cleartext of the users
|
||||
password given the UNIX hash of it) then a separate password file
|
||||
containing this 16 byte value must be kept. To minimise problems with
|
||||
these two password files, getting out of sync, the UNIX /etc/passwd and
|
||||
the smbpasswd file, a utility, mksmbpasswd.sh, is provided to generate
|
||||
a smbpasswd file from a UNIX /etc/passwd file.
|
||||
|
||||
To generate the smbpasswd file from your /etc/passwd file use the
|
||||
following command :-
|
||||
|
||||
cat /etc/passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
|
||||
|
||||
If you are running on a system that uses NIS, use
|
||||
|
||||
ypcat passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
|
||||
|
||||
The mksmbpasswd.sh program is found in the Samba source directory. By
|
||||
default, the smbpasswd file is stored in :-
|
||||
|
||||
/usr/local/samba/private/smbpasswd
|
||||
|
||||
The owner of the /usr/local/samba/private directory should be set to
|
||||
root, and the permissions on it should be set to :-
|
||||
|
||||
r-x------
|
||||
|
||||
The command
|
||||
|
||||
chmod 500 /usr/local/samba/private
|
||||
|
||||
will do the trick. Likewise, the smbpasswd file inside the private
|
||||
directory should be owned by root and the permissions on is should be
|
||||
set to
|
||||
|
||||
rw-------
|
||||
|
||||
by the command :-
|
||||
|
||||
chmod 600 smbpasswd.
|
||||
|
||||
The format of the smbpasswd file is
|
||||
|
||||
username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Long name:user home dir:user shell
|
||||
|
||||
Although only the username, uid, and XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
sections are significant and are looked at in the Samba code.
|
||||
|
||||
It is *VITALLY* important that there by 32 'X' characters between the
|
||||
two ':' characters - the smbpasswd and Samba code will fail to validate
|
||||
any entries that do not have 32 characters between ':' characters.
|
||||
|
||||
When the password file is created all users have password entries
|
||||
consisting of 32 'X' characters. By default this disallows any access
|
||||
as this user. When a user has a password set, the 'X' characters change
|
||||
to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
|
||||
representation of the 16 byte hashed value of a users password.
|
||||
|
||||
To set a user to have no password (not recommended), edit the file
|
||||
using vi, and replace the first 11 characters with the asci text
|
||||
|
||||
NO PASSWORD
|
||||
|
||||
Eg. To clear the password for user bob, his smbpasswd file entry would
|
||||
look like :
|
||||
|
||||
bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:Bob's full name:/bobhome:/bobshell
|
||||
|
||||
If you are allowing users to use the smbpasswd command to set their own
|
||||
passwords, you may want to give users NO PASSWORD initially so they do
|
||||
not have to enter a previous password when changing to their new
|
||||
password (not recommended).
|
||||
|
||||
Note : This file should be protected very carefully. Anyone with
|
||||
access to this file can (with enough knowledge of the protocols) gain
|
||||
access to your SMB server. The file is thus more sensitive than a
|
||||
normal unix /etc/passwd file.
|
||||
|
||||
The smbpasswd Command.
|
||||
----------------------
|
||||
|
||||
The smbpasswd command maintains the 32 byte password field in
|
||||
the smbpasswd file. If you wish to make it similar to the unix passwd
|
||||
or yppasswd programs, install it in /usr/local/samba/bin (or your main
|
||||
Samba binary directory) and make it setuid root.
|
||||
|
||||
Note that if you do not do this then the root user will have to set all
|
||||
users passwords.
|
||||
|
||||
To set up smbpasswd as setuid root, change to the Samba binary install
|
||||
directory and then type (as root) :
|
||||
|
||||
chown root smbpasswd
|
||||
chmod 4555 smbpasswd
|
||||
|
||||
If smbpasswd is installed as setuid root then you would use it as
|
||||
follows.
|
||||
|
||||
smbpasswd
|
||||
Old SMB password: <type old alue here - just hit return if there is NO PASSWORD>
|
||||
New SMB Password: < type new value >
|
||||
Repeat New SMB Password: < re-type new value >
|
||||
|
||||
If the old value does not match the current value stored for that user,
|
||||
or the two new values do not match each other, then the password will
|
||||
not be changed.
|
||||
|
||||
If invoked by an ordinary user it will only allow the user to change
|
||||
his or her own Samba password.
|
||||
|
||||
If run by the root user smbpasswd may take an optional argument,
|
||||
specifying the user name whose SMB password you wish to change. Note
|
||||
that when run as root smbpasswd does not prompt for or check the old
|
||||
password value, thus allowing root to set passwords for users who have
|
||||
forgotten their passwords.
|
||||
|
||||
smbpasswd is designed to work in the same way and be familiar to UNIX
|
||||
users who use the passwd or yppasswd commands.
|
||||
|
||||
NOTE. As smbpasswd is designed to be installed as setuid root I would
|
||||
appreciate it if everyone examined the source code to look for
|
||||
potential security flaws. A setuid program, if not written properly can
|
||||
be an open door to a system cracker. Please help make this program
|
||||
secure by reporting all problems to me (the author, Jeremy Allison).
|
||||
|
||||
My email address is :-
|
||||
|
||||
jra@vantive.com
|
||||
|
||||
Setting up Samba to support LanManager Encryption.
|
||||
--------------------------------------------------
|
||||
|
||||
This is a very brief description on how to setup samba to support
|
||||
password encryption. More complete instructions will probably be added
|
||||
later.
|
||||
|
||||
1) get and compile the libdes libraries. the source is available from
|
||||
nimbus.anu.edu.au in pub/tridge/libdes/libdes.tar.92-10-13.gz
|
||||
|
||||
2) enable the encryption stuff in the Samba makefile, making sure you
|
||||
point it to the libdes library and include file (it needs des.h)
|
||||
The entries you need to uncomment are the four lines after the comment :-
|
||||
|
||||
# This is for SMB encrypted (lanman) passwords.
|
||||
|
||||
Note that you may have to change the variable DES_BASE to
|
||||
point at the place where you installed the DES library.
|
||||
|
||||
3) compile and install samba as usual
|
||||
|
||||
4) f your system can't compile the module getsmbpass.c then remove the
|
||||
-DSMBGETPASS define from the Makefile.
|
||||
|
||||
5) enable encrypted passwords in smb.conf by adding the line
|
||||
"encrypt passwords = yes" in the [global] section
|
||||
|
||||
6) create the initial smbpasswd password file in the place you
|
||||
specified in the Makefile. A simple way to do this based on your
|
||||
existing Makefile (assuming it is in a reasonably standard format) is
|
||||
like this:
|
||||
|
||||
cat /etc/passwd | mksmbpasswd.sh > /usr/local/samba/private/smbpasswd
|
||||
|
||||
Change ownership of private and smbpasswd to root.
|
||||
|
||||
chown -R root /usr/local/samba/private
|
||||
|
||||
Set the correct permissions on /usr/local/samba/private
|
||||
|
||||
chmod 500 /usr/local/samba/private
|
||||
|
||||
Set the correct permissions on /usr/local/samba/private/smbpasswd
|
||||
|
||||
chmod 600 /usr/local/samba/private/smbpasswd
|
||||
|
||||
note that the mksmbpasswd.sh script is in the samba source directory.
|
||||
|
||||
If this fails then you will find that you will need entries that look
|
||||
like this:
|
||||
|
||||
# SMB password file.
|
||||
tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
|
||||
|
||||
note that the uid and username fields must be right. Also, you must get
|
||||
the number of X's right (there should be 32).
|
||||
|
||||
If you wish, install the smbpasswd program as suid root.
|
||||
|
||||
chown root /usr/local/samba/bin/smbpasswd
|
||||
chmod 4555 /usr/local/samba/bin/smbpasswd
|
||||
|
||||
7) set the passwords for users using the smbpasswd command. For
|
||||
example, as root you could do "smbpasswd tridge"
|
||||
|
||||
8) try it out!
|
||||
|
||||
Note that you can test things using smbclient, as it also now supports
|
||||
encryption.
|
||||
|
||||
NOTE TO USA Sites that Mirror Samba
|
||||
-----------------------------------
|
||||
|
||||
The DES library is considered a munition in the USA. Under US Law it is
|
||||
illegal to export this software, or to put it in a freely available ftp
|
||||
site.
|
||||
|
||||
Please do not mirror the DES directory from the site on nimbus.anu.edu.au
|
||||
|
||||
Thank you,
|
||||
|
||||
Jeremy Allison.
|
||||
|
202
docs/textdocs/HINTS.txt
Normal file
202
docs/textdocs/HINTS.txt
Normal file
@ -0,0 +1,202 @@
|
||||
Here are some random hints that you may find useful. These really
|
||||
should be incorporated in the main docs someday.
|
||||
|
||||
|
||||
----------------------
|
||||
HINT: Always test your smb.conf with testparm before using it
|
||||
|
||||
If your smb.conf file is invalid then samba will fail to load. Run
|
||||
testparm over it before you install it just to make sure there aren't
|
||||
any basic syntax or logical errors.
|
||||
|
||||
|
||||
----------------------
|
||||
HINT: Try printing with smbclient first
|
||||
|
||||
If you have problems printing, test with smbclient first. Just connect using
|
||||
"smbclient '\\server\printer' -P" and use the "print" command.
|
||||
|
||||
Once this works, you know that Samba is setup correctly for printing,
|
||||
and you should be able to get it to work from your PCs.
|
||||
|
||||
This particularly helps in getting the "print command" right.
|
||||
|
||||
|
||||
----------------------
|
||||
HINT: Mount cdroms with conv=binary
|
||||
|
||||
Some OSes (notably Linux) default to auto detection of file type on
|
||||
cdroms and do cr/lf translation. This is a very bad idea when use with
|
||||
Samba. It causes all sorts of stuff ups.
|
||||
|
||||
To overcome this problem use conv=binary when mounting the cdrom
|
||||
before exporting it with Samba.
|
||||
|
||||
|
||||
----------------------
|
||||
HINT: Convert between unix and dos text formats
|
||||
|
||||
Jim barry has written an excellent drag-and-drop cr/lf converter for
|
||||
windows. Just drag your file onto the icon and it converts the file.
|
||||
|
||||
Get it from
|
||||
ftp://nimbus.anu.edu.au/pub/tridge/samba/contributed/fixcrlf.zip
|
||||
|
||||
----------------------
|
||||
HINT: Use the "username map" option
|
||||
|
||||
If the usernames used on your PCs don't match those used on the unix
|
||||
server then you will find the "username map" option useful.
|
||||
|
||||
-----------------------
|
||||
HINT: Use "security = user" in [global]
|
||||
|
||||
If you have the same usernames on the unix box and the PCs or have
|
||||
mapped them with the "username map" option then choose "security =
|
||||
user" in the [global] section of smb.conf.
|
||||
|
||||
This will mean your password is checked only when you first connect,
|
||||
and subsequent connections to printers, disks etc will go more
|
||||
smoothly and much faster.
|
||||
|
||||
The main problem with "security = user" if you use WfWg is that you
|
||||
will ONLY be able to connect as the username that you log into WfWg
|
||||
with. This is because WfWg silently ignores the password field in the
|
||||
connect drive dialog box if the server is in user security mode.
|
||||
|
||||
------------------------
|
||||
HINT: Make your printers not "guest ok"
|
||||
|
||||
If your printers are not "guest ok" and you are using "security =
|
||||
user" and have matching unix and PC usernames then you will attach to
|
||||
the printer without trouble as your own username. This will mean you
|
||||
will be able to delete print jobs (in 1.8.06 and above) and printer
|
||||
accounting will be possible.
|
||||
|
||||
|
||||
-----------------------
|
||||
HINT: Use a sensible "guest" account
|
||||
|
||||
Even if all your services are not available to "guest" you will need a
|
||||
guest account. This is because the browsing is done as guest. In many
|
||||
cases setting "guest account = ftp" will do the trick. Using the
|
||||
default guest account or "guest account = nobody" will give problems on
|
||||
many unixes. If in doubt create another account with minimal
|
||||
privilages and use it instead. Your users don't need to know the
|
||||
password of the guest account.
|
||||
|
||||
|
||||
-----------------------
|
||||
HINT: Use the latest TCP/IP stack from microsoft if you use Windows
|
||||
for workgroups.
|
||||
|
||||
The early TCP/IP stacks had lots of bugs.
|
||||
|
||||
Microsoft has released an incremental upgrade to their TCP/IP 32-Bit
|
||||
VxD drivers. The latest release can be found on their ftp site at
|
||||
ftp.microsoft.com, located in /peropsys/windows/public/tcpip/wfwt32.exe.
|
||||
There is an update.txt file there that describes the problems that were
|
||||
fixed. New files include WINSOCK.DLL, TELNET.EXE, WSOCK.386, VNBT.386,
|
||||
WSTCP.386, TRACERT.EXE, NETSTAT.EXE, and NBTSTAT.EXE.
|
||||
|
||||
|
||||
-----------------------
|
||||
HINT: nmbd can act as a "WINS" server
|
||||
|
||||
By default SMB clients use broadcasts to find shares. Recent clients
|
||||
(such as WfWg) can use a "wins" server instead, whcih reduces your
|
||||
broadcast traffic and allows you to find names across routers.
|
||||
|
||||
Just point your WfWg, Win95 and NT clients at the Samba box in the WINS option.
|
||||
|
||||
Note: nmbd does not support all WINS operations. Anyone out there have
|
||||
a spec they could send me?
|
||||
|
||||
-----------------------
|
||||
HINT: you may need to delete your .pwl files when you change password.
|
||||
|
||||
WfWg does a lousy job with passwords. I find that if I change my
|
||||
password on either the unix box or the PC the safest thing to do is to
|
||||
delete the .pwl files in the windows directory. The PC will complain about not finding the files, but will soon get over it, allowing you to enter the new password.
|
||||
|
||||
If you don't do this you may find that WfWg remembers and uses the old
|
||||
password, even if you told it a new one.
|
||||
|
||||
Often WfWg will totally ignore a password you give it in a dialog box.
|
||||
|
||||
----------------------
|
||||
HINT: Using MS Access
|
||||
|
||||
Here are some notes on running MS-Access on a Samba drive from Stefan
|
||||
Kjellberg <stefank@esi.com.au>
|
||||
|
||||
1. Opening a database in 'exclusive' mode does NOT work. Samba ignores
|
||||
r/w/share modes on file open.
|
||||
|
||||
2. Make sure that you open the database as 'shared' and to 'lock modified
|
||||
records'
|
||||
|
||||
3. Of course locking must be enabled for the particular share (smb.conf)
|
||||
|
||||
|
||||
---------------------
|
||||
HINT: password cacheing in WfWg
|
||||
|
||||
Here is a hint from michael@ecel.uwa.edu.au (Michael Simmons):
|
||||
|
||||
In case people where not aware. There is a program call admincfg.exe
|
||||
on the last disk (disk 8) of the WFW 3.11 disk set. To install it
|
||||
type EXPAND A:\ADMINCFG.EX_ C:\WINDOWS\ADMINCFG.EXE Then add an icon
|
||||
for it via the "Progam Manager" "New" Menu. This program allows you
|
||||
to control how WFW handles passwords. ie disable Password Caching etc
|
||||
for use with "security = user"
|
||||
|
||||
|
||||
--------------------
|
||||
HINT: file descriptor limits
|
||||
|
||||
If you have problems with the limits on the number of open files you
|
||||
can edit local.h to fix it.
|
||||
|
||||
--------------------
|
||||
HINT: HPUX initgroups() problem
|
||||
|
||||
here is a hint from Frank Wales [frank@arcglade.demon.co.uk]:
|
||||
|
||||
HP's implementation of supplementary groups is, er, non-standard (for
|
||||
hysterical reasons). There are two group files, /etc/group and
|
||||
/etc/logingroup; the system maps UIDs to numbers using the former, but
|
||||
initgroups() reads the latter. Most system admins who know the ropes
|
||||
symlink /etc/group to /etc/logingroup (hard link doesn't work for reasons
|
||||
too stupid to go into here). initgroups() will complain if one of the
|
||||
groups you're in in /etc/logingroup has what it considers to be an invalid
|
||||
ID, which means outside the range [0..UID_MAX], where UID_MAX is (I think)
|
||||
60000 currently on HP-UX. This precludes -2 and 65534, the usual 'nobody'
|
||||
GIDs.
|
||||
|
||||
Perhaps you could suggest to users that, if they encounter this problem,
|
||||
they make sure that the programs that are failing to initgroups() be
|
||||
run as users not in any groups with GIDs outside the allowed range.
|
||||
|
||||
This is documented in the HP manual pages under setgroups(2) and passwd(4).
|
||||
|
||||
|
||||
---------------------
|
||||
HINT: Patch your SCO system
|
||||
|
||||
If you run SCO Unix then you may need to get important TCP/IP patches
|
||||
for Samba to work correctly. Try
|
||||
|
||||
Paul_Davis@mindlink.bc.ca writes:
|
||||
|
||||
I was having problems with Accpac using 1.9.02 on SCO Unix. One
|
||||
posting function reported corrupted data. After installing uod385a,
|
||||
the problem went away (a restore from backup and then another
|
||||
run-thru).
|
||||
|
||||
It appears that the uod385a update for SCO may be fairly important for
|
||||
a lot of different DOS and Windows software under Samba.
|
||||
|
||||
uod385a can be found at ftp.sco.com /SLS/uod385a.Z and uod385a.ltr.Z.
|
||||
|
||||
|
27
docs/textdocs/INSTALL.sambatar
Normal file
27
docs/textdocs/INSTALL.sambatar
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
Please see the readme and the man page for general info.
|
||||
|
||||
1) Follow the samba installation instructions.
|
||||
|
||||
2) If all goes well, test it out by creating a share on your PC (called
|
||||
backup for example) then doing something like,
|
||||
|
||||
./smbtar -s mypc -t /dev/rmt/0ubn -x backup
|
||||
|
||||
substituting whatever your tape drive is for the -t option, or set your
|
||||
tape environmental variable.
|
||||
|
||||
If all does not go well, feel free to mail the author (poultenr@logica.co.uk)
|
||||
about bug reports / help / money / pizza / etc.
|
||||
|
||||
3) Read the man page and the NOTES file for more information
|
||||
|
||||
4) Work smbtar into your usual nightly backup scheme (presuming you
|
||||
have one :-}).
|
||||
|
||||
|
||||
NOTE:
|
||||
|
||||
If you have problems with smbtar then it's probably best to contact the
|
||||
author Ricky Poulten (poultenr@logica.co.uk).
|
||||
|
96
docs/textdocs/PROJECTS
Normal file
96
docs/textdocs/PROJECTS
Normal file
@ -0,0 +1,96 @@
|
||||
Samba Projects Directory
|
||||
========================
|
||||
|
||||
|
||||
>>>>> NOTE: THIS FILE IS NOW VERY OUT OF DATE <<<<<
|
||||
|
||||
|
||||
This is a list of who's working on what in Samba. It's not guaranteed
|
||||
to be uptodate or accurate but I hope it will help us getting
|
||||
coordinated.
|
||||
|
||||
If you are working on something to do with Samba and you aren't here
|
||||
then please let me know! Also, if you are listed below and you have
|
||||
any corrections or updates then please let me know.
|
||||
|
||||
Email contact:
|
||||
samba-bugs@anu.edu.au
|
||||
|
||||
========================================================================
|
||||
Documentation and FAQ
|
||||
|
||||
Docs and FAQ files for the Samba suite of software.
|
||||
|
||||
Contact Karl.Auer@anu.edu.au
|
||||
|
||||
Mark Preston is now working on a set of formatted docs for Samba.
|
||||
Contact mpreston@sghms.ac.uk
|
||||
|
||||
Docs are currently up to date with version, 1.7.07. FAQ being added to
|
||||
as questions arise.
|
||||
|
||||
Status last updated 27th September 1994
|
||||
========================================================================
|
||||
|
||||
========================================================================
|
||||
Netbeui support
|
||||
|
||||
This aims to produce patches so that Samba can be used with clients
|
||||
that do not have TCP/IP. It will try to remain as portable as possible.
|
||||
|
||||
Contact Brian.Onn@Canada.Sun.COM (Brian Onn)
|
||||
|
||||
The project is just startup up.
|
||||
|
||||
Status last updated 4th October 1994
|
||||
========================================================================
|
||||
|
||||
========================================================================
|
||||
Smbfs
|
||||
|
||||
A mountable smb filesystem for Linux using the userfs userspace filesystem
|
||||
|
||||
Contact lendecke@namu01.gwdg.de (Volker Lendecke)
|
||||
|
||||
Currently this is at version 0.2. It works but is really only for
|
||||
people with some knowledge and experience of Linux kernel hacking.
|
||||
|
||||
Status last updated 23rd August 1994
|
||||
========================================================================
|
||||
|
||||
========================================================================
|
||||
Nmbd
|
||||
|
||||
Aims to produce a complete rfc1001/1002 implementation. The current
|
||||
nmbd is a partial implementation.
|
||||
|
||||
Contact Fabrice Cetre (cetre@ifhpserv.insa-lyon.fr)
|
||||
|
||||
Status last updated 23rd August 1994
|
||||
========================================================================
|
||||
|
||||
========================================================================
|
||||
Admin Tool
|
||||
|
||||
Aims to produce a nice smb.conf editor and other useful tools for
|
||||
administering a Samba system.
|
||||
|
||||
Contact: Steve Brown (steve@unicorn.dungeon.com)
|
||||
|
||||
In the design phase.
|
||||
|
||||
Status last updated 4th September 1994
|
||||
========================================================================
|
||||
|
||||
|
||||
========================================================================
|
||||
Lanman Client.
|
||||
|
||||
Contact: john@amanda.xs4all.nl (John Stewart)
|
||||
|
||||
Aims to produce a reliable LANMAN Client implementation for LINUX,
|
||||
and possibly other variations of UNIX. Project ably started by
|
||||
Tor Lillqvist; tml@hemuli.tte.vtt.fi
|
||||
|
||||
Status last updated 17th January 1995
|
||||
========================================================================
|
42
docs/textdocs/Passwords.txt
Normal file
42
docs/textdocs/Passwords.txt
Normal file
@ -0,0 +1,42 @@
|
||||
NOTE ABOUT PASSWORDS
|
||||
====================
|
||||
|
||||
Unix systems use a wide variety of methods for checking the validity
|
||||
of a password. This is primarily controlled with the Makefile defines
|
||||
mentioned in the Makefile.
|
||||
|
||||
Also note that some clients (notably WfWg) uppercase the password
|
||||
before sending it. The server tries the password as it receives it and
|
||||
also after lowercasing it.
|
||||
|
||||
The Samba server can also be configured to try different
|
||||
upper/lowercase combinations. This is controlled by the [global]
|
||||
parameter "password level". A level of N means to try all combinations
|
||||
up to N uppercase characters in the password. A high value can chew a
|
||||
fair bit of CPU time and can lower the security of your system. Do not
|
||||
use this options unless you really need it - the time taken for
|
||||
password checking can become so high that clients time out.
|
||||
|
||||
If you do use the "password level" option then you might like to use
|
||||
-DUFC_CRYPT in your Makefile. On some machine this makes password
|
||||
checking _much_ faster. This is also useful if you use the @group
|
||||
syntax in the user= option.
|
||||
|
||||
If your site uses AFS (the Andrew File System), you can use the AFS section
|
||||
in the Makefile. This will first attempt to authenticate a username and
|
||||
password to AFS. If that succeeds, then the associated AFS rights will be
|
||||
granted. Otherwise, the password checking routine falls back to whatever
|
||||
Unix password checking method you are using. Note that the AFS code is
|
||||
only written and tested for AFS 3.3 and later.
|
||||
|
||||
|
||||
SECURITY = SERVER
|
||||
=================
|
||||
|
||||
Samba can use a remote server to do it's username/password
|
||||
validation. This allows you to have one central machine (for example a
|
||||
NT box) control the passwords for the Unix box.
|
||||
|
||||
See the section on "security =" in smb.conf(5) for details.
|
||||
|
||||
|
79
docs/textdocs/README.DCEDFS
Normal file
79
docs/textdocs/README.DCEDFS
Normal file
@ -0,0 +1,79 @@
|
||||
=============================================================================
|
||||
|
||||
Basic DCE/DFS Support for SAMBA 1.9.13
|
||||
|
||||
Jim Doyle <doyle@oec.com> 06-02-95
|
||||
|
||||
=============================================================================
|
||||
|
||||
Functionality:
|
||||
--------------
|
||||
|
||||
Per-instance authentication for DCE/DFS.
|
||||
|
||||
Missing Functionality in this Implementation:
|
||||
---------------------------------------------
|
||||
|
||||
* No automatic refresh of credentials
|
||||
|
||||
To do so would not be that hard.. One could simply
|
||||
stash the clear-text key in memory, spawn a key management
|
||||
thread to wake up right before credentials expire and
|
||||
refresh the login context.
|
||||
|
||||
* No UNIX Signals support (SIGCLD, SIGPIPE, SIGHUP, SIGBUS, SIGSEGV)
|
||||
|
||||
|
||||
There is no support for signal processing in Samba daemons
|
||||
that need to authenticate with DCE. The explanation for this
|
||||
is that the smbd is linked against thread-safe libraries in
|
||||
order to be able to use DCE authentication mechanisms.
|
||||
Because smbd uses signal() and fork(), it represents the
|
||||
worst case scenario for DCE portability. In order
|
||||
to properly support signals in a forked server environment,
|
||||
some rework of smbd is needed in order to properly
|
||||
construct, shutdown and reconstruct asynchronous signal
|
||||
handling threads and synchronous signal traps across the
|
||||
parent and child. I have not had contiguous time to work
|
||||
on it, I expect it to be a weeks worth of work to cleanly
|
||||
integrate thread-safe signal handing into the code and
|
||||
test it. Until I can get to this task, I will leave it up
|
||||
to someone adventurous enough to engineer it and negotiate
|
||||
with Andrew to integrate the changes into the mainline branch.
|
||||
|
||||
The lack of full signal support means that you cannot
|
||||
rely upon SIGHUP-ing the parent daemon to refresh
|
||||
the configuration data. Likewise, you cannot take advantage
|
||||
of the builtin SIGBUS/SIGSEGV traps to diagnose failures.
|
||||
You will have to halt Samba in order to make changes
|
||||
and then have them take effect.
|
||||
|
||||
The SMBD server as it stands is suitable to use if you
|
||||
already have experience with configuring and running
|
||||
SAMBA.
|
||||
|
||||
Tested Platforms:
|
||||
-----------------
|
||||
|
||||
HP-UX 9.05 / HP-UX DCE 1.2.1
|
||||
AIX 3.2.5 / AIX DCE/6000 1.3
|
||||
DEC OSF-1 3.0 / DEC DCE 1.3
|
||||
|
||||
Building:
|
||||
---------
|
||||
|
||||
- Uncomment the the appropriate block in the Makefile
|
||||
for the platform you wish to build on.
|
||||
|
||||
- Samples of Samba server configuration files for our
|
||||
DFS environment are included in samples.dcedfs/
|
||||
|
||||
|
||||
|
||||
Bugs, Suggestions, etc..
|
||||
--------------------------
|
||||
|
||||
Please post them to the mailing list.
|
||||
That way I will see them and they will become part of
|
||||
the archives so others can share the knowledge.
|
||||
|
124
docs/textdocs/README.jis
Normal file
124
docs/textdocs/README.jis
Normal file
@ -0,0 +1,124 @@
|
||||
$B!|(B samba $BF|K\8lBP1~$K$D$$$F(B
|
||||
|
||||
1. $BL\E*(B
|
||||
|
||||
$BF|K\8lBP1~$O!"(B
|
||||
|
||||
(1) MS-Windows $B>e$G!"4A;z%U%!%$%kL>$r$I$&$7$F$b07$&I,MW$N$"$k%"%W%j%1!<%7%g%s$,$A$c(B
|
||||
$B$s$HF0:n$9$k!#Nc$($P!"(BMS-WORD 5 $B$J$I$O!"%$%s%9%H!<%k;~$K4A;z$N%U%!%$%kL>$r>!<j(B
|
||||
$B$K$D$1$F$7$^$$$^$9!#$3$&$$$C$?>l9g$K$A$c$s$HBP1~$G$-$k$h$&$K$9$k!#(B
|
||||
|
||||
(2) UNIX $B$O!":G6a$G$O$[$H$s$I$N$b$N$,(B 8 bits $B$N%U%!%$%kL>$r%5%]!<%H$7$F$$$^$9$,!"(B
|
||||
$BCf$K$O!"$3$l$r%5%]!<%H$7$F$$$J$$$b$N$b$"$j$^$9!#$3$N$h$&$J>l9g$G$b!"(B(1)$B$NL\E*(B
|
||||
$B$,K~B-$G$-$k$h$&$K$9$k!#(B
|
||||
|
||||
$B$rL\E*$H$7$F$$$^$9!#$=$N$?$a!"F|K\8lBP1~$O!"I,MW:G>.8B$7$+9T$J$C$F$*$j$^$;$s!#(B
|
||||
|
||||
2. $BMxMQJ}K!(B
|
||||
|
||||
(1) $BDI2C$7$?%Q%i%a!<%?(B
|
||||
|
||||
smb.conf $B%U%!%$%k$N(B global $B%;%/%7%g%s$K0J2<$N%Q%i%a!<%?$r@_Dj$G$-$k$h$&$K$7$^$7$?!#(B
|
||||
|
||||
[global]
|
||||
....
|
||||
coding system = <$B%3!<%I7O(B>
|
||||
|
||||
$B$3$3$G;XDj$5$l$?%3!<%I7O$,(B UNIX $B>e$N%U%!%$%k%7%9%F%`$N%U%!%$%kL>$N%3!<%I$K$J$j$^$9!#(B
|
||||
$B@_Dj$G$-$k$b$N$O!"<!$N$h$&$K$J$C$F$$$^$9!#(B
|
||||
|
||||
sjis: SHIFT JIS (MS $B4A;z%3!<%I(B)
|
||||
euc: EUC $B%3!<%I(B
|
||||
hex: 7 bits $B$N(B ASCII $B%3!<%I0J30$N%3!<%I$r0J2<$N7A<0$GI=$9J}<0$G$9!#Nc$($P!"(B
|
||||
'$B%*%U%#%9(B' $B$H$$$&L>A0$O!"(B':83:49:83:74:83:42:83:58' $B$N$h$&$K!"(B':' $B$N8e$K#27e(B
|
||||
$B$N(B16$B?J?t$rB3$1$k7A<0$K$J$j$^$9!#(B
|
||||
$B$3$3$G!"(B':' $B$rB>$NJ8;z$KJQ99$7$?$$>l9g$O!"(Bhex $B$N8e$m$K$=$NJ8;z$r;XDj$7$^$9!#(B
|
||||
$BNc$($P!"(B@$B$rJQ$o$j$K;H$$$?$$>l9g$O!"(B'hex@'$B$N$h$&$K;XDj$7$^$9!#(B
|
||||
JIS $B%3!<%I$K$D$$$F$O!"0J2<$NI=$r;2>H$7$F2<$5$$!#(B
|
||||
$B(#(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(!(!(!(!(!($(B
|
||||
$B(";XDj(B $B("4A;z3+;O("4A;z=*N;("%+%J3+;O("%+%J=*N;("1Q?t3+;O("Hw9M(B $B("(B
|
||||
$B('(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(!(!(!(!(!()(B
|
||||
$B("(Bjis7 $B("(B\E$B $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(Bjis 7$BC10LId9f(B $B("(B
|
||||
$B("(Bjunet $B("(B\E$B $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(B7bits $B%3!<%I(B $B("(B
|
||||
$B("(Bjis8 $B("(B\E$B $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(Bjis 8$BC10LId9f(B $B("(B
|
||||
$B("(Bj7bb $B("(B\E$B $B("(B\E(B $B("(B0x0e $B("(B0x0f $B("(B\E(B $B("(B $B("(B
|
||||
$B("(Bj7bj $B("(B\E$B $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(Bjis7$B$HF1$8(B $B("(B
|
||||
$B("(Bj7bh $B("(B\E$B $B("(B\E(H $B("(B0x0e $B("(B0x0f $B("(B\E(H $B("(B $B("(B
|
||||
$B("(Bj7@b $B("(B\E$@ $B("(B\E(B $B("(B0x0e $B("(B0x0f $B("(B\E(B $B("(B $B("(B
|
||||
$B("(Bj7@j $B("(B\E$@ $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(B $B("(B
|
||||
$B("(Bj7@h $B("(B\E$@ $B("(B\E(H $B("(B0x0e $B("(B0x0f $B("(B\E(H $B("(B $B("(B
|
||||
$B("(Bj8bb $B("(B\E$B $B("(B\E(B $B("(B-- $B("(B-- $B("(B\E(B $B("(B $B("(B
|
||||
$B("(Bj8bj $B("(B\E$B $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(Bjis8$B$HF1$8(B $B("(B
|
||||
$B("(Bj8bh $B("(B\E$B $B("(B\E(H $B("(B-- $B("(B-- $B("(B\E(H $B("(B $B("(B
|
||||
$B("(Bj8@b $B("(B\E@@ $B("(B\E(B $B("(B-- $B("(B-- $B("(B\E(B $B("(B $B("(B
|
||||
$B("(Bj8@j $B("(B\E$@ $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(B $B("(B
|
||||
$B("(Bj8@h $B("(B\E$@ $B("(B\E(H $B("(B-- $B("(B-- $B("(B\E(H $B("(B $B("(B
|
||||
$B("(Bjubb $B("(B\E$B $B("(B\E(B $B("(B\E(I $B("(B\E(B $B("(B\E(B $B("(B $B("(B
|
||||
$B("(Bjubj $B("(B\E$B $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(Bjunet$B$HF1$8(B $B("(B
|
||||
$B("(Bjubh $B("(B\E$B $B("(B\E(H $B("(B\E(I $B("(B\E(H $B("(B\E(H $B("(B $B("(B
|
||||
$B("(Bju@b $B("(B\E$@ $B("(B\E(B $B("(B\E(I $B("(B\E(B $B("(B\E(B $B("(B $B("(B
|
||||
$B("(Bju@j $B("(B\E$@ $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(B $B("(B
|
||||
$B("(Bju@h $B("(B\E$@ $B("(B\E(H $B("(B\E(I $B("(B\E(H $B("(B\E(H $B("(B $B("(B
|
||||
$B(&(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(!(!(!(!(!(%(B
|
||||
|
||||
$B$$$:$l$N>l9g$b!"$9$G$KB8:_$7$F$$$kL>A0$KBP$7$F$O!"4A;z$N3+;O=*N;%7!<%1%s%9$O!"0J2<(B
|
||||
$B$N$b$N$rG'<1$7$^$9!#(B
|
||||
$B4A;z$N;O$^$j(B: \E$B $B$+(B \E$@
|
||||
$B4A;z$N=*$j(B: \E(J $B$+(B \E(B $B$+(B \E(H
|
||||
|
||||
(2) smbclient $B$N%*%W%7%g%s(B
|
||||
|
||||
$B%/%i%$%"%s%H%W%m%0%i%`$G$b!"4A;z$d2>L>$r4^$s$@%U%!%$%k$r07$($k$h$&$K!"<!$N%*%W%7%g%s(B
|
||||
$B$rDI2C$7$^$7$?!#(B
|
||||
|
||||
-t <$B%?!<%_%J%k%3!<%I7O(B>
|
||||
|
||||
$B$3$3$G!"(B<$B%?!<%_%J%k%3!<%I7O(B>$B$K;XDj$G$-$k$b$N$O!">e$N(B<$B%3!<%I7O(B>$B$HF1$8$b$N$G$9!#(B
|
||||
|
||||
(3) $B%G%U%)%k%H(B
|
||||
|
||||
$B%G%U%)%k%H$N%3!<%I7O$O!"%3%s%Q%$%k;~$K7h$^$j$^$9!#(B
|
||||
|
||||
3. $B%3%s%Q%$%k;~$N@_Dj(B
|
||||
|
||||
Makefile $B$K@_Dj$9$k9`L\$r0J2<$K<($7$^$9!#(B
|
||||
|
||||
(1) KANJI $B%U%i%0(B
|
||||
|
||||
$B%3%s%Q%$%k%*%W%7%g%s$K(B -DKANJI=\"$B%3!<%I7O(B\" $B$r;XDj$7$^$9!#$3$N%3!<%I7O$O(B 2. $B$G;X(B
|
||||
$BDj$9$k$b$N$HF1$8$G$9!#Nc$($P!"(B-DKANJI=\"euc\" $B$r(BFLAGSM $B$K@_Dj$9$k$H(B UNIX $B>e$N%U%!(B
|
||||
$B%$%kL>$O!"(BEUC $B%3!<%I$K$J$j$^$9!#$3$3$G;XDj$7$?%3!<%I7O$O!"%5!<%P5Z$S%/%i%$%"%s%H(B
|
||||
$B%W%m%0%i%`$N%G%U%)%k%H$KCM$J$j$^$9!#(B
|
||||
|
||||
3. $B@)8B;v9`(B
|
||||
|
||||
(1) $B4A;z%3!<%I(B
|
||||
smbd $B$rF0:n$5$;$k%[%9%H$N(B UNIX $B$,%5%]!<%H$7$F$$$J$$4A;z%3!<%I$O!"MxMQ$G$-$J$$$3$H$,(B
|
||||
$B$"$j$^$9!#JQ$JF0:n$r$9$k$h$&$J$i(B hex $B$N;XDj$r$9$k$N$,NI$$$G$7$g$&!#(B
|
||||
|
||||
(2) smbclient $B%3%^%s%I(B
|
||||
$B%7%U%H%3!<%I$J$I$N4X78$G!"4A;z$d2>L>$r4^$s$@%U%!%$%kL>$N(B ls $B$NI=<($,Mp$l$k$3$H$,$"$j(B
|
||||
$B$^$9!#(B
|
||||
|
||||
(3) $B%o%$%k%I%+!<%I$K$D$$$F(B
|
||||
$B$A$c$s$H$7$?%9%Z%C%/$,$h$/$o$+$i$J$+$C$?$N$G$9$,!"0l1~!"(BDOS/V $B$NF0:n$HF1$8F0:n$r9T$J(B
|
||||
$B$&$h$&$K$J$C$F$$$^$9!#(B
|
||||
|
||||
4. $B>c32Ey$N%l%]!<%H$K$D$$$F(B
|
||||
|
||||
$BF|K\8l$N%U%!%$%kL>$K4X$7$F!"J8;z2=$1Ey$N>c32$,$"$l$P!";d$K%l%]!<%H$7$FD:$1$l$P9,$$$G(B
|
||||
$B$9!#$?$@$7!"%*%j%8%J%k$+$i$NLdBjE@$d<ALd$K$D$$$F$O!"%*%j%8%J%k$N:n<T$XD>@\Ld$$9g$o$;$k(B
|
||||
$B$+!"$b$7$/$O%a!<%j%s%0%j%9%H$J$I$X%l%]!<%H$9$k$h$&$K$7$F2<$5$$!#(B
|
||||
|
||||
5. $B$=$NB>(B
|
||||
|
||||
hex $B7A<0$NJQ49J}K!$O!"(B
|
||||
|
||||
$BBgLZ!wBgDM!&C^GH(B <ohki@gssm.otsuka.tsukuba.ac.jp>$B;a(B
|
||||
|
||||
$B$,:n$i$l$?%3!<%I$rMxMQ$7$F$$$^$9!#(B
|
||||
|
||||
1994$BG/(B10$B7n(B28$BF|(B $BBh#1HG(B
|
||||
1995$BG/(B 8$B7n(B16$BF|(B $BBh#2HG(B
|
||||
$BF#ED(B $B?r(B fujita@ainix.isac.co.jp
|
||||
|
15
docs/textdocs/README.sambatar
Normal file
15
docs/textdocs/README.sambatar
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
This is version 1.4 of my small extension to samba that allows PC shares
|
||||
to be backed up directly to a UNIX tape. It only has been tested under
|
||||
Solaris 2.3, Linux 1.1.59 and DG/UX 5.4r3.10 with version 1.9.13 of samba.
|
||||
|
||||
See the file INSTALL for installation instructions, and
|
||||
the man page and NOTES file for some basic usage. Please let me know if you
|
||||
have any problems getting it to work under your flavour of Unix.
|
||||
|
||||
This is only (yet another) intermediate version of sambatar.
|
||||
This version also comes with an extra gift, zen.bas, written in
|
||||
microsoft qbasic by a colleague. It is (apparently) based on a 70s
|
||||
British sci-fi series known as Blake's 7. If you have any questions
|
||||
about this program, or any suggestions (e.g. what about servillan.bas
|
||||
?), feel free to mail the author (of zen.bas) greenm@lilhd.logica.com.
|
12
docs/textdocs/SCO.txt
Normal file
12
docs/textdocs/SCO.txt
Normal file
@ -0,0 +1,12 @@
|
||||
There is an annoying TCPIP bug in SCO Unix. This causes orruption when
|
||||
transferring files with Samba.
|
||||
|
||||
Geza Makay (makayg@math.u-szeged.hu) sends this information:
|
||||
|
||||
The patch you need is UOD385 Connection Drivers SLS. It is available from
|
||||
SCO (ftp.sco.com, directory SLS, files uod385a.Z and uod385a.ltr.Z).
|
||||
|
||||
You do not need anything else but the above patch. It installs in seconds,
|
||||
and corrected the Excel problem. We also had some other minor problems (not
|
||||
only with Samba) that disappeared by installing this patch.
|
||||
|
40
docs/textdocs/SMBTAR.notes
Normal file
40
docs/textdocs/SMBTAR.notes
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
Intro
|
||||
-----
|
||||
|
||||
sambatar is just a small extension to the smbclient program distributed with
|
||||
samba. A basic front end shell script, smbtar, is provided as an interface
|
||||
to the smbclient extensions.
|
||||
|
||||
Extensions
|
||||
----------
|
||||
|
||||
This release adds the following extensions to smbclient,
|
||||
|
||||
tar [c|x] filename
|
||||
creates or restores from a tar file. The tar file may be a tape
|
||||
or a unix tar file. tar's behaviour is modified with the newer and tarmode
|
||||
commands.
|
||||
|
||||
tarmode [full|inc|reset|noreset]
|
||||
With no arguments, tarmode prints the current tar mode (by default full,
|
||||
noreset). In full mode, every file is backed up during a tar command.
|
||||
In incremental, only files with the dos archive bit set are backed up.
|
||||
The archive bit is reset if in reset mode, or left untouched if in noreset.
|
||||
In reset mode, the share has to be writable, which makes sambatar even
|
||||
less secure. An alternative might be to use tarmode inc noreset which
|
||||
would implement an "expanding incremental" backup (which some may prefer
|
||||
anyway).
|
||||
|
||||
setmode <setmode string> filename
|
||||
This is a "freebie" - nothing really to do with sambatar. This
|
||||
is a crude attrib like command (only the other way around). Setmode string
|
||||
is a combination of +-rhsa. So for example -rh would reset the read only
|
||||
bit on filename.
|
||||
|
||||
newer filename
|
||||
This is in fact part of the 1.9.13 samba distribution, but comes
|
||||
into its own with sambatar. This causes tar (or get, mget, etc) to
|
||||
only copy files newer than the specified file name. Could be used
|
||||
against the previous nights (or whatever) log file to implement incremental
|
||||
backups.
|
272
docs/textdocs/Speed.txt
Normal file
272
docs/textdocs/Speed.txt
Normal file
@ -0,0 +1,272 @@
|
||||
This file tries to outline the ways to improve the speed of a Samba server.
|
||||
|
||||
Andrew Tridgell
|
||||
January 1995
|
||||
|
||||
|
||||
COMPARISONS
|
||||
-----------
|
||||
|
||||
The Samba server uses TCP to talk to the client. Thus if you are
|
||||
trying to see if it performs well you should really compare it to
|
||||
programs that use the same protocol. The most readily available
|
||||
programs for file transfer that use TCP are ftp or another TCP based
|
||||
SMB server.
|
||||
|
||||
If you want to test against something like a NT or WfWg server then
|
||||
you will have to disable all but TCP on either the client or
|
||||
server. Otherwise you may well be using a totally different protocol
|
||||
(such as Netbeui) and comparisons may not be valid.
|
||||
|
||||
Generally you should find that Samba performs similarly to ftp at raw
|
||||
transfer speed. It should perform quite a bit faster than NFS,
|
||||
although this very much depends on your system.
|
||||
|
||||
Several people have done comparisons between Samba and Novell, NFS or
|
||||
WinNT. In some cases Samba performed the best, in others the worst. I
|
||||
suspect the biggest factor is not Samba vs some other system but the
|
||||
hardware and drivers used on the various systems. Given similar
|
||||
hardware Samba should certainly be competitive in speed with other
|
||||
systems.
|
||||
|
||||
|
||||
SOCKET OPTIONS
|
||||
--------------
|
||||
|
||||
There are a number of socket options that can greatly affect the
|
||||
performance of a TCP based server like Samba.
|
||||
|
||||
The socket options that Samba uses are settable both on the command
|
||||
line with the -O option, or in the smb.conf file.
|
||||
|
||||
The "socket options" section of the smb.conf manual page describes how
|
||||
to set these and gives recommendations.
|
||||
|
||||
Getting the socket options right can make a big difference to your
|
||||
performance, but getting them wrong can degrade it by just as
|
||||
much. The correct settings are very dependent on your local network.
|
||||
|
||||
The socket option TCP_NODELAY is the one that seems to make the
|
||||
biggest single difference for most networks. Many people report that
|
||||
adding "socket options = TCP_NODELAY" doubles the read performance of
|
||||
a Samba drive. The best explanation I have seen for this is that the
|
||||
Microsoft TCP/IP stack is slow in sending tcp ACKs.
|
||||
|
||||
|
||||
READ SIZE
|
||||
---------
|
||||
|
||||
The option "read size" affects the overlap of disk reads/writes with
|
||||
network reads/writes. If the amount of data being transferred in
|
||||
several of the SMB commands (currently SMBwrite, SMBwriteX and
|
||||
SMBreadbraw) is larger than this value then the server begins writing
|
||||
the data before it has received the whole packet from the network, or
|
||||
in the case of SMBreadbraw, it begins writing to the network before
|
||||
all the data has been read from disk.
|
||||
|
||||
This overlapping works best when the speeds of disk and network access
|
||||
are similar, having very little effect when the speed of one is much
|
||||
greater than the other.
|
||||
|
||||
The default value is 16384, but very little experimentation has been
|
||||
done yet to determine the optimal value, and it is likely that the best
|
||||
value will vary greatly between systems anyway. A value over 65536 is
|
||||
pointless and will cause you to allocate memory unnecessarily.
|
||||
|
||||
|
||||
MAX XMIT
|
||||
--------
|
||||
|
||||
At startup the client and server negotiate a "maximum transmit" size,
|
||||
which limits the size of nearly all SMB commands. You can set the
|
||||
maximum size that Samba will negotiate using the "max xmit = " option
|
||||
in smb.conf.
|
||||
|
||||
It defaults to 65536 bytes (the maximum), but it is possible that some
|
||||
clients may perform better with a smaller transmit unit. Trying values
|
||||
of less than 2048 is likely to cause severe problems.
|
||||
|
||||
In most cases the default is the best option.
|
||||
|
||||
|
||||
LOCKING
|
||||
-------
|
||||
|
||||
By default Samba does not implement strict locking on each read/write
|
||||
call (although it did in previous versions). If you enable strict
|
||||
locking (using "strict locking = yes") then you may find that you
|
||||
suffer a severe performance hit on some systems.
|
||||
|
||||
The performance hit will probably be greater on NFS mounted
|
||||
filesystems, but could be quite high even on local disks.
|
||||
|
||||
|
||||
SHARE MODES
|
||||
-----------
|
||||
|
||||
Some people find that opening files is very slow. This is often
|
||||
because of the "share modes" code needed to fully implement the dos
|
||||
share modes stuff. You can disable this code using "share modes =
|
||||
no". This will gain you a lot in opening and closing files but will
|
||||
mean that (in some cases) the system won't force a second user of a
|
||||
file to open the file read-only if the first has it open
|
||||
read-write. For many applications that do their own locking this
|
||||
doesn't matter, but for some it may.
|
||||
|
||||
LOG LEVEL
|
||||
---------
|
||||
|
||||
If you set the log level (also known as "debug level") higher than 2
|
||||
then you may suffer a large drop in performance. This is because the
|
||||
server flushes the log file after each operation, which can be very
|
||||
expensive.
|
||||
|
||||
|
||||
WIDE LINKS
|
||||
----------
|
||||
|
||||
The "wide links" option is now enabled by default, but if you disable
|
||||
it (for better security) then you may suffer a performance hit in
|
||||
resolving filenames. The performance loss is lessened if you have
|
||||
"getwd cache = yes", which is now the default.
|
||||
|
||||
|
||||
READ RAW
|
||||
--------
|
||||
|
||||
The "read raw" operation is designed to be an optimised, low-latency
|
||||
file read operation. A server may choose to not support it,
|
||||
however. and Samba makes support for "read raw" optional, with it
|
||||
being enabled by default.
|
||||
|
||||
In some cases clients don't handle "read raw" very well and actually
|
||||
get lower performance using it than they get using the conventional
|
||||
read operations.
|
||||
|
||||
So you might like to try "read raw = no" and see what happens on your
|
||||
network. It might lower, raise or not affect your performance. Only
|
||||
testing can really tell.
|
||||
|
||||
|
||||
WRITE RAW
|
||||
---------
|
||||
|
||||
The "write raw" operation is designed to be an optimised, low-latency
|
||||
file write operation. A server may choose to not support it,
|
||||
however. and Samba makes support for "write raw" optional, with it
|
||||
being enabled by default.
|
||||
|
||||
Some machines may find "write raw" slower than normal write, in which
|
||||
case you may wish to change this option.
|
||||
|
||||
READ PREDICTION
|
||||
---------------
|
||||
|
||||
Samba can do read prediction on some of the SMB commands. Read
|
||||
prediction means that Samba reads some extra data on the last file it
|
||||
read while waiting for the next SMB command to arrive. It can then
|
||||
respond more quickly when the next read request arrives.
|
||||
|
||||
This is disabled by default. You can enable it by using "read
|
||||
prediction = yes".
|
||||
|
||||
Note that read prediction is only used on files that were opened read
|
||||
only.
|
||||
|
||||
Read prediction should particularly help for those silly clients (such
|
||||
as "Write" under NT) which do lots of very small reads on a file.
|
||||
|
||||
Samba will not read ahead more data than the amount specified in the
|
||||
"read size" option. It always reads ahead on 1k block boundaries.
|
||||
|
||||
|
||||
MEMORY MAPPING
|
||||
--------------
|
||||
|
||||
Samba supports reading files via memory mapping them. One some
|
||||
machines this can give a large boost to performance, on others it
|
||||
makes not difference at all, and on some it may reduce performance.
|
||||
|
||||
To enable you you have to recompile Samba with the -DUSE_MMAP=1 option
|
||||
on the FLAGS line of the Makefile.
|
||||
|
||||
Note that memory mapping is only used on files opened read only, and
|
||||
is not used by the "read raw" operation. Thus you may find memory
|
||||
mapping is more effective if you disable "read raw" using "read raw =
|
||||
no".
|
||||
|
||||
|
||||
SLOW CLIENTS
|
||||
------------
|
||||
|
||||
One person has reported that setting the protocol to COREPLUS rather
|
||||
than LANMAN2 gave a dramatic speed improvement (from 10k/s to 150k/s).
|
||||
|
||||
I suspect that his PC's (386sx16 based) were asking for more data than
|
||||
they could chew. I suspect a similar speed could be had by setting
|
||||
"read raw = no" and "max xmit = 2048", instead of changing the
|
||||
protocol. Lowering the "read size" might also help.
|
||||
|
||||
|
||||
SLOW LOGINS
|
||||
-----------
|
||||
|
||||
Slow logins are almost always due to the password checking time. Using
|
||||
the lowest practical "password level" will improve things a lot. You
|
||||
could also enable the "UFC crypt" option in the Makefile.
|
||||
|
||||
CLIENT TUNING
|
||||
-------------
|
||||
|
||||
Often a speed problem can be traced to the client. The client (for
|
||||
example Windows for Workgroups) can often be tuned for better TCP
|
||||
performance.
|
||||
|
||||
See your client docs for details. In particular, I have heard rumours
|
||||
that the WfWg options TCPWINDOWSIZE and TCPSEGMENTSIZE can have a
|
||||
large impact on performance.
|
||||
|
||||
Also note that some people have found that setting DefaultRcvWindow in
|
||||
the [MSTCP] section of the SYSTEM.INI file under WfWg to 3072 gives a
|
||||
big improvement. I don't know why.
|
||||
|
||||
My own experience wth DefaultRcvWindow is that I get much better
|
||||
performance with a large value (16384 or larger). Other people have
|
||||
reported that anything over 3072 slows things down enourmously. One
|
||||
person even reported a speed drop of a factor of 30 when he went from
|
||||
3072 to 8192. I don't know why.
|
||||
|
||||
It probably depends a lot on your hardware, and the type of unix box
|
||||
you have at the other end of the link.
|
||||
|
||||
MY RESULTS
|
||||
----------
|
||||
|
||||
Some people want to see real numbers in a document like this, so here
|
||||
they are. I have a 486sx33 client running WfWg 3.11 with the 3.11b
|
||||
tcp/ip stack. It has a slow IDE drive and 20Mb of ram. It has a SMC
|
||||
Elite-16 ISA bus ethernet card. The only WfWg tuning I've done is to
|
||||
set DefaultRcvWindow in the [MSTCP] section of system.ini to 16384. My
|
||||
server is a 486dx3-66 running Linux. It also has 20Mb of ram and a SMC
|
||||
Elite-16 card. You can see my server config in the examples/tridge/
|
||||
subdirectory of the distribution.
|
||||
|
||||
I get 490k/s on reading a 8Mb file with copy.
|
||||
I get 441k/s writing the same file to the samba server.
|
||||
|
||||
Of course, there's a lot more to benchmarks than 2 raw throughput
|
||||
figures, but it gives you a ballpark figure.
|
||||
|
||||
I've also tested Win95 and WinNT, and found WinNT gave me the best
|
||||
speed as a samba client. The fastest client of all (for me) is
|
||||
smbclient running on another linux box. Maybe I'll add those results
|
||||
here someday ...
|
||||
|
||||
|
||||
COMMENTS
|
||||
--------
|
||||
|
||||
If you've read this far then please give me some feedback! Which of
|
||||
the above suggestions worked for you?
|
||||
|
||||
Mail the samba mailing list or samba-bugs@anu.edu.au
|
376
docs/textdocs/Support.txt
Normal file
376
docs/textdocs/Support.txt
Normal file
@ -0,0 +1,376 @@
|
||||
The Samba Consultants List
|
||||
==========================
|
||||
|
||||
This is a list of people who are prepared to install and support Samba.
|
||||
Note that in most countries nobody should admit to "supplying" Samba, since
|
||||
there is then an implied warranty with possibly onerous legal obligations.
|
||||
Just downloading and installing it isn't supply in this sense, but advertising
|
||||
"run our Samba for best results" may be so.
|
||||
|
||||
Being on this list does not imply any sort of endorsement by anyone, it is just
|
||||
provided in the hope that it will be useful.
|
||||
|
||||
If you want to be added to the list, or want your entry modified then
|
||||
contact the address below. They are currently listed in the
|
||||
order that they were received. If it gets too big we may organise it
|
||||
by region. Please make sure to include a header line giving the region
|
||||
and country, eg CANBERRA - AUSTRALIA.
|
||||
|
||||
You can contact the maintainers at samba-bugs@anu.edu.au
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
BRISBANE - AUSTRALIA
|
||||
|
||||
Brett Worth
|
||||
Select Computer Technology - Brisbane
|
||||
431 Logan Road
|
||||
Stones Corner QLD 4120
|
||||
E-Mail: brett@sct.com.au
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
CANBERRA - AUSTRALIA
|
||||
|
||||
Paul Blackman (ictinus@lake.canberra.edu.au, Ph. 06 2012518) is
|
||||
available for consultation. Paul's Samba background is with
|
||||
Solaris 2.3/4 and WFWG/Win95 machines. Paul is also the maintainer
|
||||
of the SAMBA Web Pages.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
READING - ENGLAND
|
||||
|
||||
Philip Hands | E-Mail: info@hands.com
|
||||
Philip Hands Computing Ltd. | Tel: +44 1734 476287 Fax: 1734 474655
|
||||
Unit 1, Cherry Close, Caversham, Reading RG4 8UP UK
|
||||
|
||||
Samba experience: SVR4,SVR3.2 & Linux <--> WfWg, W3.1, OS2 and MS-LanMan
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
ILLONOIS - USA
|
||||
|
||||
Information One, Inc.
|
||||
736 Hinman Ave, Suite 2W
|
||||
Evanston, IL 60202
|
||||
708-328-9137 708-328-0117 FAX
|
||||
info@info1.com
|
||||
|
||||
Providing custom Internet and networking solutions.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Olympic Peninsula Consulting; 1241 Lansing Ave W., Bremerton, WA 98312-4343
|
||||
telephone 1+ 360 792 6938; mailto:opc@aa.net; http://www.aa.net/~opc;
|
||||
Unix Systems and TCP/IP Network design, programming, and administration.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
SolutionS R Us has been in business for 3+ years providing viable 3rd
|
||||
party support in system/network administration. With our own Linux
|
||||
distribution which we're constantly improving to make it the best and
|
||||
using it to provide total solutions for companies which are open to
|
||||
using Linux.
|
||||
|
||||
Mauro DePalma <mauro@sru.com>
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
BIELEFELD - GERMANY
|
||||
|
||||
I am located in Bielefeld/Germany and have been doing Unix consultancy
|
||||
work for the past 8 years throughout Germany and the rest of Europe. I
|
||||
can be contacted by email at <jpm@mens.de> or via phone at +49 521
|
||||
9225922 or telefax at +49 521 9225924.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
CANBERRA - AUSTRALIA
|
||||
|
||||
Ben Elliston
|
||||
Faculty of Information Sciences and Engineering
|
||||
University of Canberra AUSTRALIA
|
||||
E-mail: ben@ise.canberra.edu.au (Uni)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
PALERMO - ITALY
|
||||
|
||||
Francesco Cardinale
|
||||
E-Mail: cardinal@palermo.italtel.it
|
||||
Samba experience: SVR3.2, SOLARIS, ULTRIX, LINUX <--> DOS LAN-MAN, WFW
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
SYDNEY - AUSTRALIA
|
||||
|
||||
John Terpstra - Aquasoft (jht@aquasoft.com.au)
|
||||
Business: +612 524 4040
|
||||
Home: +612 540 3154
|
||||
Shoephone: +612 414 334422 (aka 0414 334422)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
ONTARIO - CANADA
|
||||
|
||||
Strata Software Limited, Kanata Ontario CANADA
|
||||
Tel: +1 (613) 591-1922 Fax: +1 (613) 591-3485
|
||||
Email: sales@strataware.com WWW: http://www.strataware.com/
|
||||
|
||||
Strata Software Limited is a software development and consulting group
|
||||
specializing in data communications (TCP/IP and OSI), X.400, X.500 and
|
||||
LDAP, and X.509-based security. We have Samba experience with Windows NT,
|
||||
Windows 95, and Windows for Workgroups clients with Linux, Unixware
|
||||
(SVR4), and HP-UX servers.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
SYDNEY - AUSTRALIA
|
||||
|
||||
We are a Unix & Windows developer with a consulting & support component.
|
||||
In business since 1981 with experience on Sun, hp, sgi, IBM rs6000 plus
|
||||
Windows, NT and Win95, Using Samba since September 94.
|
||||
CodeSmiths, 22 Darley Road, MANLY 2095 NSW; 977 1979; fax: 977 2116
|
||||
philm@esi.com.au (Australia; New South Wales; SYDNEY; North East)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
EDINBUGH - SCOTLAND
|
||||
|
||||
Charlie Hussey email charlie@edina.demon.co.uk
|
||||
Edina Software Limited tel 0131 657 1129
|
||||
4 James Street fax 0131 669 9092
|
||||
Edinburgh EH15 2DS
|
||||
|
||||
SAMBA experience: SCO UNIX <=> WfWg
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
LONDON - ENGLAND
|
||||
|
||||
Mark H. Preston,
|
||||
Network Analyst, | Email : mpreston@sghms.ac.uk
|
||||
Computer Unit, | Tel : +44 (0)181 725-5434
|
||||
St. George's Hospital Med School, | Fax : +44 (0)181 725-3583
|
||||
London SW17 ORE. | WWW : http://www.sghms.ac.uk
|
||||
|
||||
Samba Experience:
|
||||
Server: Solaris 2.3 & 2.4, Irix 5.2 & 5.3
|
||||
Client: WinNT, Win95, WfWg, Win3.1, Ms-LanMan, DHCP support
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
SYDNEY - AUSTRALIA
|
||||
|
||||
Pacific ESI has used and installed Samba since 1.6 on a range
|
||||
of machines running SunOS, BSD/OS, SCO/UNIX, HP/UX, and Solaris,
|
||||
and WfWG and Windows95. The largest system worked on to date
|
||||
involved an Australia wide network of machines with PCs and SUNs
|
||||
at the various nodes. The in-house testing site is a wide area
|
||||
network with three sites, remotely connected with PPP and with
|
||||
SUN servers at each site to all of which are connected several
|
||||
PCs running mainly WfWG.
|
||||
|
||||
Stefan Kjellberg Pacific Engineering Systems
|
||||
International
|
||||
info@eram.esi.com.au Voice:+61-2-9063377
|
||||
... Fax:+61-2-9063468
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
CHANTILLY - USA
|
||||
|
||||
Intelligent Decisions, Inc.
|
||||
ATTN: Richard Bullington
|
||||
14121 Parke Long Ct. #104
|
||||
Chantilly, VA 22021
|
||||
U.S.A.
|
||||
(703) 803-8070
|
||||
rbullington@intdec.com
|
||||
|
||||
Samba experience: Linux, DEC ULTRIX <=> WFWG 3.11, Windows NT 3.5
|
||||
Specializing in World Wide Web related UNIX-to-PC connectivity.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
FORT COLLINS, CO - USA
|
||||
|
||||
Granite Computing Solutions
|
||||
ATTN: Brian Grossman
|
||||
Box 270103
|
||||
Fort Collins, CO 80527-0103
|
||||
U.S.A.
|
||||
(970) 225-2370
|
||||
granite@fortnet.org
|
||||
|
||||
Information services, including WfWG, NT, Apple <=> Unix interoperability.
|
||||
|
||||
Our standard advertisement says:
|
||||
|
||||
> Unix workstations, servers and custom systems <
|
||||
>> WWW and Unix education <<
|
||||
>>> Enterprise and departmental computing solutions <<<
|
||||
>>> Backup & restore <<<
|
||||
>> Software forensics <<
|
||||
> Data translation <
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------
|
||||
Adelaide, Australia
|
||||
|
||||
NS Computer Software and Services P/L
|
||||
PO Box 86
|
||||
Ingle Farm
|
||||
SA 5098
|
||||
|
||||
Contact: Richard Sharpe
|
||||
Ph: +61-8-281-0063 (08-281-0063) AH
|
||||
FAX:+61-8-250-2080 (08-250-2080)
|
||||
|
||||
Experience with: ULTRIX, Digital UNIX, SunOS, WfW 3.11, Win95, WNT 3.51
|
||||
|
||||
----------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------
|
||||
TECTONIC LIMITED
|
||||
WESTWOOD
|
||||
78 LOUGHBOROUGH ROAD
|
||||
QUORN
|
||||
LEICESTERSHIRE
|
||||
LE12 8DX
|
||||
|
||||
TELEPHONE 01509-620922
|
||||
FAX 01509-620933
|
||||
|
||||
CONTACT DAVID ROBINSON
|
||||
|
||||
WE ARE UNIX ORIENTATED BUT ALSO SPECIALISE IN PC TO UNIX COMMUNICATIONS, WE
|
||||
KNOW AND UNDERSTAND PC-NFS, (HENCE OUR INTEREST IN SAMBA).
|
||||
WE SUPPORT SUNOS, SOLARIS 1.X AND 2.X, HP-UX 9.0 AND 10.0, OSF (or DEC UNIX,
|
||||
whichever you prefer), WinNT, WfWG and Win95.
|
||||
|
||||
WE ARE ALREADY TALKING TO A COUPLE OF VERY LARGE SAMBA USERS HERE IN THE UK.
|
||||
WE WOULD LIKE TO SUPPORT THEM (AND MANY MORE), WOULD YOU PLEASE CONTACT ME ON:
|
||||
david@tectonic.demon.co.uk
|
||||
----------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------
|
||||
MIAMI, FL - USA
|
||||
|
||||
Swaney & Associates, Inc.
|
||||
ATTN: Stephen Swaney
|
||||
2543 Lincoln Avenue
|
||||
Miami, Florida 33133
|
||||
U.S.A
|
||||
(305) 860-0570
|
||||
|
||||
Specializing in:
|
||||
High Availability system & networks
|
||||
UNIX to PC connectivity
|
||||
Market Data systems
|
||||
Messaging Systems (Sendmail & Microsoft Exchange)
|
||||
----------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
NEW JERSEY - USA
|
||||
|
||||
William J. Maggio
|
||||
LAN & Computer Integrators, Inc.
|
||||
242 Old New Brunswick Road Email: bmaggio@lci.com
|
||||
Suite 440 Voice: 908-981-1991
|
||||
Piscataway, NJ 08855 Fax : 908-981-1858
|
||||
|
||||
Specializing in Internet connectivity and security, Sun integration and
|
||||
high speed, enterprise network design and deployment.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
FAREHAM - ENGLAND
|
||||
|
||||
High Field Technology Ltd
|
||||
Little Park Farm Road, Segensworth West,
|
||||
Fareham, Hants PO15 5SJ, UK.
|
||||
sales@hft.co.uk tel +44 148 957 0111 fax +44 148 957 0555
|
||||
|
||||
Company skills: Real time hardware and software systems
|
||||
|
||||
Samba experience: BSD/OS, Linux, LynxOS <==> WFWG, NT
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
QUEBEC - CANADA
|
||||
|
||||
Dataden Computer Systems
|
||||
Attn: Danny Arseneau
|
||||
arseneau@parkmed.com
|
||||
895 2nd Avenue
|
||||
Ile Bizard, Quebec
|
||||
Canada, H9C 1K3
|
||||
Tel: (514)891-2293
|
||||
Fax: (514)696-0848
|
||||
|
||||
Dataden is company that specializes in Unix--TCP/IP networking.
|
||||
We have over 15 years of experience. We have been installing,
|
||||
configuring and maintaining Samba for clients for 1-1/2 years now. We
|
||||
have samba installations on Linx, SunOS and DEC OSF. Our biggest site
|
||||
has 4 Suns and 3 Linux servers running Samba which are serving a network
|
||||
of about 50 PC's running WFWg and Win95.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
CALIFORNIA - USA
|
||||
|
||||
Ron Halstead
|
||||
Open Systems Consulting
|
||||
3098-4 Lakemont Drive
|
||||
San Ramon, CA 94583 (San Francisco Bay Area)
|
||||
(510) 735-7529
|
||||
halstead@ix.netcom.com
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
MELBOURNE - AUSTRALIA
|
||||
|
||||
Michael Ciavarella
|
||||
Cybersoruce Pty Ltd.
|
||||
8/140 Queen Street
|
||||
Melbourne VIC 3000
|
||||
Phone: +61-3-9642-5997
|
||||
Fax: +61-3-9642-5998
|
||||
Email: mikec@cyber.com.au
|
||||
WWW: http://www.cyber.com.au
|
||||
|
||||
Cybersource specialises in TCP/IP network integration and Open Systems
|
||||
administration. Cybersource is an Australian-owned and operated
|
||||
company, with clients including some of Australia's largest financial,
|
||||
petrochemical and state government organisations.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
SOUTHERN CALIFORNIA - USA
|
||||
|
||||
Michael St. Laurent
|
||||
Serving Los Angeles and Orange Counties. Please contact via email.
|
||||
rowl@earthlink.net
|
||||
Michael St. Laurent
|
||||
Hartwell Corporation
|
||||
------------------------------------------------------------------------------
|
||||
WASHINGTON DC METRO - USA
|
||||
|
||||
Asset Software, Inc. has been running Samba since the 1.6 release on various
|
||||
platforms, including SunOS 4.x, Solaris 2.x, IRIX 4.x and 5.x, Linux 1.1x,
|
||||
1.2x, and 1.3x, and BSD UNIX 4.3 and above. We specialize in small office
|
||||
network solutions and provide services to enhance a small office's
|
||||
operations. Primarily a custom software operation, our vast knowledge of
|
||||
Windows, DOS, Unix, Windows NT, MacOS, and OS/2 enable us to provide quality
|
||||
technical assistance to the small office environment at a reasonable price.
|
||||
Our upcoming multi-mailbox mail client, IQ Mail, enables users with more
|
||||
than one mailbox to send and retrieve their mail from a single, consistent
|
||||
mail client running in Windows.
|
||||
|
||||
David J. Fenwick Asset Software, Inc.
|
||||
President djf@assetsw.com
|
||||
------------------------------------------------------------------------------
|
||||
|
220
docs/textdocs/UNIX-SMB.txt
Normal file
220
docs/textdocs/UNIX-SMB.txt
Normal file
@ -0,0 +1,220 @@
|
||||
This is a short document that describes some of the issues that
|
||||
confront a SMB implementation on unix, and how Samba copes with
|
||||
them. They may help people who are looking at unix<->PC
|
||||
interoperability.
|
||||
|
||||
It was written to help out a person who was writing a paper on unix to
|
||||
PC connectivity.
|
||||
|
||||
Andrew Tridgell
|
||||
April 1995
|
||||
|
||||
|
||||
Usernames
|
||||
=========
|
||||
|
||||
The SMB protocol has only a loose username concept. Early SMB
|
||||
protocols (such as CORE and COREPLUS) have no username concept at
|
||||
all. Even in later protocols clients often attempt operations
|
||||
(particularly printer operations) without first validating a username
|
||||
on the server.
|
||||
|
||||
Unix security is based around username/password pairs. A unix box
|
||||
should not allow clients to do any substantive operation without some
|
||||
sort of validation.
|
||||
|
||||
The problem mostly manifests itself when the unix server is in "share
|
||||
level" security mode. This is the default mode as the alternative
|
||||
"user level" security mode usually forces a client to connect to the
|
||||
server as the same user for each connected share, which is
|
||||
inconvenient in many sites.
|
||||
|
||||
In "share level" security the client normally gives a username in the
|
||||
"session setup" protocol, but does not supply an accompanying
|
||||
password. The client then connects to resources using the "tree
|
||||
connect" protocol, and supplies a password. The problem is that the
|
||||
user on the PC types the username and the password in different
|
||||
contexts, unaware that they need to go together to give access to the
|
||||
server. The username is normally the one the user typed in when they
|
||||
"logged onto" the PC (this assumes Windows for Workgroups). The
|
||||
password is the one they chose when connecting to the disk or printer.
|
||||
|
||||
The user often chooses a totally different username for their login as
|
||||
for the drive connection. Often they also want to access different
|
||||
drives as different usernames. The unix server needs some way of
|
||||
divining the correct username to combine with each password.
|
||||
|
||||
Samba tries to avoid this problem using several methods. These succeed
|
||||
in the vast majority of cases. The methods include username maps, the
|
||||
service%user syntax, the saving of session setup usernames for later
|
||||
validation and the derivation of the username from the service name
|
||||
(either directly or via the user= option).
|
||||
|
||||
File Ownership
|
||||
==============
|
||||
|
||||
The commonly used SMB protocols have no way of saying "you can't do
|
||||
that because you don't own the file". They have, in fact, no concept
|
||||
of file ownership at all.
|
||||
|
||||
This brings up all sorts of interesting problems. For example, when
|
||||
you copy a file to a unix drive, and the file is world writeable but
|
||||
owned by another user the file will transfer correctly but will
|
||||
receive the wrong date. This is because the utime() call under unix
|
||||
only succeeds for the owner of the file, or root, even if the file is
|
||||
world writeable. For security reasons Samba does all file operations
|
||||
as the validated user, not root, so the utime() fails. This can stuff
|
||||
up shared development diectories as programs like "make" will not get
|
||||
file time comparisons right.
|
||||
|
||||
There are several possible solutions to this problem, including
|
||||
username mapping, and forcing a specific username for particular
|
||||
shares.
|
||||
|
||||
Passwords
|
||||
=========
|
||||
|
||||
Many SMB clients uppercase passwords before sending them. I have no
|
||||
idea why they do this. Interestingly WfWg uppercases the password only
|
||||
if the server is running a protocol greater than COREPLUS, so
|
||||
obviously it isn't just the data entry routines that are to blame.
|
||||
|
||||
Unix passwords are case sensitive. So if users use mixed case
|
||||
passwords they are in trouble.
|
||||
|
||||
Samba can try to cope with this by either using the "password level"
|
||||
option which causes Samba to try the offered password with up to the
|
||||
specified number of case changes, or by using the "password server"
|
||||
option which allows Samba to do it's validation via another machine
|
||||
(typically a WinNT server).
|
||||
|
||||
Samba also doesn't support the password encryption method used by SMB
|
||||
clients. This is because the spec isn't sufficiently detailed for an
|
||||
implementation (although Jeremy Allison is working on it, to try and
|
||||
work it out). Also, there is a fundamental problem with what we
|
||||
understand so far in the algorithm, as it seems that the server would
|
||||
need to store somewhere on disk a reversibly encrypted (effectively
|
||||
plaintext) copy of the users password in order to use the
|
||||
algorithm. This goes against the unix policy that "even the super-user
|
||||
doesn't know your password" which comes from the use of a one-way hash
|
||||
function.
|
||||
|
||||
Locking
|
||||
=======
|
||||
|
||||
The locking calls available under a DOS/Windows environment are much
|
||||
richer than those available in unix. This means a unix server (like
|
||||
Samba) choosing to use the standard fcntl() based unix locking calls
|
||||
to implement SMB locking has to improvise a bit.
|
||||
|
||||
One major problem is that dos locks can be in a 32 bit (unsigned)
|
||||
range. Unix locking calls are 32 bits, but are signed, giving only a 31
|
||||
bit range. Unfortunately OLE2 clients use the top bit to select a
|
||||
locking range used for OLE semaphores.
|
||||
|
||||
To work around this problem Samba compresses the 32 bit range into 31
|
||||
bits by appropriate bit shifting. This seems to work but is not
|
||||
ideal. In a future version a separate SMB lockd may be added to cope
|
||||
with the problem.
|
||||
|
||||
It also doesn't help that many unix lockd daemons are very buggy and
|
||||
crash at the slightest provocation. They normally go mostly unused in
|
||||
a unix environment because few unix programs use byte range
|
||||
locking. The stress of huge numbers of lock requests from dos/windows
|
||||
clients can kill the daemon on some systems.
|
||||
|
||||
The second major problem is the "opportunistic locking" requested by
|
||||
some clients. If a client requests opportunistic locking then it is
|
||||
asking the server to notify it if anyone else tries to do something on
|
||||
the same file, at which time the client will say if it is willing to
|
||||
give up it's lock. Unix has no simple way of implementing
|
||||
opportunistic locking, and currently Samba has no support for it.
|
||||
|
||||
Deny Modes
|
||||
==========
|
||||
|
||||
When a SMB client opens a file it asks for a particular "deny mode" to
|
||||
be placed on the file. These modes (DENY_NONE, DENY_READ, DENY_WRITE,
|
||||
DENY_ALL, DENY_FCB and DENY_DOS) specify what actions should be
|
||||
allowed by anyone else who tries to use the file at the same time. If
|
||||
DENY_READ is placed on the file, for example, then any attempt to open
|
||||
the file for reading should fail.
|
||||
|
||||
Unix has no equivalent notion. To implement these Samba uses lock
|
||||
files based on the files inode and placed in a separate lock
|
||||
directory. These are clumsy and consume processing and file resources,
|
||||
so they are optional and off by default.
|
||||
|
||||
Trapdoor UIDs
|
||||
=============
|
||||
|
||||
A SMB session can run with several uids on the one socket. This
|
||||
happens when a user connects to two shares with different
|
||||
usernames. To cope with this the unix server needs to switch uids
|
||||
within the one process. On some unixes (such as SCO) this is not
|
||||
possible. This means that on those unixes the client is restricted to
|
||||
a single uid.
|
||||
|
||||
Port numbers
|
||||
============
|
||||
|
||||
There is a convention that clients on sockets use high "unprivilaged"
|
||||
port numbers (>1000) and connect to servers on low "privilaged" port
|
||||
numbers. This is enforced in Unix as non-root users can't open a
|
||||
socket for listening on port numbers less than 1000.
|
||||
|
||||
Most PC based SMB clients (such as WfWg and WinNT) don't follow this
|
||||
convention completely. The main culprit is the netbios nameserving on
|
||||
udp port 137. Name query requests come from a source port of 137. This
|
||||
is a problem when you combine it with the common firewalling technique
|
||||
of not allowing incoming packets on low port numbers. This means that
|
||||
these clients can't query a netbios nameserver on the other side of a
|
||||
low port based firewall.
|
||||
|
||||
The problem is more severe with netbios node status queries. I've
|
||||
found that WfWg, Win95 and WinNT3.5 all respond to netbios node status
|
||||
queries on port 137 no matter what the source port was in the
|
||||
request. This works between machines that are both using port 137, but
|
||||
it means it's not possible for a unix user to do a node status request
|
||||
to any of these OSes unless they are running as root. The answer comes
|
||||
back, but it goes to port 137 which the unix user can't listen
|
||||
on. Interestingly WinNT3.1 got this right - it sends node status
|
||||
responses back to the source port in the request.
|
||||
|
||||
|
||||
Protocol Complexity
|
||||
===================
|
||||
|
||||
There are many "protocol levels" in the SMB protocol. It seems that
|
||||
each time new functionality was added to a Microsoft operating system,
|
||||
they added the equivalent functions in a new protocol level of the SMB
|
||||
protocol to "externalise" the new capabilities.
|
||||
|
||||
This means the protocol is very "rich", offering many ways of doing
|
||||
each file operation. This means SMB servers need to be complex and
|
||||
large. It also means it is very difficult to make them bug free. It is
|
||||
not just Samba that suffers from this problem, other servers such as
|
||||
WinNT don't support every variation of every call and it has almost
|
||||
certainly been a headache for MS developers to support the myriad of
|
||||
SMB calls that are available.
|
||||
|
||||
There are about 65 "top level" operations in the SMB protocol (things
|
||||
like SMBread and SMBwrite). Some of these include hundreds of
|
||||
sub-functions (SMBtrans has at least 120 sub-functions, like
|
||||
DosPrintQAdd and NetSessionEnum). All of them take several options
|
||||
that can change the way they work. Many take dozens of possible
|
||||
"information levels" that change the structures that need to be
|
||||
returned. Samba supports all but 2 of the "top level" functions. It
|
||||
supports only 8 (so far) of the SMBtrans sub-functions. Even NT
|
||||
doesn't support them all.
|
||||
|
||||
Samba currently supports up to the "NT LM 0.12" protocol, which is the
|
||||
one preferred by Win95 and WinNT3.5. Luckily this protocol level has a
|
||||
"capabilities" field which specifies which super-duper new-fangled
|
||||
options the server suports. This helps to make the implementation of
|
||||
this protocol level much easier.
|
||||
|
||||
There is also a problem with the SMB specications. SMB is a X/Open
|
||||
spec, but the X/Open book is far from ideal, and fails to cover many
|
||||
important issues, leaving much to the imagination.
|
||||
|
56
docs/textdocs/WinNT.txt
Normal file
56
docs/textdocs/WinNT.txt
Normal file
@ -0,0 +1,56 @@
|
||||
There are some particular issues with Samba and Windows NT
|
||||
|
||||
=====================================================================
|
||||
One of the most annoying problems with WinNT is that NT refuses to
|
||||
connect to a server that is in user level security mode and that
|
||||
doesn't support password encryption unless it first prompts the user
|
||||
for a password.
|
||||
|
||||
This means even if you have the same password on the NT box and the
|
||||
Samba server you will get prompted for a password. Entering the
|
||||
correct password will get you connected.
|
||||
|
||||
The other major ramification of this feature of NT is that it can't
|
||||
browse a user level non-encrypted server unless it already has a
|
||||
connection open. This is because there is no spot for a password
|
||||
prompt in the browser window. It works fine if you already have a
|
||||
drive mounted (for example, one auto mounted on startup).
|
||||
|
||||
Samba should support encrypted passwords soon, which will solve this
|
||||
problem.
|
||||
=====================================================================
|
||||
|
||||
|
||||
|
||||
=====================================================================
|
||||
When you mount a printer using the print manager in NT you may find
|
||||
the following info from Matthew Harrell <harrell@leech.nrl.navy.mil>
|
||||
useful:
|
||||
|
||||
------------
|
||||
I noticed in your change-log you noted that some people were
|
||||
still unable to use print manager under NT. If this is the same problem
|
||||
that I encountered, it's caused by the length of time it takes NT to
|
||||
determine if the printer is ready.
|
||||
|
||||
The problem occurs when you double-click on a printer to connect it to
|
||||
the NT machine. Because it's unable to determine if the printer is ready
|
||||
in the short span of time it has, it assumes it isn't and gives some
|
||||
strange error about not having enough resources (I forget what the error
|
||||
is). A solution to this that seems to work fine for us is to click
|
||||
once on the printer, look at the bottom of the window and wait until
|
||||
it says it's ready, then clilck on "OK".
|
||||
|
||||
By the way, this problem probably occurs in our group because the
|
||||
Samba server doesn't actually have the printers - it queues them to
|
||||
remote printers either on other machines or using their own network
|
||||
cards. Because of this "middle layer", it takes an extra amount of
|
||||
time for the NT machine to get verification that the printer queue
|
||||
actually exists.
|
||||
|
||||
I hope this helped in some way...
|
||||
-----------
|
||||
=====================================================================
|
||||
|
||||
|
||||
|
6
examples/README
Normal file
6
examples/README
Normal file
@ -0,0 +1,6 @@
|
||||
This directory contains example config files for Samba. If you have an
|
||||
interesting config file, then please send it in for inclusion in the
|
||||
package.
|
||||
|
||||
Send it to: Andrew.Tridgell@anu.edu.au
|
||||
|
4
examples/dce-dfs/README
Normal file
4
examples/dce-dfs/README
Normal file
@ -0,0 +1,4 @@
|
||||
this is a sample configuration file from Jim Doyle <doyle@oec.com> who
|
||||
did the DCE/DFS patches for Samba. It shows how to make DCE/DFS shares
|
||||
available.
|
||||
|
42
examples/dce-dfs/smb.conf
Normal file
42
examples/dce-dfs/smb.conf
Normal file
@ -0,0 +1,42 @@
|
||||
[global]
|
||||
printing = bsd
|
||||
printcap name = /etc/printcap
|
||||
load printers = no
|
||||
guest account = guest
|
||||
log file = /usr/local/samba/var/log.%m
|
||||
log level = 8
|
||||
password level = 8
|
||||
|
||||
[homes]
|
||||
comment = Home Directories
|
||||
browseable = no
|
||||
read only = no
|
||||
create mode = 0750
|
||||
|
||||
[test]
|
||||
comment = test stuff
|
||||
path = /dept/mis/home/testacct
|
||||
valid users = testacct
|
||||
public = no
|
||||
writable = yes
|
||||
|
||||
[namespace]
|
||||
comment = DCE-DFS Global Root
|
||||
path = /...
|
||||
public = no
|
||||
writable = yes
|
||||
|
||||
[oecdfs]
|
||||
comment = Corporate Cell
|
||||
path = /.../corp.boston.oec.com/fs
|
||||
browseable = no
|
||||
read only = no
|
||||
create mode = 0750
|
||||
|
||||
[develdfs]
|
||||
comment = Technology Development Cell
|
||||
path = /.../devel.boston.oec.com/fs
|
||||
browseable = no
|
||||
read only = no
|
||||
create mode = 0750
|
||||
|
47
examples/misc/extra_smbstatus
Normal file
47
examples/misc/extra_smbstatus
Normal file
@ -0,0 +1,47 @@
|
||||
Here's something that Paul Blackman sent me that may be useful:
|
||||
|
||||
-------------------
|
||||
I created this script to do a few things that smbstatus doesn't at the
|
||||
moment. Perhaps you might want to include these. Sorry I haven't
|
||||
added things at source level, script was quick&easy.
|
||||
|
||||
*******
|
||||
#!/bin/csh
|
||||
if ($1 == "-p") then
|
||||
smbstatus -p |sort -u
|
||||
else if ($1 == "-c") then
|
||||
echo There are `smbstatus -p |sort -u |grep -n -v z |grep -c :` unique
|
||||
smbd processes running.
|
||||
else if ($1 == "-l") then
|
||||
echo `date '+ %d/%m/%y %H:%M:%S'` `smbstatus -p |sort -u |grep -n -v z
|
||||
|grep -c :` >>$2
|
||||
else
|
||||
smbstatus |sort +3 -4 -u
|
||||
endif
|
||||
******
|
||||
|
||||
The '-p' option was just to show unique PIDs.
|
||||
|
||||
The more important ones are the '-c' and '-l' options '-c' just counts
|
||||
the number of unique smbd's, While '-l' logs this count with date and
|
||||
time to a log file specified on the command line. I'm using '-l' at
|
||||
the moment with cron to give me an idea of usage/max connections etc.
|
||||
I was also thinking of doing a log for individual/specified services.
|
||||
|
||||
The default (last) option was to show unique PIDs with user names.
|
||||
Unfortunately this still lists all file locks etc. This would be
|
||||
better with a 'no locked files' option from smbstatus (or is there one
|
||||
that I didn't see)
|
||||
|
||||
Cheers,
|
||||
~^ MIME OK ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~
|
||||
o | Paul Blackman ictinus@lake.canberra.edu.au
|
||||
o | Co-operative Research ------------------------
|
||||
o _ | Centre For Freshwater Ecology. Ph. (Aus) 06 2012518
|
||||
-- (") o | University of Canberra, Australia. Fax. " 06 2015038
|
||||
\_|_-- |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| | "Spend a little love and get high"
|
||||
_/ \_ | - Lenny Kravitz
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~ SAMBA Web Pages: http://samba.canberra.edu.au/pub/samba/samba.html ~~~~~
|
||||
|
45
examples/misc/wall.perl
Normal file
45
examples/misc/wall.perl
Normal file
@ -0,0 +1,45 @@
|
||||
#!/usr/local/bin/perl
|
||||
#
|
||||
#@(#) smb-wall.pl Description:
|
||||
#@(#) A perl script which allows you to announce whatever you choose to
|
||||
#@(#) every PC client currently connected to a Samba Server...
|
||||
#@(#) ...using "smbclient -M" message to winpopup service.
|
||||
#@(#) Default usage is to message every connected PC.
|
||||
#@(#) Alternate usage is to message every pc on the argument list.
|
||||
#@(#) Hacked up by Keith Farrar <farrar@parc.xerox.com>
|
||||
#
|
||||
#=============================================================================
|
||||
$smbstatus = "/usr/local/bin/smbstatus";
|
||||
$smbclient = "/usr/local/bin/smbclient";
|
||||
|
||||
print STDOUT "\nEnter message for Samba clients of this host\n";
|
||||
print STDOUT "(terminated with single '.' or end of file):\n";
|
||||
|
||||
while ( <STDIN> ) {
|
||||
/^\.$/ && last;
|
||||
push(@message, $_);
|
||||
}
|
||||
|
||||
if ( $ARGV[0] ne "" ) {
|
||||
$debug && print STDOUT "Was given args: \n\t @ARGV\n";
|
||||
foreach $client ( @ARGV ) {
|
||||
$pcclient{$client} = $client;
|
||||
}
|
||||
} else {
|
||||
open( PCLIST, "$smbstatus | /bin/awk '/^[a-z]/ {print $5}' | /bin/sort | /bin/uniq|");
|
||||
while ( <PCLIST> ) {
|
||||
/^[a-z]+[a-z0-9A-Z-_]+.+/ || next;
|
||||
($share, $user, $group, $pid, $client, @junk) = split;
|
||||
$pcclient{$client} = $client;
|
||||
}
|
||||
close(PCLIST);
|
||||
}
|
||||
|
||||
foreach $pc ( keys(%pcclient) ) {
|
||||
print STDOUT "Sending message ";
|
||||
$debug && print STDOUT " <@message> \n";
|
||||
print STDOUT "To <$pc>\n";
|
||||
open(SENDMSG,"|$smbclient -M $pc") || next;
|
||||
print SENDMSG @message;
|
||||
close(SENDMSG);
|
||||
}
|
77
examples/printing/smbprint
Executable file
77
examples/printing/smbprint
Executable file
@ -0,0 +1,77 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
# This script is an input filter for printcap printing on a unix machine. It
|
||||
# uses the smbclient program to print the file to the specified smb-based
|
||||
# server and service.
|
||||
# For example you could have a printcap entry like this
|
||||
#
|
||||
# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
|
||||
#
|
||||
# which would create a unix printer called "smb" that will print via this
|
||||
# script. You will need to create the spool directory /usr/spool/smb with
|
||||
# appropriate permissions and ownerships for your system.
|
||||
|
||||
# Set these to the server and service you wish to print to
|
||||
# In this example I have a WfWg PC called "lapland" that has a printer
|
||||
# exported called "printer" with no password.
|
||||
|
||||
#
|
||||
# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
|
||||
# so that the server, service, and password can be read from
|
||||
# a /usr/var/spool/lpd/PRINTNAME/.config file.
|
||||
#
|
||||
# In order for this to work the /etc/printcap entry must include an
|
||||
# accounting file (af=...):
|
||||
#
|
||||
# cdcolour:\
|
||||
# :cm=CD IBM Colorjet on 6th:\
|
||||
# :sd=/var/spool/lpd/cdcolour:\
|
||||
# :af=/var/spool/lpd/cdcolour/acct:\
|
||||
# :if=/usr/local/etc/smbprint:\
|
||||
# :mx=0:\
|
||||
# :lp=/dev/null:
|
||||
#
|
||||
# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
|
||||
# server=PC_SERVER
|
||||
# service=PR_SHARENAME
|
||||
# password="password"
|
||||
#
|
||||
# E.g.
|
||||
# server=PAULS_PC
|
||||
# service=CJET_371
|
||||
# password=""
|
||||
|
||||
#
|
||||
# Debugging log file, change to /dev/null if you like.
|
||||
#
|
||||
logfile=/tmp/smb-print.log
|
||||
# logfile=/dev/null
|
||||
|
||||
|
||||
#
|
||||
# The last parameter to the filter is the accounting file name.
|
||||
# Extract the directory name from the file name.
|
||||
# Concat this with /.config to get the config file.
|
||||
#
|
||||
eval acct_file=\$$#
|
||||
spool_dir=`dirname $acct_file`
|
||||
config_file=$spool_dir/.config
|
||||
|
||||
# Should read the following variables set in the config file:
|
||||
# server
|
||||
# service
|
||||
# password
|
||||
eval `cat $config_file`
|
||||
|
||||
#
|
||||
# Some debugging help, change the >> to > if you want to same space.
|
||||
#
|
||||
echo "server $server, service $service" >> $logfile
|
||||
|
||||
(
|
||||
# NOTE You may wish to add the line `echo translate' if you want automatic
|
||||
# CR/LF translation when printing.
|
||||
# echo translate
|
||||
echo "print -"
|
||||
cat
|
||||
) | /usr/local/samba/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
|
52
examples/printing/smbprint.sysv
Normal file
52
examples/printing/smbprint.sysv
Normal file
@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# @(#) smbprint.sysv version 1.0 Ross Wakelin <r.wakelin@march.co.uk>
|
||||
#
|
||||
# Version 1.0 13 January 1995
|
||||
# modified from the original smbprint (bsd) script
|
||||
#
|
||||
# this script is a System 5 printer interface script. It
|
||||
# uses the smbclient program to print the file to the specified smb-based
|
||||
# server and service.
|
||||
#
|
||||
# To add this to your lp system, copy this file into your samba directory
|
||||
# (the example here is /opt/samba), modify the server and service variables
|
||||
# and then execute the following command (as root)
|
||||
#
|
||||
# lpadmin -punixprintername -v/dev/null -i/opt/samba/smbprint
|
||||
#
|
||||
# where unixprintername is the name that the printer will be known as
|
||||
# on your unix box.
|
||||
#
|
||||
# the script smbprint will be copied into your printer administration
|
||||
# directory (/usr/lib/lp or /etc/lp) as a new interface
|
||||
# (interface/unixprintername)
|
||||
# Then you have to enable unixprintername and accept unixprintername
|
||||
#
|
||||
# This script will then be called by the lp service to print the files
|
||||
# This script will have 6 or more parameters passed to it by the lp service.
|
||||
# The first five will contain details of the print job, who queued it etc,
|
||||
# while parameters 6 onwards are a list of files to print. We just
|
||||
# cat these at the samba client.
|
||||
#
|
||||
# Set these to the server and service you wish to print to
|
||||
# In this example I have a WfWg PC called "lapland" that has a printer
|
||||
# exported called "printer" with no password.
|
||||
#
|
||||
# clear out the unwanted parameters
|
||||
shift;shift;shift;shift;shift
|
||||
# now the argument list is just the files to print
|
||||
|
||||
server=admin
|
||||
service=hplj2
|
||||
password=""
|
||||
|
||||
(
|
||||
# NOTE You may wish to add the line `echo translate' if you want automatic
|
||||
# CR/LF translation when printing.
|
||||
echo translate
|
||||
echo "print -"
|
||||
cat $*
|
||||
) | /opt/samba/smbclient "\\\\$server\\$service" $password -N -P > /dev/null
|
||||
exit $?
|
||||
|
2
examples/simple/README
Normal file
2
examples/simple/README
Normal file
@ -0,0 +1,2 @@
|
||||
This is the "original" sample config file.
|
||||
|
165
examples/simple/smb.conf
Normal file
165
examples/simple/smb.conf
Normal file
@ -0,0 +1,165 @@
|
||||
; Configuration file for smbd.
|
||||
; ============================================================================
|
||||
; For the format of this file and comprehensive descriptions of all the
|
||||
; configuration option, please refer to the man page for smb.conf(5).
|
||||
;
|
||||
; The following configuration should suit most systems for basic usage and
|
||||
; initial testing. It gives all clients access to their home directories and
|
||||
; allows access to all printers specified in /etc/printcap.
|
||||
;
|
||||
; Things you need to check:
|
||||
; --------------------------
|
||||
;
|
||||
; 1: Check the path to your printcap file. If you are using a system that does
|
||||
; not use printcap (eg., Solaris), create a file containing lines of the
|
||||
; form
|
||||
;
|
||||
; printername|printername|printername|
|
||||
;
|
||||
; where each "printername" is the name of a printer you want to provide
|
||||
; access to. Then alter the "printcap =" entry to point to the new file.
|
||||
;
|
||||
; If using Solaris, the following command will generate a suitable printcap
|
||||
; file:
|
||||
;
|
||||
; lpc status | grep ":" | sed s/:/\|/ > myprintcap
|
||||
;
|
||||
; 2: Make sure the "print command" entry is correct for your system. This
|
||||
; command should submit a file (represented by %s) to a printer
|
||||
; (represented by %p) for printing and should REMOVE the file after
|
||||
; printing.
|
||||
;
|
||||
; One most systems the default will be OK, as long as you get "printing ="
|
||||
; right.
|
||||
;
|
||||
; It is also a good idea to use an absolute path in the print command
|
||||
; as there is no guarantee the search path will be set correctly.
|
||||
;
|
||||
; 3: Make sure the "printing =" option is set correctly for your system.
|
||||
; Possible values are "sysv", "bsd" or "aix".
|
||||
;
|
||||
; 4: Make sure the "lpq command" entry is correct for your system. The default
|
||||
; may not work for you.
|
||||
;
|
||||
; 5: Make sure that the user specified in "guest account" exists. Typically
|
||||
; this will be a user that cannot log in and has minimal privileges.
|
||||
; Often the "nobody" account doesn't work (very system dependant).
|
||||
;
|
||||
; 6: You should consider the "security =" option. See a full description
|
||||
; in the main documentation and the smb.conf(5) manual page
|
||||
;
|
||||
; 7: Look at the "hosts allow" option, unless you want everyone on the internet
|
||||
; to be able to access your files.
|
||||
;
|
||||
[global]
|
||||
printing = bsd
|
||||
printcap name = /etc/printcap
|
||||
load printers = yes
|
||||
guest account = pcguest
|
||||
; This next option sets a separate log file for each client. Remove
|
||||
; it if you want a combined log file.
|
||||
log file = /usr/local/samba/log.%m
|
||||
|
||||
; You will need a world readable lock directory and "share modes=yes"
|
||||
; if you want to support the file sharing modes for multiple users
|
||||
; of the same files
|
||||
; lock directory = /usr/local/samba/var/locks
|
||||
; share modes = yes
|
||||
|
||||
[homes]
|
||||
comment = Home Directories
|
||||
browseable = no
|
||||
read only = no
|
||||
create mode = 0750
|
||||
|
||||
[printers]
|
||||
comment = All Printers
|
||||
browseable = no
|
||||
printable = yes
|
||||
public = no
|
||||
writable = no
|
||||
create mode = 0700
|
||||
|
||||
; you might also want this one
|
||||
; [tmp]
|
||||
; comment = Temporary file space
|
||||
; path = /tmp
|
||||
; read only = no
|
||||
; public = yes
|
||||
|
||||
;
|
||||
; Other examples.
|
||||
;
|
||||
; A private printer, usable only by fred. Spool data will be placed in fred's
|
||||
; home directory. Note that fred must have write access to the spool directory,
|
||||
; wherever it is.
|
||||
;[fredsprn]
|
||||
; comment = Fred's Printer
|
||||
; valid users = fred
|
||||
; path = /homes/fred
|
||||
; printer = freds_printer
|
||||
; public = no
|
||||
; writable = no
|
||||
; printable = yes
|
||||
;
|
||||
; A private directory, usable only by fred. Note that fred requires write
|
||||
; access to the directory.
|
||||
;[fredsdir]
|
||||
; comment = Fred's Service
|
||||
; path = /usr/somewhere/private
|
||||
; valid users = fred
|
||||
; public = no
|
||||
; writable = yes
|
||||
; printable = no
|
||||
;
|
||||
; A publicly accessible directory, but read only, except for people in
|
||||
; the staff group
|
||||
;[public]
|
||||
; comment = Public Stuff
|
||||
; path = /usr/somewhere/public
|
||||
; public = yes
|
||||
; writable = no
|
||||
; printable = no
|
||||
; write list = @staff
|
||||
;
|
||||
; a service which has a different directory for each machine that connects
|
||||
; this allows you to tailor configurations to incoming machines. You could
|
||||
; also use the %u option to tailor it by user name.
|
||||
; The %m gets replaced with the machine name that is connecting.
|
||||
;[pchome]
|
||||
; comment = PC Directories
|
||||
; path = /usr/pc/%m
|
||||
; public = no
|
||||
; writeable = yes
|
||||
;
|
||||
;
|
||||
; A publicly accessible directory, read/write to all users. Note that all files
|
||||
; created in the directory by users will be owned by the default user, so
|
||||
; any user with access can delete any other user's files. Obviously this
|
||||
; directory must be writable by the default user. Another user could of course
|
||||
; be specified, in which case all files would be owned by that user instead.
|
||||
;[public]
|
||||
; path = /usr/somewhere/else/public
|
||||
; public = yes
|
||||
; only guest = yes
|
||||
; writable = yes
|
||||
; printable = no
|
||||
;
|
||||
;
|
||||
; The following two entries demonstrate how to share a directory so that two
|
||||
; users can place files there that will be owned by the specific users. In this
|
||||
; setup, the directory should be writable by both users and should have the
|
||||
; sticky bit set on it to prevent abuse. Obviously this could be extended to
|
||||
; as many users as required.
|
||||
;[myshare]
|
||||
; comment = Mary's and Fred's stuff
|
||||
; path = /usr/somewhere/shared
|
||||
; valid users = mary fred
|
||||
; public = no
|
||||
; writable = yes
|
||||
; printable = no
|
||||
; create mask = 0765
|
||||
|
||||
|
||||
|
||||
|
8
examples/tridge/README
Normal file
8
examples/tridge/README
Normal file
@ -0,0 +1,8 @@
|
||||
This is the configuration I use at home. I have 2 client PCs, one
|
||||
running Win95, one running alternately WfWg and NTAS3.5. My server is
|
||||
a 486dx2-66 Linux box.
|
||||
|
||||
Note that I use the %a and %m macros to load smb.conf extensions
|
||||
particular to machines and architectures. This gives me a lot of
|
||||
flexibility in how I handle each of the machines.
|
||||
|
101
examples/tridge/smb.conf
Normal file
101
examples/tridge/smb.conf
Normal file
@ -0,0 +1,101 @@
|
||||
[global]
|
||||
config file = /usr/local/samba/smb.conf.%m
|
||||
status = yes
|
||||
security = user
|
||||
encrypt passwords = yes
|
||||
server string = Tridge (%v,%h)
|
||||
load printers = yes
|
||||
log level = 1
|
||||
log file = /usr/local/samba/var/log.%m
|
||||
guest account = pcguest
|
||||
hosts allow = 192.0.2. localhost
|
||||
password level = 2
|
||||
auto services = tridge susan
|
||||
message command = csh -c '/usr/bin/X11/xedit -display :0 %s;rm %s' &
|
||||
read prediction = yes
|
||||
socket options = TCP_NODELAY
|
||||
valid chars = ö:Ö å:Å ä:Ä
|
||||
share modes = yes
|
||||
locking = yes
|
||||
strict locking = yes
|
||||
keepalive = 30
|
||||
include = /usr/local/samba/lib/smb.conf.%m
|
||||
include = /usr/local/samba/lib/smb.conf.%a
|
||||
|
||||
|
||||
[uniprint]
|
||||
comment = University Printing
|
||||
path = /home/susan/print
|
||||
user = susan
|
||||
postscript = yes
|
||||
print ok = yes
|
||||
print command = xmenu -heading "%s" OK&
|
||||
|
||||
[testprn]
|
||||
comment = Test printer
|
||||
path = /tmp
|
||||
user = susan
|
||||
print ok = yes
|
||||
print command = cp %s /tmp/smb.%U.prn
|
||||
lpq command = cat /tmp/xxyz
|
||||
|
||||
[amd]
|
||||
comment = amd area
|
||||
path = /mount
|
||||
force user = tridge
|
||||
read only = no
|
||||
|
||||
[homes]
|
||||
browseable = no
|
||||
guest ok = no
|
||||
read only = no
|
||||
create mask = 0755
|
||||
|
||||
[printers]
|
||||
browseable = no
|
||||
comment = Printer in Printcap
|
||||
guest ok = no
|
||||
path = /tmp
|
||||
read only = no
|
||||
print ok = yes
|
||||
|
||||
[dos]
|
||||
browseable = yes
|
||||
comment = Dos Files
|
||||
force group = samba
|
||||
create mode = 0775
|
||||
path = /home/tridge/dos
|
||||
copy = homes
|
||||
|
||||
[msoffice]
|
||||
browseable = yes
|
||||
comment = Microsoft Office
|
||||
force group = samba
|
||||
create mode = 0775
|
||||
path = /data/msoffice
|
||||
read only = yes
|
||||
|
||||
[root]
|
||||
comment = Root Dir
|
||||
copy = dos
|
||||
path = /
|
||||
dont descend = /proc ./proc /etc
|
||||
|
||||
[tmp]
|
||||
comment = tmp files
|
||||
copy = dos
|
||||
path = /tmp
|
||||
read only = no
|
||||
|
||||
|
||||
[cdrom]
|
||||
comment = Tridge's CdRom
|
||||
path = /mount/cdrom
|
||||
read only = yes
|
||||
locking = no
|
||||
|
||||
[data]
|
||||
comment = Data Partition
|
||||
path = /data
|
||||
read only = yes
|
||||
guest ok = yes
|
14
examples/tridge/smb.conf.WinNT
Normal file
14
examples/tridge/smb.conf.WinNT
Normal file
@ -0,0 +1,14 @@
|
||||
#log level = 4
|
||||
#readraw = no
|
||||
#writeraw = no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
21
examples/tridge/smb.conf.fjall
Normal file
21
examples/tridge/smb.conf.fjall
Normal file
@ -0,0 +1,21 @@
|
||||
;log level = 4
|
||||
;readraw = no
|
||||
;writeraw = no
|
||||
;password level = 4
|
||||
;mangled map = (;1 )
|
||||
;protocol = lanman1
|
||||
;user = susan
|
||||
;getwd cache = no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
14
examples/tridge/smb.conf.lapland
Normal file
14
examples/tridge/smb.conf.lapland
Normal file
@ -0,0 +1,14 @@
|
||||
#log level = 4
|
||||
#readraw = no
|
||||
#writeraw = no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
14
examples/tridge/smb.conf.vittjokk
Normal file
14
examples/tridge/smb.conf.vittjokk
Normal file
@ -0,0 +1,14 @@
|
||||
;protocol = LANMAN2
|
||||
log level = 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1872
source3/change-log
Normal file
1872
source3/change-log
Normal file
File diff suppressed because it is too large
Load Diff
4534
source3/client/client.c
Normal file
4534
source3/client/client.c
Normal file
File diff suppressed because it is too large
Load Diff
1713
source3/client/clitar.c
Normal file
1713
source3/client/clitar.c
Normal file
File diff suppressed because it is too large
Load Diff
80
source3/include/byteorder.h
Normal file
80
source3/include/byteorder.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
SMB Byte handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements macros for machine independent short and
|
||||
int manipulation
|
||||
*/
|
||||
|
||||
#undef CAREFUL_ALIGNMENT
|
||||
|
||||
/* we know that the 386 can handle misalignment and has the "right"
|
||||
byteorder */
|
||||
#ifdef __i386__
|
||||
#define CAREFUL_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#ifndef CAREFUL_ALIGNMENT
|
||||
#define CAREFUL_ALIGNMENT 1
|
||||
#endif
|
||||
|
||||
#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
|
||||
#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
|
||||
#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
|
||||
|
||||
|
||||
#if CAREFUL_ALIGNMENT
|
||||
#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
|
||||
#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
|
||||
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
|
||||
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
|
||||
#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
|
||||
#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
|
||||
#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
|
||||
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
|
||||
#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
|
||||
#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
|
||||
#else
|
||||
/* this handles things for architectures like the 386 that can handle
|
||||
alignment errors */
|
||||
/*
|
||||
WARNING: This section is dependent on the length of int16 and int32
|
||||
being correct
|
||||
*/
|
||||
#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
|
||||
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
|
||||
#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
|
||||
#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
|
||||
#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
|
||||
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
|
||||
#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
|
||||
#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
|
||||
#endif
|
||||
|
||||
|
||||
/* now the reverse routines - these are used in nmb packets (mostly) */
|
||||
#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
|
||||
#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
|
||||
|
||||
#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
|
||||
#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
|
||||
#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
|
||||
#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
|
61
source3/include/charset.h
Normal file
61
source3/include/charset.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Character set handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef CHARSET_C
|
||||
|
||||
extern char *dos_char_map;
|
||||
extern char *upper_char_map;
|
||||
extern char *lower_char_map;
|
||||
extern void add_char_string(char *s);
|
||||
extern void charset_initialise(void);
|
||||
|
||||
#ifdef toupper
|
||||
#undef toupper
|
||||
#endif
|
||||
|
||||
#ifdef tolower
|
||||
#undef tolower
|
||||
#endif
|
||||
|
||||
#ifdef isupper
|
||||
#undef isupper
|
||||
#endif
|
||||
|
||||
#ifdef islower
|
||||
#undef islower
|
||||
#endif
|
||||
|
||||
#ifdef isdoschar
|
||||
#undef isdoschar
|
||||
#endif
|
||||
|
||||
#ifdef isspace
|
||||
#undef isspace
|
||||
#endif
|
||||
|
||||
#define toupper(c) upper_char_map[(char)(c)]
|
||||
#define tolower(c) lower_char_map[(char)(c)]
|
||||
#define isupper(c) (((char)(c)) != tolower(c))
|
||||
#define islower(c) (((char)(c)) != toupper(c))
|
||||
#define isdoschar(c) (dos_char_map[(char)(c)] != 0)
|
||||
#define isspace(c) ((c)==' ' || (c) == '\t')
|
||||
#endif
|
||||
|
17
source3/include/clitar.h
Normal file
17
source3/include/clitar.h
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
#define TBLOCK 512
|
||||
#define NAMSIZ 100
|
||||
union hblock {
|
||||
char dummy[TBLOCK];
|
||||
struct header {
|
||||
char name[NAMSIZ];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char linkflag;
|
||||
char linkname[NAMSIZ];
|
||||
} dbuf;
|
||||
};
|
1154
source3/include/includes.h
Normal file
1154
source3/include/includes.h
Normal file
File diff suppressed because it is too large
Load Diff
130
source3/include/kanji.h
Normal file
130
source3/include/kanji.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Kanji Extensions
|
||||
Copyright (C) Andrew Tridgell 1992-1994
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
|
||||
and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
|
||||
and add all jis codes sequence at 1995.8.16
|
||||
Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
|
||||
*/
|
||||
#ifndef _KANJI_H_
|
||||
#define _KANJI_H_
|
||||
|
||||
#ifdef KANJI
|
||||
|
||||
/* FOR SHIFT JIS CODE */
|
||||
#define is_shift_jis(c) \
|
||||
((0x81 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0x9f) \
|
||||
|| (0xe0 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xef))
|
||||
#define is_shift_jis2(c) \
|
||||
(0x40 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xfc \
|
||||
&& ((unsigned char) (c)) != 0x7f)
|
||||
#define is_kana(c) ((0xa0 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xdf))
|
||||
|
||||
#ifdef _KANJI_C_
|
||||
/* FOR EUC CODE */
|
||||
#define euc_kana (0x8e)
|
||||
#define is_euc_kana(c) (((unsigned char) (c)) == euc_kana)
|
||||
#define is_euc(c) (0xa0 < ((unsigned char) (c)) && ((unsigned char) (c)) < 0xff)
|
||||
|
||||
/* FOR JIS CODE */
|
||||
/* default jis third shift code, use for output */
|
||||
#ifndef JIS_KSO
|
||||
#define JIS_KSO 'B'
|
||||
#endif
|
||||
#ifndef JIS_KSI
|
||||
#define JIS_KSI 'J'
|
||||
#endif
|
||||
/* in: \E$B or \E$@ */
|
||||
/* out: \E(J or \E(B or \E(H */
|
||||
#define jis_esc (0x1b)
|
||||
#define jis_so (0x0e)
|
||||
#define jis_so1 ('$')
|
||||
#define jis_so2 ('B')
|
||||
#define jis_si (0x0f)
|
||||
#define jis_si1 ('(')
|
||||
#define jis_si2 ('J')
|
||||
#define is_esc(c) (((unsigned char) (c)) == jis_esc)
|
||||
#define is_so1(c) (((unsigned char) (c)) == jis_so1)
|
||||
#define is_so2(c) (((unsigned char) (c)) == jis_so2 || ((unsigned char) (c)) == '@')
|
||||
#define is_si1(c) (((unsigned char) (c)) == jis_si1)
|
||||
#define is_si2(c) (((unsigned char) (c)) == jis_si2 || ((unsigned char) (c)) == 'B' \
|
||||
|| ((unsigned char) (c)) == 'H')
|
||||
#define is_so(c) (((unsigned char) (c)) == jis_so)
|
||||
#define is_si(c) (((unsigned char) (c)) == jis_si)
|
||||
#define junet_kana1 ('(')
|
||||
#define junet_kana2 ('I')
|
||||
#define is_juk1(c) (((unsigned char) (c)) == junet_kana1)
|
||||
#define is_juk2(c) (((unsigned char) (c)) == junet_kana2)
|
||||
|
||||
#define _KJ_ROMAN (0)
|
||||
#define _KJ_KANJI (1)
|
||||
#define _KJ_KANA (2)
|
||||
|
||||
/* FOR HEX */
|
||||
#define HEXTAG ':'
|
||||
#define hex2bin(x) \
|
||||
( ((int) '0' <= ((int) (x)) && ((int) (x)) <= (int)'9')? \
|
||||
(((int) (x))-(int)'0'): \
|
||||
((int) 'a'<= ((int) (x)) && ((int) (x))<= (int) 'f')? \
|
||||
(((int) (x)) - (int)'a'+10): \
|
||||
(((int) (x)) - (int)'A'+10) )
|
||||
#define bin2hex(x) \
|
||||
( (((int) (x)) >= 10)? (((int) (x))-10 + (int) 'a'): (((int) (x)) + (int) '0') )
|
||||
|
||||
#else /* not _KANJI_C_ */
|
||||
|
||||
extern char* (*_dos_to_unix) (const char *str, BOOL overwrite);
|
||||
extern char* (*_unix_to_dos) (const char *str, BOOL overwrite);
|
||||
|
||||
#define unix_to_dos (*_unix_to_dos)
|
||||
#define dos_to_unix (*_dos_to_unix)
|
||||
|
||||
extern char *sj_strtok (char *s1, const char *s2);
|
||||
extern char *sj_strchr (const char *s, int c);
|
||||
extern char *sj_strrchr (const char *s, int c);
|
||||
extern char *sj_strstr (const char *s1, const char *s2);
|
||||
|
||||
#define strchr sj_strchr
|
||||
#define strrchr sj_strrchr
|
||||
#define strstr sj_strstr
|
||||
#define strtok sj_strtok
|
||||
|
||||
#endif /* _KANJI_C_ */
|
||||
|
||||
#define UNKNOWN_CODE (-1)
|
||||
#define SJIS_CODE (0)
|
||||
#define EUC_CODE (1)
|
||||
#define JIS7_CODE (2)
|
||||
#define JIS8_CODE (3)
|
||||
#define JUNET_CODE (4)
|
||||
#define HEX_CODE (5)
|
||||
#define CAP_CODE (6)
|
||||
#define DOSV_CODE SJIS_CODE
|
||||
|
||||
int interpret_coding_system (char *str, int def);
|
||||
|
||||
#else
|
||||
|
||||
#define unix_to_dos(x,y) (x)
|
||||
#define dos_to_unix(x,y) (x)
|
||||
|
||||
#endif /* not KANJI */
|
||||
|
||||
#endif /* _KANJI_H_ */
|
167
source3/include/local.h
Normal file
167
source3/include/local.h
Normal file
@ -0,0 +1,167 @@
|
||||
/* local definitions for file server */
|
||||
#ifndef _LOCAL_H
|
||||
#define _LOCAL_H
|
||||
|
||||
/* This defines the section name in the configuration file that will contain */
|
||||
/* global parameters - that is, parameters relating to the whole server, not */
|
||||
/* just services. This name is then reserved, and may not be used as a */
|
||||
/* a service name. It will default to "global" if not defined here. */
|
||||
#define GLOBAL_NAME "global"
|
||||
#define GLOBAL_NAME2 "globals"
|
||||
|
||||
/* This defines the section name in the configuration file that will
|
||||
refer to the special "homes" service */
|
||||
#define HOMES_NAME "homes"
|
||||
|
||||
/* This defines the section name in the configuration file that will
|
||||
refer to the special "printers" service */
|
||||
#define PRINTERS_NAME "printers"
|
||||
|
||||
/* This defines the name of the printcap file. It is MOST UNLIKELY that
|
||||
this will change BUT! Specifying a file with the format of a printcap
|
||||
file but containing only a subset of the printers actually in your real
|
||||
printcap file is a quick-n-dirty way to allow dynamic access to a subset
|
||||
of available printers.
|
||||
*/
|
||||
#define PRINTCAP_NAME "/etc/printcap"
|
||||
|
||||
/* set these to define the limits of the server. NOTE These are on a
|
||||
per-client basis. Thus any one machine can't connect to more than
|
||||
MAX_CONNECTIONS services, but any number of machines may connect at
|
||||
one time. */
|
||||
#define MAX_CONNECTIONS 127
|
||||
#define MAX_OPEN_FILES 100
|
||||
|
||||
/* the max number of connections that the smbstatus program will show */
|
||||
#define MAXSTATUS 1000
|
||||
|
||||
/* max number of directories open at once */
|
||||
/* note that with the new directory code this no longer requires a
|
||||
file handle per directory, but large numbers do use more memory */
|
||||
#define MAXDIR 64
|
||||
|
||||
#define WORDMAX 0xFFFF
|
||||
|
||||
|
||||
/* separators for lists */
|
||||
#define LIST_SEP " \t,;:\n\r"
|
||||
|
||||
#ifndef LOCKDIR
|
||||
#define LOCKDIR "/tmp/samba"
|
||||
#endif
|
||||
|
||||
/* this is where browse lists are kept in the lock dir */
|
||||
#define SERVER_LIST "browse.dat"
|
||||
|
||||
/* the print command on the server, %s is replaced with the filename */
|
||||
/* note that the -r removes the file after printing - you'll run out */
|
||||
/* of disk pretty quickly if you don't. This command is only used as */
|
||||
/* the default - it can be overridden in the configuration file. */
|
||||
#define PRINT_COMMAND "lpr -r %s"
|
||||
|
||||
/* the lpq command on the server. the printername is passed as an argument */
|
||||
#ifndef LPQ_COMMAND
|
||||
#define LPQ_COMMAND "lpq -P"
|
||||
#endif
|
||||
|
||||
/* shall guest entries in printer queues get changed to user entries,
|
||||
so they can be deleted using the windows print manager? */
|
||||
#define LPQ_GUEST_TO_USER
|
||||
|
||||
/* shall filenames with illegal chars in them get mangled in long
|
||||
filename listings? */
|
||||
#define MANGLE_LONG_FILENAMES
|
||||
|
||||
/* define this if you want to stop spoofing with .. and soft links
|
||||
NOTE: This also slows down the server considerably */
|
||||
#define REDUCE_PATHS
|
||||
|
||||
/* the size of the directory cache */
|
||||
#define DIRCACHESIZE 20
|
||||
|
||||
/* what type of filesystem do we want this to show up as in a NT file
|
||||
manager window? */
|
||||
#define FSTYPE_STRING "Samba"
|
||||
|
||||
/* we have two time standards - local and GMT. This will try to sort them out.
|
||||
*/
|
||||
|
||||
#define LOCAL_TO_GMT 1
|
||||
#define GMT_TO_LOCAL (-1)
|
||||
|
||||
/* do you want smbd to send a 1 byte packet to nmbd to trigger it to start
|
||||
when smbd starts? */
|
||||
#ifndef PRIME_NMBD
|
||||
#define PRIME_NMBD 1
|
||||
#endif
|
||||
|
||||
/* do you want session setups at user level security with a invalid
|
||||
password to be rejected or allowed in as guest? WinNT rejects them
|
||||
but it can be a pain as it means "net view" needs to use a password
|
||||
|
||||
You have 3 choices:
|
||||
|
||||
GUEST_SESSSETUP = 0 means session setups with an invalid password
|
||||
are rejected.
|
||||
|
||||
GUEST_SESSSETUP = 1 means session setups with an invalid password
|
||||
are rejected, unless the username does not exist, in which case it
|
||||
is treated as a guest login
|
||||
|
||||
GUEST_SESSSETUP = 2 means session setups with an invalid password
|
||||
are treated as a guest login
|
||||
|
||||
Note that GUEST_SESSSETUP only has an effect in user or server
|
||||
level security.
|
||||
*/
|
||||
#ifndef GUEST_SESSSETUP
|
||||
#define GUEST_SESSSETUP 0
|
||||
#endif
|
||||
|
||||
/* the default pager to use for the client "more" command. Users can
|
||||
override this with the PAGER environment variable */
|
||||
#ifndef PAGER
|
||||
#define PAGER "more"
|
||||
#endif
|
||||
|
||||
/* the size of the uid cache used to reduce valid user checks */
|
||||
#define UID_CACHE_SIZE 4
|
||||
|
||||
/* the following control timings of various actions. Don't change
|
||||
them unless you know what you are doing. These are all in seconds */
|
||||
#define DEFAULT_SMBD_TIMEOUT (60*60*24*7)
|
||||
#define SMBD_RELOAD_CHECK (10)
|
||||
#define SHARE_MODES_CHECK (10)
|
||||
#define SHARE_MODES_CLEAN (300)
|
||||
#define IDLE_CLOSED_TIMEOUT (60)
|
||||
#define DPTR_IDLE_TIMEOUT (120)
|
||||
#define SMBD_SELECT_LOOP (10)
|
||||
#define NMBD_SELECT_LOOP (10)
|
||||
#define BROWSE_INTERVAL (60)
|
||||
#define REGISTRATION_INTERVAL (10*60)
|
||||
#define NMBD_INETD_TIMEOUT (120)
|
||||
#define NMBD_MAX_TTL (24*60*60)
|
||||
#define LPQ_LOCK_TIMEOUT (5)
|
||||
|
||||
/* the following are in milliseconds */
|
||||
#define LOCK_RETRY_TIMEOUT (100)
|
||||
|
||||
/* do you want to dump core (carefully!) when an internal error is
|
||||
encountered? Samba will be careful to make the core file only
|
||||
accessible to root */
|
||||
#define DUMP_CORE 1
|
||||
|
||||
/* what is the longest significant password available on your system?
|
||||
Knowing this speeds up password searches a lot */
|
||||
#ifndef PASSWORD_LENGTH
|
||||
#define PASSWORD_LENGTH 8
|
||||
#endif
|
||||
|
||||
#define SMB_ALIGNMENT 1
|
||||
|
||||
|
||||
/* shall we support browse requests via a FIFO to nmbd? */
|
||||
#define ENABLE_FIFO 1
|
||||
|
||||
|
||||
#endif
|
184
source3/include/nameserv.h
Normal file
184
source3/include/nameserv.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios header - version 2
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#define MAX_DGRAM_SIZE 576
|
||||
#define MIN_DGRAM_SIZE 12
|
||||
|
||||
#define NMB_PORT 137
|
||||
#define DGRAM_PORT 138
|
||||
#define SMB_PORT 139
|
||||
|
||||
enum name_source {LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
|
||||
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
|
||||
enum packet_type {NMB_PACKET, DGRAM_PACKET};
|
||||
|
||||
/* a netbios name structure */
|
||||
struct nmb_name {
|
||||
char name[17];
|
||||
char scope[64];
|
||||
int name_type;
|
||||
};
|
||||
|
||||
/* this is the structure used for the local netbios name list */
|
||||
struct name_record
|
||||
{
|
||||
struct name_record *next;
|
||||
struct name_record *prev;
|
||||
struct nmb_name name;
|
||||
time_t death_time;
|
||||
struct in_addr ip;
|
||||
BOOL unique;
|
||||
enum name_source source;
|
||||
};
|
||||
|
||||
/* this is used by the list of domains */
|
||||
struct domain_record
|
||||
{
|
||||
struct domain_record *next;
|
||||
struct domain_record *prev;
|
||||
fstring name;
|
||||
time_t lastannounce_time;
|
||||
int announce_interval;
|
||||
struct in_addr bcast_ip;
|
||||
};
|
||||
|
||||
/* this is used to hold the list of servers in my domain */
|
||||
struct server_record
|
||||
{
|
||||
struct server_record *next;
|
||||
struct server_record *prev;
|
||||
fstring name;
|
||||
fstring comment;
|
||||
uint32 servertype;
|
||||
time_t death_time;
|
||||
};
|
||||
|
||||
/* a resource record */
|
||||
struct res_rec {
|
||||
struct nmb_name rr_name;
|
||||
int rr_type;
|
||||
int rr_class;
|
||||
int ttl;
|
||||
int rdlength;
|
||||
char rdata[MAX_DGRAM_SIZE];
|
||||
};
|
||||
|
||||
/* define a nmb packet. */
|
||||
struct nmb_packet
|
||||
{
|
||||
struct {
|
||||
int name_trn_id;
|
||||
int opcode;
|
||||
BOOL response;
|
||||
struct {
|
||||
BOOL bcast;
|
||||
BOOL recursion_available;
|
||||
BOOL recursion_desired;
|
||||
BOOL trunc;
|
||||
BOOL authoritative;
|
||||
} nm_flags;
|
||||
int rcode;
|
||||
int qdcount;
|
||||
int ancount;
|
||||
int nscount;
|
||||
int arcount;
|
||||
} header;
|
||||
|
||||
struct {
|
||||
struct nmb_name question_name;
|
||||
int question_type;
|
||||
int question_class;
|
||||
} question;
|
||||
|
||||
struct res_rec *answers;
|
||||
struct res_rec *nsrecs;
|
||||
struct res_rec *additional;
|
||||
};
|
||||
|
||||
|
||||
/* a datagram - this normally contains SMB data in the data[] array */
|
||||
struct dgram_packet {
|
||||
struct {
|
||||
int msg_type;
|
||||
struct {
|
||||
enum node_type node_type;
|
||||
BOOL first;
|
||||
BOOL more;
|
||||
} flags;
|
||||
int dgm_id;
|
||||
struct in_addr source_ip;
|
||||
int source_port;
|
||||
int dgm_length;
|
||||
int packet_offset;
|
||||
} header;
|
||||
struct nmb_name source_name;
|
||||
struct nmb_name dest_name;
|
||||
int datasize;
|
||||
char data[MAX_DGRAM_SIZE];
|
||||
};
|
||||
|
||||
/* define a structure used to queue packets. this will be a linked
|
||||
list of nmb packets */
|
||||
struct packet_struct
|
||||
{
|
||||
struct packet_struct *next;
|
||||
struct packet_struct *prev;
|
||||
struct in_addr ip;
|
||||
int port;
|
||||
int fd;
|
||||
time_t timestamp;
|
||||
enum packet_type packet_type;
|
||||
union {
|
||||
struct nmb_packet nmb;
|
||||
struct dgram_packet dgram;
|
||||
} packet;
|
||||
};
|
||||
|
||||
|
||||
/* this defines a list of network interfaces */
|
||||
struct net_interface {
|
||||
struct net_interface *next;
|
||||
struct in_addr ip;
|
||||
struct in_addr bcast;
|
||||
struct in_addr netmask;
|
||||
};
|
||||
|
||||
|
||||
/* prototypes */
|
||||
void free_nmb_packet(struct nmb_packet *nmb);
|
||||
void free_packet(struct packet_struct *packet);
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
|
||||
BOOL send_packet(struct packet_struct *p);
|
||||
struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
|
||||
void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
|
||||
BOOL name_query(int fd,char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, struct in_addr *ip,void (*fn)());
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)());
|
||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
|
||||
char *srcname,char *dstname,
|
||||
int src_type,int dest_type,
|
||||
struct in_addr dest_ip,
|
||||
struct in_addr src_ip);
|
||||
char *namestr(struct nmb_name *n);
|
1006
source3/include/smb.h
Normal file
1006
source3/include/smb.h
Normal file
File diff suppressed because it is too large
Load Diff
241
source3/include/trans2.h
Normal file
241
source3/include/trans2.h
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
SMB transaction2 handling
|
||||
Copyright (C) Jeremy Allison 1994
|
||||
|
||||
Extensively modified by Andrew Tridgell, 1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _TRANS2_H_
|
||||
#define _TRANS2_H_
|
||||
|
||||
/* Define the structures needed for the trans2 calls. */
|
||||
|
||||
/*******************************************************
|
||||
For DosFindFirst/DosFindNext - level 1
|
||||
|
||||
MAXFILENAMELEN = 255;
|
||||
FDATE == uint16
|
||||
FTIME == uint16
|
||||
ULONG == uint32
|
||||
USHORT == uint16
|
||||
|
||||
typedef struct _FILEFINDBUF {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 FDATE fdateCreation;
|
||||
2 FTIME ftimeCreation;
|
||||
4 FDATE fdateLastAccess;
|
||||
6 FTIME ftimeLastAccess;
|
||||
8 FDATE fdateLastWrite;
|
||||
10 FTIME ftimeLastWrite;
|
||||
12 ULONG cbFile file length in bytes
|
||||
16 ULONG cbFileAlloc size of file allocation unit
|
||||
20 USHORT attrFile
|
||||
22 UCHAR cchName length of name to follow (not including zero)
|
||||
23 UCHAR achName[MAXFILENAMELEN]; Null terminated name
|
||||
} FILEFINDBUF;
|
||||
*********************************************************/
|
||||
|
||||
#define l1_fdateCreation 0
|
||||
#define l1_fdateLastAccess 4
|
||||
#define l1_fdateLastWrite 8
|
||||
#define l1_cbFile 12
|
||||
#define l1_cbFileAlloc 16
|
||||
#define l1_attrFile 20
|
||||
#define l1_cchName 22
|
||||
#define l1_achName 23
|
||||
|
||||
/**********************************************************
|
||||
For DosFindFirst/DosFindNext - level 2
|
||||
|
||||
typedef struct _FILEFINDBUF2 {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 FDATE fdateCreation;
|
||||
2 FTIME ftimeCreation;
|
||||
4 FDATE fdateLastAccess;
|
||||
6 FTIME ftimeLastAccess;
|
||||
8 FDATE fdateLastWrite;
|
||||
10 FTIME ftimeLastWrite;
|
||||
12 ULONG cbFile file length in bytes
|
||||
16 ULONG cbFileAlloc size of file allocation unit
|
||||
20 USHORT attrFile
|
||||
22 ULONG cbList Extended attribute list (always 0)
|
||||
26 UCHAR cchName length of name to follow (not including zero)
|
||||
27 UCHAR achName[MAXFILENAMELEN]; Null terminated name
|
||||
} FILEFINDBUF2;
|
||||
*************************************************************/
|
||||
|
||||
#define l2_fdateCreation 0
|
||||
#define l2_fdateLastAccess 4
|
||||
#define l2_fdateLastWrite 8
|
||||
#define l2_cbFile 12
|
||||
#define l2_cbFileAlloc 16
|
||||
#define l2_attrFile 20
|
||||
#define l2_cbList 22
|
||||
#define l2_cchName 26
|
||||
#define l2_achName 27
|
||||
|
||||
|
||||
/**********************************************************
|
||||
For DosFindFirst/DosFindNext - level 260
|
||||
|
||||
typedef struct _FILEFINDBUF260 {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 ULONG NextEntryOffset;
|
||||
4 ULONG FileIndex;
|
||||
8 LARGE_INTEGER CreationTime;
|
||||
16 LARGE_INTEGER LastAccessTime;
|
||||
24 LARGE_INTEGER LastWriteTime;
|
||||
32 LARGE_INTEGER ChangeTime;
|
||||
40 LARGE_INTEGER EndOfFile;
|
||||
48 LARGE_INTEGER AllocationSize;
|
||||
56 ULONG FileAttributes;
|
||||
60 ULONG FileNameLength;
|
||||
64 ULONG EaSize;
|
||||
68 CHAR ShortNameLength;
|
||||
70 UNICODE ShortName[12];
|
||||
94 UNICODE FileName[];
|
||||
*************************************************************/
|
||||
|
||||
#define l260_achName 94
|
||||
|
||||
|
||||
/**********************************************************
|
||||
For DosQueryPathInfo/DosQueryFileInfo/DosSetPathInfo/
|
||||
DosSetFileInfo - level 1
|
||||
|
||||
typedef struct _FILESTATUS {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 FDATE fdateCreation;
|
||||
2 FTIME ftimeCreation;
|
||||
4 FDATE fdateLastAccess;
|
||||
6 FTIME ftimeLastAccess;
|
||||
8 FDATE fdateLastWrite;
|
||||
10 FTIME ftimeLastWrite;
|
||||
12 ULONG cbFile file length in bytes
|
||||
16 ULONG cbFileAlloc size of file allocation unit
|
||||
20 USHORT attrFile
|
||||
} FILESTATUS;
|
||||
*************************************************************/
|
||||
|
||||
/* Use the l1_ defines from DosFindFirst */
|
||||
|
||||
/**********************************************************
|
||||
For DosQueryPathInfo/DosQueryFileInfo/DosSetPathInfo/
|
||||
DosSetFileInfo - level 2
|
||||
|
||||
typedef struct _FILESTATUS2 {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 FDATE fdateCreation;
|
||||
2 FTIME ftimeCreation;
|
||||
4 FDATE fdateLastAccess;
|
||||
6 FTIME ftimeLastAccess;
|
||||
8 FDATE fdateLastWrite;
|
||||
10 FTIME ftimeLastWrite;
|
||||
12 ULONG cbFile file length in bytes
|
||||
16 ULONG cbFileAlloc size of file allocation unit
|
||||
20 USHORT attrFile
|
||||
22 ULONG cbList Length of EA's (0)
|
||||
} FILESTATUS2;
|
||||
*************************************************************/
|
||||
|
||||
/* Use the l2_ #defines from DosFindFirst */
|
||||
|
||||
/**********************************************************
|
||||
For DosQFSInfo/DosSetFSInfo - level 1
|
||||
|
||||
typedef struct _FSALLOCATE {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 ULONG idFileSystem id of file system
|
||||
4 ULONG cSectorUnit number of sectors per allocation unit
|
||||
8 ULONG cUnit number of allocation units
|
||||
12 ULONG cUnitAvail Available allocation units
|
||||
16 USHORT cbSector bytes per sector
|
||||
} FSALLOCATE;
|
||||
*************************************************************/
|
||||
|
||||
#define l1_idFileSystem 0
|
||||
#define l1_cSectorUnit 4
|
||||
#define l1_cUnit 8
|
||||
#define l1_cUnitAvail 12
|
||||
#define l1_cbSector 16
|
||||
|
||||
/**********************************************************
|
||||
For DosQFSInfo/DosSetFSInfo - level 2
|
||||
|
||||
typedef struct _FSINFO {
|
||||
Byte offset Type name description
|
||||
-------------+-------+-------------------+--------------
|
||||
0 FDATE vol_fdateCreation
|
||||
2 FTIME vol_ftimeCreation
|
||||
4 UCHAR vol_cch length of volume name (excluding NULL)
|
||||
5 UCHAR vol_szVolLabel[12] volume name
|
||||
} FSINFO;
|
||||
*************************************************************/
|
||||
|
||||
#define SMB_QUERY_FS_LABEL_INFO 0x101
|
||||
#define SMB_QUERY_FS_VOLUME_INFO 0x102
|
||||
#define SMB_QUERY_FS_SIZE_INFO 0x103
|
||||
#define SMB_QUERY_FS_DEVICE_INFO 0x104
|
||||
#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105
|
||||
|
||||
|
||||
#define l2_vol_fdateCreation 0
|
||||
#define l2_vol_cch 4
|
||||
#define l2_vol_szVolLabel 5
|
||||
|
||||
|
||||
#define SMB_QUERY_FILE_BASIC_INFO 0x101
|
||||
#define SMB_QUERY_FILE_STANDARD_INFO 0x102
|
||||
#define SMB_QUERY_FILE_EA_INFO 0x103
|
||||
#define SMB_QUERY_FILE_NAME_INFO 0x104
|
||||
#define SMB_QUERY_FILE_ALLOCATION_INFO 0x105
|
||||
#define SMB_QUERY_FILE_END_OF_FILEINFO 0x106
|
||||
#define SMB_QUERY_FILE_ALL_INFO 0x107
|
||||
#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108
|
||||
#define SMB_QUERY_FILE_STREAM_INFO 0x109
|
||||
|
||||
#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
|
||||
#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
|
||||
#define SMB_FIND_FILE_NAMES_INFO 0x103
|
||||
#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104
|
||||
|
||||
#define SMB_SET_FILE_BASIC_INFO 0x101
|
||||
#define SMB_SET_FILE_DISPOSITION_INFO 0x102
|
||||
#define SMB_SET_FILE_ALLOCATION_INFO 0x103
|
||||
#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
|
||||
|
||||
#define DIRLEN_GUESS (45+MAX(l1_achName,l2_achName))
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
|
||||
int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
|
||||
int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
1
source3/include/version.h
Normal file
1
source3/include/version.h
Normal file
@ -0,0 +1 @@
|
||||
#define VERSION "1.9.16alpha1"
|
48
source3/include/vt_mode.h
Normal file
48
source3/include/vt_mode.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* vt_mode.h */
|
||||
/*
|
||||
support vtp-sessions
|
||||
|
||||
written by Christian A. Lademann <cal@zls.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
02.05.95:cal:ported to samba-1.9.13
|
||||
*/
|
||||
|
||||
#ifndef __vt_mode_h__
|
||||
# define __vt_mode_h__
|
||||
|
||||
# define VT_CLOSED 0
|
||||
# define VT_OPEN 1
|
||||
|
||||
# define MS_NONE 0
|
||||
# define MS_PTY 1
|
||||
# define MS_STREAM 2
|
||||
# define MS_VTY 3
|
||||
|
||||
# define VT_MAXREAD 32
|
||||
|
||||
|
||||
# undef EXTERN
|
||||
|
||||
# ifndef __vt_mode_c__
|
||||
# define EXTERN extern
|
||||
# define DEFAULT(v)
|
||||
# else
|
||||
# define EXTERN
|
||||
# define DEFAULT(v) =(v)
|
||||
# endif
|
||||
|
||||
EXTERN int VT_Status DEFAULT(VT_CLOSED),
|
||||
VT_Fd DEFAULT(-1),
|
||||
VT_ChildPID DEFAULT(-1);
|
||||
|
||||
EXTERN BOOL VT_Mode DEFAULT(False),
|
||||
VT_ChildDied DEFAULT(False);
|
||||
|
||||
EXTERN char *VT_Line DEFAULT(NULL);
|
||||
|
||||
# undef EXTERN
|
||||
|
||||
|
||||
#endif /* __vt_mode_h__ */
|
389
source3/lib/access.c
Normal file
389
source3/lib/access.c
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
This module is an adaption of code from the tcpd-1.4 package written
|
||||
by Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||
|
||||
The code is used here with permission.
|
||||
|
||||
The code has been considerably changed from the original. Bug reports
|
||||
should be sent to Andrew.Tridgell@anu.edu.au
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
#define ALLOW_PURE_ADDRESSES
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE ((unsigned long)~0)
|
||||
#endif
|
||||
|
||||
|
||||
#define FROM_ADDRLEN (4*3+3+1)
|
||||
#define Good True
|
||||
#define Bad False
|
||||
|
||||
#define CLIENT_MATCH client_match
|
||||
|
||||
/* Delimiters for lists of daemons or clients. */
|
||||
|
||||
static char sep[] = ", \t";
|
||||
|
||||
/* Constants to be used in assignments only, not in comparisons... */
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
#define FAIL (-1)
|
||||
|
||||
/* Forward declarations. */
|
||||
BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
|
||||
static int list_match(char *list,char *item, int (*match_fn)());
|
||||
static int client_match(char *tok,char *item);
|
||||
static int string_match(char *tok,char *s);
|
||||
static int masked_match(char *tok, char *slash, char *s);
|
||||
static int matchname(char *remotehost,struct in_addr addr);
|
||||
BOOL fromhost(int sock,struct from_host *f);
|
||||
|
||||
|
||||
/* Size of logical line buffer. */
|
||||
#define BUFLEN 2048
|
||||
|
||||
|
||||
/* return true if access should be allowed to a service*/
|
||||
BOOL check_access(int snum)
|
||||
{
|
||||
extern int Client;
|
||||
extern struct from_host Client_info;
|
||||
char *denyl,*allowl;
|
||||
BOOL ret = False;
|
||||
|
||||
denyl = lp_hostsdeny(snum);
|
||||
if (denyl) denyl = strdup(denyl);
|
||||
|
||||
allowl = lp_hostsallow(snum);
|
||||
if (allowl) allowl = strdup(allowl);
|
||||
|
||||
|
||||
fromhost(Client,&Client_info);
|
||||
|
||||
if ((!denyl || *denyl==0) && (!allowl || *allowl==0))
|
||||
ret = True;
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
if (!fromhost(Client,&Client_info))
|
||||
DEBUG(0,("ERROR: Can't get from_host info\n"));
|
||||
else
|
||||
{
|
||||
if (allow_access(denyl,allowl,&Client_info))
|
||||
{
|
||||
if (snum >= 0)
|
||||
DEBUG(2,("Allowed connection from %s (%s) to %s\n",
|
||||
Client_info.name,Client_info.addr,
|
||||
lp_servicename(snum)));
|
||||
ret = True;
|
||||
}
|
||||
else
|
||||
if (snum >= 0)
|
||||
DEBUG(0,("Denied connection from %s (%s) to %s\n",
|
||||
Client_info.name,Client_info.addr,
|
||||
lp_servicename(snum)));
|
||||
}
|
||||
}
|
||||
|
||||
if (denyl) free(denyl);
|
||||
if (allowl) free(allowl);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* return true if access should be allowed */
|
||||
BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client)
|
||||
{
|
||||
/* if theres no deny list and no allow list then allow access */
|
||||
if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0))
|
||||
return(True);
|
||||
|
||||
/* if there is an allow list but no deny list then allow only hosts
|
||||
on the allow list */
|
||||
if (!deny_list || *deny_list == 0)
|
||||
return(list_match(allow_list,(char *)client,CLIENT_MATCH));
|
||||
|
||||
/* if theres a deny list but no allow list then allow
|
||||
all hosts not on the deny list */
|
||||
if (!allow_list || *allow_list == 0)
|
||||
return(!list_match(deny_list,(char *)client,CLIENT_MATCH));
|
||||
|
||||
/* if there are both type of list then allow all hosts on the allow list */
|
||||
if (list_match(allow_list,(char *)client,CLIENT_MATCH))
|
||||
return (True);
|
||||
|
||||
/* if there are both type of list and it's not on the allow then
|
||||
allow it if its not on the deny */
|
||||
if (list_match(deny_list,(char *)client,CLIENT_MATCH))
|
||||
return (False);
|
||||
|
||||
return (True);
|
||||
}
|
||||
|
||||
/* list_match - match an item against a list of tokens with exceptions */
|
||||
/* (All modifications are marked with the initials "jkf") */
|
||||
static int list_match(char *list,char *item, int (*match_fn)())
|
||||
{
|
||||
char *tok;
|
||||
char *listcopy; /* jkf */
|
||||
int match = NO;
|
||||
|
||||
/*
|
||||
* jkf@soton.ac.uk -- 31 August 1994 -- Stop list_match()
|
||||
* overwriting the list given as its first parameter.
|
||||
*/
|
||||
|
||||
/* jkf -- can get called recursively with NULL list */
|
||||
listcopy = (list == 0) ? (char *)0 : strdup(list);
|
||||
|
||||
/*
|
||||
* Process tokens one at a time. We have exhausted all possible matches
|
||||
* when we reach an "EXCEPT" token or the end of the list. If we do find
|
||||
* a match, look for an "EXCEPT" list and recurse to determine whether
|
||||
* the match is affected by any exceptions.
|
||||
*/
|
||||
|
||||
for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep)) {
|
||||
if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
|
||||
break;
|
||||
if ((match = (*match_fn) (tok, item))) /* YES or FAIL */
|
||||
break;
|
||||
}
|
||||
/* Process exceptions to YES or FAIL matches. */
|
||||
|
||||
if (match != NO) {
|
||||
while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
|
||||
/* VOID */ ;
|
||||
if (tok == 0 || list_match((char *) 0, item, match_fn) == NO) {
|
||||
if (listcopy != 0) free(listcopy); /* jkf */
|
||||
return (match);
|
||||
}
|
||||
}
|
||||
|
||||
if (listcopy != 0) free(listcopy); /* jkf */
|
||||
return (NO);
|
||||
}
|
||||
|
||||
|
||||
/* client_match - match host name and address against token */
|
||||
static int client_match(char *tok,char *item)
|
||||
{
|
||||
struct from_host *client = (struct from_host *) item;
|
||||
int match;
|
||||
|
||||
/*
|
||||
* Try to match the address first. If that fails, try to match the host
|
||||
* name if available.
|
||||
*/
|
||||
|
||||
if ((match = string_match(tok, client->addr)) == 0)
|
||||
if (client->name[0] != 0)
|
||||
match = string_match(tok, client->name);
|
||||
return (match);
|
||||
}
|
||||
|
||||
/* string_match - match string against token */
|
||||
static int string_match(char *tok,char *s)
|
||||
{
|
||||
int tok_len;
|
||||
int str_len;
|
||||
char *cut;
|
||||
|
||||
/*
|
||||
* Return YES if a token has the magic value "ALL". Return FAIL if the
|
||||
* token is "FAIL". If the token starts with a "." (domain name), return
|
||||
* YES if it matches the last fields of the string. If the token has the
|
||||
* magic value "LOCAL", return YES if the string does not contain a "."
|
||||
* character. If the token ends on a "." (network number), return YES if
|
||||
* it matches the first fields of the string. If the token begins with a
|
||||
* "@" (netgroup name), return YES if the string is a (host) member of
|
||||
* the netgroup. Return YES if the token fully matches the string. If the
|
||||
* token is a netnumber/netmask pair, return YES if the address is a
|
||||
* member of the specified subnet.
|
||||
*/
|
||||
|
||||
if (tok[0] == '.') { /* domain: match last fields */
|
||||
if ((str_len = strlen(s)) > (tok_len = strlen(tok))
|
||||
&& strcasecmp(tok, s + str_len - tok_len) == 0)
|
||||
return (YES);
|
||||
} else if (tok[0] == '@') { /* netgroup: look it up */
|
||||
#ifdef NETGROUP
|
||||
static char *mydomain = NULL;
|
||||
char *hostname = NULL;
|
||||
BOOL netgroup_ok = False;
|
||||
|
||||
if (!mydomain) yp_get_default_domain(&mydomain);
|
||||
|
||||
if (!(hostname = strdup(s))) {
|
||||
DEBUG(1,("out of memory for strdup!\n"));
|
||||
return NO;
|
||||
}
|
||||
|
||||
netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);
|
||||
|
||||
DEBUG(5,("looking for %s of domain %s in netgroup %s gave %s\n",
|
||||
hostname,
|
||||
mydomain,
|
||||
tok+1,
|
||||
BOOLSTR(netgroup_ok)));
|
||||
|
||||
#ifdef NETGROUP_INSECURE
|
||||
/* if you really want netgroups that match non qualified names
|
||||
then define NETGROUP_INSECURE. It can, however, be a big
|
||||
security hole */
|
||||
{
|
||||
char *clnt_domain;
|
||||
if (!netgroup_ok && (clnt_domain=strchr(hostname,'.'))) {
|
||||
*clnt_domain++ = '\0';
|
||||
netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
free(hostname);
|
||||
|
||||
if (netgroup_ok) return(YES);
|
||||
#else
|
||||
DEBUG(0,("access: netgroup support is not configured"));
|
||||
return (NO);
|
||||
#endif
|
||||
} else if (strcasecmp(tok, "ALL") == 0) { /* all: match any */
|
||||
return (YES);
|
||||
} else if (strcasecmp(tok, "FAIL") == 0) { /* fail: match any */
|
||||
return (FAIL);
|
||||
} else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
|
||||
if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
|
||||
return (YES);
|
||||
} else if (!strcasecmp(tok, s)) { /* match host name or address */
|
||||
return (YES);
|
||||
} else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */
|
||||
if (strncmp(tok, s, tok_len) == 0)
|
||||
return (YES);
|
||||
} else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */
|
||||
if (isdigit(s[0]) && masked_match(tok, cut, s))
|
||||
return (YES);
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
|
||||
/* masked_match - match address against netnumber/netmask */
|
||||
static int masked_match(char *tok, char *slash, char *s)
|
||||
{
|
||||
unsigned long net;
|
||||
unsigned long mask;
|
||||
unsigned long addr;
|
||||
|
||||
if ((addr = interpret_addr(s)) == INADDR_NONE)
|
||||
return (NO);
|
||||
*slash = 0;
|
||||
net = interpret_addr(tok);
|
||||
*slash = '/';
|
||||
if (net == INADDR_NONE || (mask = interpret_addr(slash + 1)) == INADDR_NONE) {
|
||||
DEBUG(0,("access: bad net/mask access control: %s", tok));
|
||||
return (NO);
|
||||
}
|
||||
return ((addr & mask) == net);
|
||||
}
|
||||
|
||||
|
||||
/* fromhost - find out what is at the other end of a socket */
|
||||
BOOL fromhost(int sock,struct from_host *f)
|
||||
{
|
||||
static struct sockaddr sa;
|
||||
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
|
||||
struct hostent *hp;
|
||||
int length = sizeof(sa);
|
||||
static char addr_buf[FROM_ADDRLEN];
|
||||
static char name_buf[MAXHOSTNAMELEN];
|
||||
BOOL takeAddressAsHostname = False;
|
||||
|
||||
if (getpeername(sock, &sa, &length) < 0)
|
||||
{
|
||||
DEBUG(0,("getpeername failed\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
f->sin = sockin;
|
||||
f->addr = strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
|
||||
|
||||
/* Look up the remote host name. */
|
||||
if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
|
||||
sizeof(sockin->sin_addr),
|
||||
AF_INET)) == 0) {
|
||||
DEBUG(1,("Gethostbyaddr failed for %s\n",addr_buf));
|
||||
#ifdef ALLOW_PURE_ADDRESSES
|
||||
takeAddressAsHostname = True;
|
||||
#else
|
||||
return(False);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Save the host name. A later gethostbyxxx() call may clobber it. */
|
||||
f->name = StrnCpy(name_buf,
|
||||
takeAddressAsHostname? f->addr : hp->h_name,
|
||||
sizeof(name_buf) - 1);
|
||||
|
||||
/*
|
||||
* Verify that the host name does not belong to someone else. If host
|
||||
* name verification fails, pretend that the host name lookup failed.
|
||||
*/
|
||||
if (!takeAddressAsHostname && !matchname(f->name, sockin->sin_addr))
|
||||
{
|
||||
DEBUG(0,("Matchname failed\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
/* matchname - determine if host name matches IP address */
|
||||
static int matchname(char *remotehost,struct in_addr addr)
|
||||
{
|
||||
struct hostent *hp;
|
||||
int i;
|
||||
|
||||
if ((hp = Get_Hostbyname(remotehost)) == 0) {
|
||||
DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
|
||||
return (Bad);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that gethostbyname() returns the "correct" host name.
|
||||
* Unfortunately, gethostbyname("localhost") sometimes yields
|
||||
* "localhost.domain". Since the latter host name comes from the
|
||||
* local DNS, we just have to trust it (all bets are off if the local
|
||||
* DNS is perverted). We always check the address list, though.
|
||||
*/
|
||||
|
||||
if (strcasecmp(remotehost, hp->h_name)
|
||||
&& strcasecmp(remotehost, "localhost")) {
|
||||
DEBUG(0,("host name/name mismatch: %s != %s",
|
||||
remotehost, hp->h_name));
|
||||
return (Bad);
|
||||
}
|
||||
|
||||
/* Look up the host address in the address list we just got. */
|
||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
||||
if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
|
||||
return (Good);
|
||||
}
|
||||
|
||||
/*
|
||||
* The host name does not map to the original host address. Perhaps
|
||||
* someone has compromised a name server. More likely someone botched
|
||||
* it, but that could be dangerous, too.
|
||||
*/
|
||||
|
||||
DEBUG(0,("host name/address mismatch: %s != %s",
|
||||
inet_ntoa(addr), hp->h_name));
|
||||
return (Bad);
|
||||
}
|
||||
|
||||
|
126
source3/lib/charcnv.c
Normal file
126
source3/lib/charcnv.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Character set conversion Extensions
|
||||
Copyright (C) Andrew Tridgell 1992-1994
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#include "includes.h"
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
static char cvtbuf[1024];
|
||||
|
||||
static mapsinited = 0;
|
||||
|
||||
static char unix2dos[256];
|
||||
static char dos2unix[256];
|
||||
|
||||
static void initmaps() {
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 256; k++) unix2dos[k] = k;
|
||||
for (k = 0; k < 256; k++) dos2unix[k] = k;
|
||||
|
||||
mapsinited = 1;
|
||||
}
|
||||
|
||||
static void update_map(char * str) {
|
||||
char *p;
|
||||
|
||||
for (p = str; *p; p++) {
|
||||
if (p[1]) {
|
||||
unix2dos[(unsigned char)*p] = p[1];
|
||||
dos2unix[(unsigned char)p[1]] = *p;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void initiso() {
|
||||
|
||||
if (!mapsinited) initmaps();
|
||||
|
||||
update_map("\241\255\242\233\243\234\244\236\245\235\246\272\247\025\250\251");
|
||||
update_map("\251\273\252\246\253\256\254\252\255\274\256\310\257\257\260\370");
|
||||
update_map("\261\361\262\375\263\264\264\265\265\266\266\024\267\371\270\267");
|
||||
update_map("\271\270\272\247\273\275\274\254\275\253\276\276\277\250\200\277");
|
||||
update_map("\301\300\302\301\303\302\304\216\305\217\306\222\307\200\310\303");
|
||||
update_map("\311\220\312\305\313\306\314\307\315\315\316\317\317\320\320\311");
|
||||
update_map("\321\245\322\321\323\322\324\323\325\324\326\231\327\312\330\325");
|
||||
update_map("\331\326\332\327\333\330\334\232\335\313\336\314\337\341\340\205");
|
||||
update_map("\341\240\342\203\343\331\344\204\345\206\346\221\347\207\350\212");
|
||||
update_map("\351\202\352\210\353\211\354\215\355\241\356\214\357\213\360\316");
|
||||
update_map("\361\244\362\225\363\242\364\223\365\332\366\224\367\366\370\362");
|
||||
update_map("\371\227\372\243\373\226\374\201\375\304\376\263\377\230");
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert unix to dos
|
||||
*/
|
||||
char *
|
||||
unix2dos_format(char *str,BOOL overwrite)
|
||||
{
|
||||
char *p;
|
||||
char *dp;
|
||||
|
||||
if (!mapsinited) initmaps();
|
||||
if (overwrite) {
|
||||
for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p];
|
||||
return str;
|
||||
} else {
|
||||
for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p];
|
||||
*dp = 0;
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dos to unix
|
||||
*/
|
||||
char *
|
||||
dos2unix_format (char *str, BOOL overwrite)
|
||||
{
|
||||
char *p;
|
||||
char *dp;
|
||||
|
||||
if (!mapsinited) initmaps();
|
||||
if (overwrite) {
|
||||
for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p];
|
||||
return str;
|
||||
} else {
|
||||
for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p];
|
||||
*dp = 0;
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Interpret character set.
|
||||
*/
|
||||
int
|
||||
interpret_character_set (char *str, int def)
|
||||
{
|
||||
|
||||
if (strequal (str, "iso8859-1")) {
|
||||
initiso();
|
||||
return def;
|
||||
} else {
|
||||
DEBUG(0,("unrecognized character set\n"));
|
||||
}
|
||||
return def;
|
||||
}
|
111
source3/lib/charset.c
Normal file
111
source3/lib/charset.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Character set handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define CHARSET_C
|
||||
#include "includes.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
char xx_dos_char_map[256];
|
||||
char xx_upper_char_map[256];
|
||||
char xx_lower_char_map[256];
|
||||
|
||||
char *dos_char_map = NULL;
|
||||
char *upper_char_map = NULL;
|
||||
char *lower_char_map = NULL;
|
||||
|
||||
static void add_dos_char(int lower, int upper)
|
||||
{
|
||||
DEBUG(6,("Adding chars 0%o 0%o\n",lower,upper));
|
||||
if (lower) dos_char_map[(char)lower] = 1;
|
||||
if (upper) dos_char_map[(char)upper] = 1;
|
||||
if (lower && upper) {
|
||||
lower_char_map[(char)upper] = (char)lower;
|
||||
upper_char_map[(char)lower] = (char)upper;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
initialise the charset arrays
|
||||
****************************************************************************/
|
||||
void charset_initialise(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
dos_char_map = &xx_dos_char_map[128];
|
||||
upper_char_map = &xx_upper_char_map[128];
|
||||
lower_char_map = &xx_lower_char_map[128];
|
||||
|
||||
for (i= -128;i<=127;i++) {
|
||||
dos_char_map[(char)i] = 0;
|
||||
}
|
||||
|
||||
for (i=0;i<=127;i++) {
|
||||
if (isalnum((char)i) || strchr("._^$~!#%&-{}()@'`",(char)i))
|
||||
add_dos_char(i,0);
|
||||
}
|
||||
|
||||
for (i= -128;i<=127;i++) {
|
||||
char c = (char)i;
|
||||
upper_char_map[i] = lower_char_map[i] = c;
|
||||
if (isupper(c)) lower_char_map[c] = tolower(c);
|
||||
if (islower(c)) upper_char_map[c] = toupper(c);
|
||||
}
|
||||
|
||||
/* valid for all DOS PC */
|
||||
add_dos_char(142,0); /* A trema */
|
||||
add_dos_char(143,0); /* A o */
|
||||
add_dos_char(144,0); /* E ' */
|
||||
add_dos_char(146,0); /* AE */
|
||||
add_dos_char(153,0); /* O trema */
|
||||
add_dos_char(154,0); /* U trema */
|
||||
add_dos_char(165,0); /* N tilda */
|
||||
add_dos_char(128,0); /* C cedille */
|
||||
add_dos_char(156,0); /* Pound */
|
||||
add_dos_char(183,0); /* A ` (WIN)*/
|
||||
add_dos_char(157,0); /* Phi (WIN)*/
|
||||
add_dos_char(212,0); /* E` (WIN)*/
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
add characters depending on a string passed by the user
|
||||
********************************************************************/
|
||||
void add_char_string(char *s)
|
||||
{
|
||||
char *extra_chars = (char *)strdup(s);
|
||||
char *t;
|
||||
if (!extra_chars) return;
|
||||
|
||||
for (t=strtok(extra_chars," \t\r\n"); t; t=strtok(NULL," \t\r\n")) {
|
||||
char c1=0,c2=0;
|
||||
int i1=0,i2=0;
|
||||
if (isdigit(*t) || (*t)=='-') {
|
||||
sscanf(t,"%i:%i",&i1,&i2);
|
||||
add_dos_char(i1,i2);
|
||||
} else {
|
||||
sscanf(t,"%c:%c",&c1,&c2);
|
||||
add_dos_char(c1,c2);
|
||||
}
|
||||
}
|
||||
|
||||
free(extra_chars);
|
||||
}
|
86
source3/lib/fault.c
Normal file
86
source3/lib/fault.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Critical Fault handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef LINUX
|
||||
#define __KERNEL__
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
|
||||
static void (*cont_fn)();
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
report a fault
|
||||
********************************************************************/
|
||||
static void fault_report(int sig)
|
||||
{
|
||||
DEBUG(0,("===============================================================\n"));
|
||||
DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION));
|
||||
DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
|
||||
DEBUG(0,("===============================================================\n"));
|
||||
|
||||
#if AJT
|
||||
ajt_panic();
|
||||
#endif
|
||||
|
||||
if (cont_fn)
|
||||
{
|
||||
fault_setup(cont_fn);
|
||||
cont_fn(NULL);
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV,SIGNAL_CAST SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS,SIGNAL_CAST SIG_DFL);
|
||||
#endif
|
||||
return; /* this should cause a core dump */
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
catch serious errors
|
||||
****************************************************************************/
|
||||
static void sig_fault(int sig)
|
||||
{
|
||||
fault_report(sig);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
setup our fault handlers
|
||||
********************************************************************/
|
||||
void fault_setup(void (*fn)())
|
||||
{
|
||||
cont_fn = fn;
|
||||
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV,SIGNAL_CAST sig_fault);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS,SIGNAL_CAST sig_fault);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
166
source3/lib/getsmbpass.c
Normal file
166
source3/lib/getsmbpass.c
Normal file
@ -0,0 +1,166 @@
|
||||
/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Modified to use with samba by Jeremy Allison, 8th July 1995. */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef REPLACE_GETPASS
|
||||
|
||||
#ifdef SYSV_TERMIO
|
||||
|
||||
/* SYSTEM V TERMIO HANDLING */
|
||||
|
||||
static struct termio t;
|
||||
|
||||
#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
|
||||
#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
|
||||
#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
|
||||
|
||||
#ifndef TCSAFLUSH
|
||||
#define TCSAFLUSH 1
|
||||
#endif
|
||||
|
||||
#ifndef TCSANOW
|
||||
#define TCSANOW 0
|
||||
#endif
|
||||
|
||||
int tcgetattr(int fd, struct termio *t)
|
||||
{
|
||||
return ioctl(fd, TCGETA, t);
|
||||
}
|
||||
|
||||
int tcsetattr(int fd, int flags, const struct termio *t)
|
||||
{
|
||||
if(flags & TCSAFLUSH)
|
||||
ioctl(fd, TCFLSH, TCIOFLUSH);
|
||||
return ioctl(fd, TCSETS, t);
|
||||
}
|
||||
|
||||
#else /* SYSV_TERMIO */
|
||||
#ifdef BSD_TERMIO
|
||||
|
||||
/* BSD TERMIO HANDLING */
|
||||
|
||||
static struct sgttyb t;
|
||||
|
||||
#define ECHO_IS_ON(t) ((t).sg_flags & ECHO)
|
||||
#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO)
|
||||
#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO)
|
||||
|
||||
#ifndef TCSAFLUSH
|
||||
#define TCSAFLUSH 1
|
||||
#endif
|
||||
|
||||
#ifndef TCSANOW
|
||||
#define TCSANOW 0
|
||||
#endif
|
||||
|
||||
int tcgetattr(int fd, struct sgttyb *t)
|
||||
{
|
||||
return ioctl(fd, TIOCGETP, (char *)t);
|
||||
}
|
||||
|
||||
int tcsetattr(int fd, int flags, const struct sgttyb *t)
|
||||
{
|
||||
return ioctl(fd, TIOCSETP, (char *)t);
|
||||
}
|
||||
|
||||
#else /* BSD_TERMIO */
|
||||
|
||||
/* POSIX TERMIO HANDLING */
|
||||
#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
|
||||
#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
|
||||
#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
|
||||
|
||||
static struct termios t;
|
||||
#endif /* BSD_TERMIO */
|
||||
#endif /* SYSV_TERMIO */
|
||||
|
||||
char *
|
||||
getsmbpass(char *prompt)
|
||||
{
|
||||
FILE *in, *out;
|
||||
int echo_off;
|
||||
static char buf[256];
|
||||
static size_t bufsize = sizeof(buf);
|
||||
size_t nread;
|
||||
|
||||
/* Catch problematic signals */
|
||||
signal(SIGINT, SIGNAL_CAST SIG_IGN);
|
||||
|
||||
/* Try to write to and read from the terminal if we can.
|
||||
If we can't open the terminal, use stderr and stdin. */
|
||||
|
||||
in = fopen ("/dev/tty", "w+");
|
||||
if (in == NULL)
|
||||
{
|
||||
in = stdin;
|
||||
out = stderr;
|
||||
}
|
||||
else
|
||||
out = in;
|
||||
|
||||
setvbuf(in, NULL, _IONBF, 0);
|
||||
|
||||
/* Turn echoing off if it is on now. */
|
||||
|
||||
if (tcgetattr (fileno (in), &t) == 0)
|
||||
{
|
||||
if (ECHO_IS_ON(t))
|
||||
{
|
||||
TURN_ECHO_OFF(t);
|
||||
echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
|
||||
TURN_ECHO_ON(t);
|
||||
}
|
||||
else
|
||||
echo_off = 0;
|
||||
}
|
||||
else
|
||||
echo_off = 0;
|
||||
|
||||
/* Write the prompt. */
|
||||
fputs (prompt, out);
|
||||
fflush (out);
|
||||
|
||||
/* Read the password. */
|
||||
buf[0] = 0;
|
||||
fgets(buf, bufsize, in);
|
||||
nread = strlen(buf);
|
||||
if (buf[nread - 1] == '\n')
|
||||
buf[nread - 1] = '\0';
|
||||
|
||||
/* Restore echoing. */
|
||||
if (echo_off)
|
||||
(void) tcsetattr (fileno (in), TCSANOW, &t);
|
||||
|
||||
if (in != stdin)
|
||||
/* We opened the terminal; now close it. */
|
||||
fclose (in);
|
||||
|
||||
/* Catch problematic signals */
|
||||
signal(SIGINT, SIGNAL_CAST SIG_DFL);
|
||||
|
||||
printf("\n");
|
||||
return buf;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void getsmbpasswd_dummy() {;}
|
||||
#endif
|
895
source3/lib/kanji.c
Normal file
895
source3/lib/kanji.c
Normal file
@ -0,0 +1,895 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Kanji Extensions
|
||||
Copyright (C) Andrew Tridgell 1992-1994
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
|
||||
and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
|
||||
and add all jis codes sequence type at 1995.8.16
|
||||
Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
|
||||
*/
|
||||
#ifdef KANJI
|
||||
|
||||
#define _KANJI_C_
|
||||
#include "includes.h"
|
||||
|
||||
/* coding system keep in */
|
||||
int coding_system = SJIS_CODE;
|
||||
|
||||
/* jis si/so sequence */
|
||||
char jis_kso = JIS_KSO;
|
||||
char jis_ksi = JIS_KSI;
|
||||
char hex_tag = HEXTAG;
|
||||
|
||||
/*******************************************************************
|
||||
SHIFT JIS functions
|
||||
********************************************************************/
|
||||
/*******************************************************************
|
||||
search token from S1 separated any char of S2
|
||||
S1 contain SHIFT JIS chars.
|
||||
********************************************************************/
|
||||
char *
|
||||
sj_strtok (char *s1, const char *s2)
|
||||
{
|
||||
static char *s = NULL;
|
||||
char *q;
|
||||
if (!s1) {
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
s1 = s;
|
||||
}
|
||||
for (q = s1; *s1; ) {
|
||||
if (is_shift_jis (*s1)) {
|
||||
s1 += 2;
|
||||
} else if (is_kana (*s1)) {
|
||||
s1++;
|
||||
} else {
|
||||
char *p = strchr (s2, *s1);
|
||||
if (p) {
|
||||
if (s1 != q) {
|
||||
s = s1 + 1;
|
||||
*s1 = '\0';
|
||||
return q;
|
||||
}
|
||||
q = s1 + 1;
|
||||
}
|
||||
s1++;
|
||||
}
|
||||
}
|
||||
s = NULL;
|
||||
if (*q) {
|
||||
return q;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
search string S2 from S1
|
||||
S1 contain SHIFT JIS chars.
|
||||
********************************************************************/
|
||||
char *
|
||||
sj_strstr (const char *s1, const char *s2)
|
||||
{
|
||||
register int len = strlen ((char *) s2);
|
||||
if (!*s2)
|
||||
return (char *) s1;
|
||||
for (;*s1;) {
|
||||
if (*s1 == *s2) {
|
||||
if (strncmp (s1, s2, len) == 0)
|
||||
return (char *) s1;
|
||||
}
|
||||
if (is_shift_jis (*s1)) {
|
||||
s1 += 2;
|
||||
} else {
|
||||
s1++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Search char C from beginning of S.
|
||||
S contain SHIFT JIS chars.
|
||||
********************************************************************/
|
||||
char *
|
||||
sj_strchr (const char *s, int c)
|
||||
{
|
||||
for (; *s; ) {
|
||||
if (*s == c)
|
||||
return (char *) s;
|
||||
if (is_shift_jis (*s)) {
|
||||
s += 2;
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Search char C end of S.
|
||||
S contain SHIFT JIS chars.
|
||||
********************************************************************/
|
||||
char *
|
||||
sj_strrchr (const char *s, int c)
|
||||
{
|
||||
register char *q;
|
||||
|
||||
for (q = 0; *s; ) {
|
||||
if (*s == c) {
|
||||
q = (char *) s;
|
||||
}
|
||||
if (is_shift_jis (*s)) {
|
||||
s += 2;
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Code conversion
|
||||
********************************************************************/
|
||||
/* convesion buffer */
|
||||
static char cvtbuf[1024];
|
||||
|
||||
/*******************************************************************
|
||||
EUC <-> SJIS
|
||||
********************************************************************/
|
||||
static int
|
||||
euc2sjis (register int hi, register int lo)
|
||||
{
|
||||
if (hi & 1)
|
||||
return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) |
|
||||
(lo - (lo >= 0xe0 ? 0x60 : 0x61));
|
||||
else
|
||||
return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2);
|
||||
}
|
||||
|
||||
static int
|
||||
sjis2euc (register int hi, register int lo)
|
||||
{
|
||||
if (lo >= 0x9f)
|
||||
return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
|
||||
else
|
||||
return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
|
||||
(lo + (lo >= 0x7f ? 0x60 : 0x61));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain SHIFT JIS codes to EUC codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_euc (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
char *save;
|
||||
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from;) {
|
||||
if (is_shift_jis (*from)) {
|
||||
int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
} else if (is_kana (*from)) {
|
||||
*out++ = euc_kana;
|
||||
*out++ = *from++;
|
||||
} else {
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy((char *) save, (char *) cvtbuf);
|
||||
return (char *) save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain EUC codes to SHIFT JIS codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
euc_to_sj (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
char *save;
|
||||
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from; ) {
|
||||
if (is_euc (*from)) {
|
||||
int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
} else if (is_euc_kana (*from)) {
|
||||
*out++ = from[1];
|
||||
from += 2;
|
||||
} else {
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy(save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
JIS7,JIS8,JUNET <-> SJIS
|
||||
********************************************************************/
|
||||
static int
|
||||
sjis2jis (register int hi, register int lo)
|
||||
{
|
||||
if (lo >= 0x9f)
|
||||
return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
|
||||
else
|
||||
return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
|
||||
(lo - (lo >= 0x7f ? 0x20 : 0x1f));
|
||||
}
|
||||
|
||||
static int
|
||||
jis2sjis (register int hi, register int lo)
|
||||
{
|
||||
if (hi & 1)
|
||||
return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) |
|
||||
(lo + (lo >= 0x60 ? 0x20 : 0x1f));
|
||||
else
|
||||
return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain JIS codes to SHIFT JIS codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
jis8_to_sj (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
register int shifted;
|
||||
char *save;
|
||||
|
||||
shifted = _KJ_ROMAN;
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from;) {
|
||||
if (is_esc (*from)) {
|
||||
if (is_so1 (from[1]) && is_so2 (from[2])) {
|
||||
shifted = _KJ_KANJI;
|
||||
from += 3;
|
||||
} else if (is_si1 (from[1]) && is_si2 (from[2])) {
|
||||
shifted = _KJ_ROMAN;
|
||||
from += 3;
|
||||
} else { /* sequence error */
|
||||
goto normal;
|
||||
}
|
||||
} else {
|
||||
normal:
|
||||
switch (shifted) {
|
||||
default:
|
||||
case _KJ_ROMAN:
|
||||
*out++ = *from++;
|
||||
break;
|
||||
case _KJ_KANJI:
|
||||
{
|
||||
int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy (save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain SHIFT JIS codes to JIS codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_jis8 (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
register int shifted;
|
||||
char *save;
|
||||
|
||||
shifted = _KJ_ROMAN;
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from; ) {
|
||||
if (is_shift_jis (*from)) {
|
||||
int code;
|
||||
switch (shifted) {
|
||||
case _KJ_ROMAN: /* to KANJI */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_so1;
|
||||
*out++ = jis_kso;
|
||||
shifted = _KJ_KANJI;
|
||||
break;
|
||||
}
|
||||
code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
} else {
|
||||
switch (shifted) {
|
||||
case _KJ_KANJI: /* to ROMAN/KANA */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_ksi;
|
||||
shifted = _KJ_ROMAN;
|
||||
break;
|
||||
}
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
switch (shifted) {
|
||||
case _KJ_KANJI: /* to ROMAN/KANA */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_ksi;
|
||||
shifted = _KJ_ROMAN;
|
||||
break;
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy (save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
jis7_to_sj (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
register int shifted;
|
||||
char *save;
|
||||
|
||||
shifted = _KJ_ROMAN;
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from;) {
|
||||
if (is_esc (*from)) {
|
||||
if (is_so1 (from[1]) && is_so2 (from[2])) {
|
||||
shifted = _KJ_KANJI;
|
||||
from += 3;
|
||||
} else if (is_si1 (from[1]) && is_si2 (from[2])) {
|
||||
shifted = _KJ_ROMAN;
|
||||
from += 3;
|
||||
} else { /* sequence error */
|
||||
goto normal;
|
||||
}
|
||||
} else if (is_so (*from)) {
|
||||
shifted = _KJ_KANA; /* to KANA */
|
||||
from++;
|
||||
} else if (is_si (*from)) {
|
||||
shifted = _KJ_ROMAN; /* to ROMAN */
|
||||
from++;
|
||||
} else {
|
||||
normal:
|
||||
switch (shifted) {
|
||||
default:
|
||||
case _KJ_ROMAN:
|
||||
*out++ = *from++;
|
||||
break;
|
||||
case _KJ_KANJI:
|
||||
{
|
||||
int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
}
|
||||
break;
|
||||
case _KJ_KANA:
|
||||
*out++ = ((int) from[0]) + 0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy (save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_jis7 (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
register int shifted;
|
||||
char *save;
|
||||
|
||||
shifted = _KJ_ROMAN;
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from; ) {
|
||||
if (is_shift_jis (*from)) {
|
||||
int code;
|
||||
switch (shifted) {
|
||||
case _KJ_KANA:
|
||||
*out++ = jis_si; /* to ROMAN and through down */
|
||||
case _KJ_ROMAN: /* to KANJI */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_so1;
|
||||
*out++ = jis_kso;
|
||||
shifted = _KJ_KANJI;
|
||||
break;
|
||||
}
|
||||
code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
} else if (is_kana (from[0])) {
|
||||
switch (shifted) {
|
||||
case _KJ_KANJI: /* to ROMAN */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_ksi;
|
||||
case _KJ_ROMAN: /* to KANA */
|
||||
*out++ = jis_so;
|
||||
shifted = _KJ_KANA;
|
||||
break;
|
||||
}
|
||||
*out++ = ((int) *from++) - 0x80;
|
||||
} else {
|
||||
switch (shifted) {
|
||||
case _KJ_KANA:
|
||||
*out++ = jis_si; /* to ROMAN */
|
||||
shifted = _KJ_ROMAN;
|
||||
break;
|
||||
case _KJ_KANJI: /* to ROMAN */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_ksi;
|
||||
shifted = _KJ_ROMAN;
|
||||
break;
|
||||
}
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
switch (shifted) {
|
||||
case _KJ_KANA:
|
||||
*out++ = jis_si; /* to ROMAN */
|
||||
break;
|
||||
case _KJ_KANJI: /* to ROMAN */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_ksi;
|
||||
break;
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy (save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
junet_to_sj (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
register int shifted;
|
||||
char *save;
|
||||
|
||||
shifted = _KJ_ROMAN;
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from;) {
|
||||
if (is_esc (*from)) {
|
||||
if (is_so1 (from[1]) && is_so2 (from[2])) {
|
||||
shifted = _KJ_KANJI;
|
||||
from += 3;
|
||||
} else if (is_si1 (from[1]) && is_si2 (from[2])) {
|
||||
shifted = _KJ_ROMAN;
|
||||
from += 3;
|
||||
} else if (is_juk1(from[1]) && is_juk2 (from[2])) {
|
||||
shifted = _KJ_KANA;
|
||||
from += 3;
|
||||
} else { /* sequence error */
|
||||
goto normal;
|
||||
}
|
||||
} else {
|
||||
normal:
|
||||
switch (shifted) {
|
||||
default:
|
||||
case _KJ_ROMAN:
|
||||
*out++ = *from++;
|
||||
break;
|
||||
case _KJ_KANJI:
|
||||
{
|
||||
int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
}
|
||||
break;
|
||||
case _KJ_KANA:
|
||||
*out++ = ((int) from[0]) + 0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy (save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
|
||||
return converted buffer
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_junet (const char *from, BOOL overwrite)
|
||||
{
|
||||
register char *out;
|
||||
register int shifted;
|
||||
char *save;
|
||||
|
||||
shifted = _KJ_ROMAN;
|
||||
save = (char *) from;
|
||||
for (out = cvtbuf; *from; ) {
|
||||
if (is_shift_jis (*from)) {
|
||||
int code;
|
||||
switch (shifted) {
|
||||
case _KJ_KANA:
|
||||
case _KJ_ROMAN: /* to KANJI */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_so1;
|
||||
*out++ = jis_so2;
|
||||
shifted = _KJ_KANJI;
|
||||
break;
|
||||
}
|
||||
code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
|
||||
*out++ = (code >> 8) & 0xff;
|
||||
*out++ = code;
|
||||
from += 2;
|
||||
} else if (is_kana (from[0])) {
|
||||
switch (shifted) {
|
||||
case _KJ_KANJI: /* to ROMAN */
|
||||
case _KJ_ROMAN: /* to KANA */
|
||||
*out++ = jis_esc;
|
||||
*out++ = junet_kana1;
|
||||
*out++ = junet_kana2;
|
||||
shifted = _KJ_KANA;
|
||||
break;
|
||||
}
|
||||
*out++ = ((int) *from++) - 0x80;
|
||||
} else {
|
||||
switch (shifted) {
|
||||
case _KJ_KANA:
|
||||
case _KJ_KANJI: /* to ROMAN */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_si2;
|
||||
shifted = _KJ_ROMAN;
|
||||
break;
|
||||
}
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
switch (shifted) {
|
||||
case _KJ_KANA:
|
||||
case _KJ_KANJI: /* to ROMAN */
|
||||
*out++ = jis_esc;
|
||||
*out++ = jis_si1;
|
||||
*out++ = jis_si2;
|
||||
break;
|
||||
}
|
||||
*out = 0;
|
||||
if (overwrite) {
|
||||
strcpy (save, (char *) cvtbuf);
|
||||
return save;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
HEX <-> SJIS
|
||||
********************************************************************/
|
||||
/* ":xx" -> a byte */
|
||||
static char *
|
||||
hex_to_sj (const char *from, BOOL overwrite)
|
||||
{
|
||||
char *sp, *dp;
|
||||
|
||||
sp = (char *) from;
|
||||
dp = cvtbuf;
|
||||
while (*sp) {
|
||||
if (*sp == hex_tag && isxdigit (sp[1]) && isxdigit (sp[2])) {
|
||||
*dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
|
||||
sp += 3;
|
||||
} else
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
*dp = '\0';
|
||||
if (overwrite) {
|
||||
strcpy ((char *) from, (char *) cvtbuf);
|
||||
return (char *) from;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
kanji/kana -> ":xx"
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_hex (const char *from, BOOL overwrite)
|
||||
{
|
||||
unsigned char *sp, *dp;
|
||||
|
||||
sp = (unsigned char*) from;
|
||||
dp = (unsigned char*) cvtbuf;
|
||||
while (*sp) {
|
||||
if (is_kana(*sp)) {
|
||||
*dp++ = hex_tag;
|
||||
*dp++ = bin2hex (((*sp)>>4)&0x0f);
|
||||
*dp++ = bin2hex ((*sp)&0x0f);
|
||||
sp++;
|
||||
} else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
|
||||
*dp++ = hex_tag;
|
||||
*dp++ = bin2hex (((*sp)>>4)&0x0f);
|
||||
*dp++ = bin2hex ((*sp)&0x0f);
|
||||
sp++;
|
||||
*dp++ = hex_tag;
|
||||
*dp++ = bin2hex (((*sp)>>4)&0x0f);
|
||||
*dp++ = bin2hex ((*sp)&0x0f);
|
||||
sp++;
|
||||
} else
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
*dp = '\0';
|
||||
if (overwrite) {
|
||||
strcpy ((char *) from, (char *) cvtbuf);
|
||||
return (char *) from;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
kanji/kana -> ":xx"
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_cap (const char *from, BOOL overwrite)
|
||||
{
|
||||
unsigned char *sp, *dp;
|
||||
|
||||
sp = (unsigned char*) from;
|
||||
dp = (unsigned char*) cvtbuf;
|
||||
while (*sp) {
|
||||
if (*sp >= 0x80) {
|
||||
*dp++ = hex_tag;
|
||||
*dp++ = bin2hex (((*sp)>>4)&0x0f);
|
||||
*dp++ = bin2hex ((*sp)&0x0f);
|
||||
sp++;
|
||||
} else {
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
*dp = '\0';
|
||||
if (overwrite) {
|
||||
strcpy ((char *) from, (char *) cvtbuf);
|
||||
return (char *) from;
|
||||
} else {
|
||||
return cvtbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
sj to sj
|
||||
********************************************************************/
|
||||
static char *
|
||||
sj_to_sj (const char *from, BOOL overwrite)
|
||||
{
|
||||
if (!overwrite) {
|
||||
strcpy (cvtbuf, (char *) from);
|
||||
return cvtbuf;
|
||||
} else {
|
||||
return (char *) from;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
conversion:
|
||||
_dos_to_unix _unix_to_dos
|
||||
************************************************************************/
|
||||
|
||||
char* (*_dos_to_unix) (const char *str, BOOL overwrite) = sj_to_sj;
|
||||
char* (*_unix_to_dos) (const char *str, BOOL overwrite) = sj_to_sj;
|
||||
|
||||
static int
|
||||
setup_string_function (int codes)
|
||||
{
|
||||
switch (codes) {
|
||||
default:
|
||||
case SJIS_CODE:
|
||||
_dos_to_unix = sj_to_sj;
|
||||
_unix_to_dos = sj_to_sj;
|
||||
|
||||
break;
|
||||
|
||||
case EUC_CODE:
|
||||
_dos_to_unix = sj_to_euc;
|
||||
_unix_to_dos = euc_to_sj;
|
||||
break;
|
||||
|
||||
case JIS7_CODE:
|
||||
_dos_to_unix = sj_to_jis7;
|
||||
_unix_to_dos = jis7_to_sj;
|
||||
break;
|
||||
|
||||
case JIS8_CODE:
|
||||
_dos_to_unix = sj_to_jis8;
|
||||
_unix_to_dos = jis8_to_sj;
|
||||
break;
|
||||
|
||||
case JUNET_CODE:
|
||||
_dos_to_unix = sj_to_junet;
|
||||
_unix_to_dos = junet_to_sj;
|
||||
break;
|
||||
|
||||
case HEX_CODE:
|
||||
_dos_to_unix = sj_to_hex;
|
||||
_unix_to_dos = hex_to_sj;
|
||||
break;
|
||||
|
||||
case CAP_CODE:
|
||||
_dos_to_unix = sj_to_cap;
|
||||
_unix_to_dos = hex_to_sj;
|
||||
break;
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interpret coding system.
|
||||
*/
|
||||
int
|
||||
interpret_coding_system (char *str, int def)
|
||||
{
|
||||
int codes = def;
|
||||
|
||||
if (strequal (str, "sjis")) {
|
||||
codes = SJIS_CODE;
|
||||
} else if (strequal (str, "euc")) {
|
||||
codes = EUC_CODE;
|
||||
} else if (strequal (str, "cap")) {
|
||||
codes = CAP_CODE;
|
||||
hex_tag = HEXTAG;
|
||||
} else if (strequal (str, "hex")) {
|
||||
codes = HEX_CODE;
|
||||
hex_tag = HEXTAG;
|
||||
} else if (strncasecmp (str, "hex", 3)) {
|
||||
codes = HEX_CODE;
|
||||
hex_tag = (str[3] ? str[3] : HEXTAG);
|
||||
} else if (strequal (str, "j8bb")) {
|
||||
codes = JIS8_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'B';
|
||||
} else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
|
||||
codes = JIS8_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'J';
|
||||
} else if (strequal (str, "j8bh")) {
|
||||
codes = JIS8_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'H';
|
||||
} else if (strequal (str, "j8@b")) {
|
||||
codes = JIS8_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'B';
|
||||
} else if (strequal (str, "j8@j")) {
|
||||
codes = JIS8_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'J';
|
||||
} else if (strequal (str, "j8@h")) {
|
||||
codes = JIS8_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'H';
|
||||
} else if (strequal (str, "j7bb")) {
|
||||
codes = JIS7_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'B';
|
||||
} else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
|
||||
codes = JIS7_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'J';
|
||||
} else if (strequal (str, "j7bh")) {
|
||||
codes = JIS7_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'H';
|
||||
} else if (strequal (str, "j7@b")) {
|
||||
codes = JIS7_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'B';
|
||||
} else if (strequal (str, "j7@j")) {
|
||||
codes = JIS7_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'J';
|
||||
} else if (strequal (str, "j7@h")) {
|
||||
codes = JIS7_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'H';
|
||||
} else if (strequal (str, "jubb")) {
|
||||
codes = JUNET_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'B';
|
||||
} else if (strequal (str, "jubj") || strequal (str, "junet")) {
|
||||
codes = JUNET_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'J';
|
||||
} else if (strequal (str, "jubh")) {
|
||||
codes = JUNET_CODE;
|
||||
jis_kso = 'B';
|
||||
jis_ksi = 'H';
|
||||
} else if (strequal (str, "ju@b")) {
|
||||
codes = JUNET_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'B';
|
||||
} else if (strequal (str, "ju@j")) {
|
||||
codes = JUNET_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'J';
|
||||
} else if (strequal (str, "ju@h")) {
|
||||
codes = JUNET_CODE;
|
||||
jis_kso = '@';
|
||||
jis_ksi = 'H';
|
||||
}
|
||||
return setup_string_function (codes);
|
||||
}
|
||||
#else
|
||||
int kanji_dummy_procedure(void)
|
||||
{return 0;}
|
||||
#endif /* KANJI */
|
299
source3/lib/md4.c
Normal file
299
source3/lib/md4.c
Normal file
@ -0,0 +1,299 @@
|
||||
#ifdef SMB_PASSWD
|
||||
/*
|
||||
This code is from rfc1186.
|
||||
*/
|
||||
|
||||
/*
|
||||
** ********************************************************************
|
||||
** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||
** Updated: 2/16/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
** To use MD4:
|
||||
** -- Include md4.h in your program
|
||||
** -- Declare an MDstruct MD to hold the state of the digest
|
||||
** computation.
|
||||
** -- Initialize MD using MDbegin(&MD)
|
||||
** -- For each full block (64 bytes) X you wish to process, call
|
||||
** MDupdate(&MD,X,512)
|
||||
** (512 is the number of bits in a full block.)
|
||||
** -- For the last block (less than 64 bytes) you wish to process,
|
||||
** MDupdate(&MD,X,n)
|
||||
** where n is the number of bits in the partial block. A partial
|
||||
** block terminates the computation, so every MD computation
|
||||
** should terminate by processing a partial block, even if it
|
||||
** has n = 0.
|
||||
** -- The message digest is available in MD.buffer[0] ...
|
||||
** MD.buffer[3]. (Least-significant byte of each word
|
||||
** should be output first.)
|
||||
** -- You can print out the digest using MDprint(&MD)
|
||||
*/
|
||||
|
||||
/* Implementation notes:
|
||||
** This implementation assumes that ints are 32-bit quantities.
|
||||
** If the machine stores the least-significant byte of an int in the
|
||||
** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
|
||||
** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST
|
||||
** should be set to FALSE. Note that on machines with LOWBYTEFIRST
|
||||
** FALSE the routine MDupdate modifies has a side-effect on its input
|
||||
** array (the order of bytes in each word are reversed). If this is
|
||||
** undesired a call to MDreverse(X) can reverse the bytes of X back
|
||||
** into order after each call to MDupdate.
|
||||
*/
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
/* Compile-time includes
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "md4.h"
|
||||
|
||||
#define uchar unsigned char
|
||||
#define int16 unsigned short
|
||||
#define uint32 unsigned int
|
||||
|
||||
#include "byteorder.h"
|
||||
|
||||
/* Compile-time declarations of MD4 "magic constants".
|
||||
*/
|
||||
#define I0 0x67452301 /* Initial values for MD buffer */
|
||||
#define I1 0xefcdab89
|
||||
#define I2 0x98badcfe
|
||||
#define I3 0x10325476
|
||||
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
|
||||
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
|
||||
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
|
||||
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
|
||||
** Table 2, page 660.
|
||||
*/
|
||||
|
||||
#define fs1 3 /* round 1 shift amounts */
|
||||
#define fs2 7
|
||||
#define fs3 11
|
||||
#define fs4 19
|
||||
#define gs1 3 /* round 2 shift amounts */
|
||||
#define gs2 5
|
||||
#define gs3 9
|
||||
#define gs4 13
|
||||
#define hs1 3 /* round 3 shift amounts */
|
||||
#define hs2 9
|
||||
#define hs3 11
|
||||
#define hs4 15
|
||||
|
||||
/* Compile-time macro declarations for MD4.
|
||||
** Note: The "rot" operator uses the variable "tmp".
|
||||
** It assumes tmp is declared as unsigned int, so that the >>
|
||||
** operator will shift in zeros rather than extending the sign bit.
|
||||
*/
|
||||
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
|
||||
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
|
||||
#define h(X,Y,Z) (X^Y^Z)
|
||||
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
|
||||
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
|
||||
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
|
||||
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
|
||||
|
||||
/* MDprint(MDp)
|
||||
** Print message digest buffer MDp as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte of
|
||||
** buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MDprint(MDp)
|
||||
MDptr MDp;
|
||||
{ int i,j;
|
||||
for (i=0;i<4;i++)
|
||||
for (j=0;j<32;j=j+8)
|
||||
printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
|
||||
}
|
||||
|
||||
/* MDbegin(MDp)
|
||||
** Initialize message digest buffer MDp.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MDbegin(MDp)
|
||||
MDptr MDp;
|
||||
{ int i;
|
||||
MDp->buffer[0] = I0;
|
||||
MDp->buffer[1] = I1;
|
||||
MDp->buffer[2] = I2;
|
||||
MDp->buffer[3] = I3;
|
||||
for (i=0;i<8;i++) MDp->count[i] = 0;
|
||||
MDp->done = 0;
|
||||
}
|
||||
|
||||
/* MDreverse(X)
|
||||
** Reverse the byte-ordering of every int in X.
|
||||
** Assumes X is an array of 16 ints.
|
||||
** The macro revx reverses the byte-ordering of the next word of X.
|
||||
*/
|
||||
void MDreverse(X)
|
||||
unsigned int *X;
|
||||
{ register unsigned int t;
|
||||
register unsigned int i;
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
t = X[i];
|
||||
SIVAL(X,i*4,t);
|
||||
}
|
||||
}
|
||||
|
||||
/* MDblock(MDp,X)
|
||||
** Update message digest buffer MDp->buffer using 16-word data block X.
|
||||
** Assumes all 16 words of X are full of data.
|
||||
** Does not update MDp->count.
|
||||
** This routine is not user-callable.
|
||||
*/
|
||||
static void
|
||||
MDblock(MDp,X)
|
||||
MDptr MDp;
|
||||
unsigned int *X;
|
||||
{
|
||||
register unsigned int tmp, A, B, C, D;
|
||||
MDreverse(X);
|
||||
A = MDp->buffer[0];
|
||||
B = MDp->buffer[1];
|
||||
C = MDp->buffer[2];
|
||||
D = MDp->buffer[3];
|
||||
/* Update the message digest buffer */
|
||||
ff(A , B , C , D , 0 , fs1); /* Round 1 */
|
||||
ff(D , A , B , C , 1 , fs2);
|
||||
ff(C , D , A , B , 2 , fs3);
|
||||
ff(B , C , D , A , 3 , fs4);
|
||||
ff(A , B , C , D , 4 , fs1);
|
||||
ff(D , A , B , C , 5 , fs2);
|
||||
ff(C , D , A , B , 6 , fs3);
|
||||
ff(B , C , D , A , 7 , fs4);
|
||||
ff(A , B , C , D , 8 , fs1);
|
||||
ff(D , A , B , C , 9 , fs2);
|
||||
ff(C , D , A , B , 10 , fs3);
|
||||
ff(B , C , D , A , 11 , fs4);
|
||||
ff(A , B , C , D , 12 , fs1);
|
||||
ff(D , A , B , C , 13 , fs2);
|
||||
ff(C , D , A , B , 14 , fs3);
|
||||
ff(B , C , D , A , 15 , fs4);
|
||||
gg(A , B , C , D , 0 , gs1); /* Round 2 */
|
||||
gg(D , A , B , C , 4 , gs2);
|
||||
gg(C , D , A , B , 8 , gs3);
|
||||
gg(B , C , D , A , 12 , gs4);
|
||||
gg(A , B , C , D , 1 , gs1);
|
||||
gg(D , A , B , C , 5 , gs2);
|
||||
gg(C , D , A , B , 9 , gs3);
|
||||
gg(B , C , D , A , 13 , gs4);
|
||||
gg(A , B , C , D , 2 , gs1);
|
||||
gg(D , A , B , C , 6 , gs2);
|
||||
gg(C , D , A , B , 10 , gs3);
|
||||
gg(B , C , D , A , 14 , gs4);
|
||||
gg(A , B , C , D , 3 , gs1);
|
||||
gg(D , A , B , C , 7 , gs2);
|
||||
gg(C , D , A , B , 11 , gs3);
|
||||
gg(B , C , D , A , 15 , gs4);
|
||||
hh(A , B , C , D , 0 , hs1); /* Round 3 */
|
||||
hh(D , A , B , C , 8 , hs2);
|
||||
hh(C , D , A , B , 4 , hs3);
|
||||
hh(B , C , D , A , 12 , hs4);
|
||||
hh(A , B , C , D , 2 , hs1);
|
||||
hh(D , A , B , C , 10 , hs2);
|
||||
hh(C , D , A , B , 6 , hs3);
|
||||
hh(B , C , D , A , 14 , hs4);
|
||||
hh(A , B , C , D , 1 , hs1);
|
||||
hh(D , A , B , C , 9 , hs2);
|
||||
hh(C , D , A , B , 5 , hs3);
|
||||
hh(B , C , D , A , 13 , hs4);
|
||||
hh(A , B , C , D , 3 , hs1);
|
||||
hh(D , A , B , C , 11 , hs2);
|
||||
hh(C , D , A , B , 7 , hs3);
|
||||
hh(B , C , D , A , 15 , hs4);
|
||||
MDp->buffer[0] += A;
|
||||
MDp->buffer[1] += B;
|
||||
MDp->buffer[2] += C;
|
||||
MDp->buffer[3] += D;
|
||||
}
|
||||
|
||||
/* MDupdate(MDp,X,count)
|
||||
** Input: MDp -- an MDptr
|
||||
** X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use.
|
||||
** (if not a multiple of 8, uses high bits of last byte.)
|
||||
** Update MDp using the number of bits of X given by count.
|
||||
** This is the basic input routine for an MD4 user.
|
||||
** The routine completes the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MDupdate with a
|
||||
** count less than 512. A call with count 0 will be ignored if the
|
||||
** MD has already been terminated (done != 0), so an extra call with
|
||||
** count 0 can be given as a "courtesy close" to force termination
|
||||
** if desired.
|
||||
*/
|
||||
void
|
||||
MDupdate(MDp,X,count)
|
||||
MDptr MDp;
|
||||
unsigned char *X;
|
||||
unsigned int count;
|
||||
{ unsigned int i, tmp, bit, byte, mask;
|
||||
unsigned char XX[64];
|
||||
unsigned char *p;
|
||||
/* return with no error if this is a courtesy close with count
|
||||
** zero and MDp->done is true.
|
||||
*/
|
||||
if (count == 0 && MDp->done) return;
|
||||
/* check to see if MD is already done and report error */
|
||||
if (MDp->done)
|
||||
{ printf("\nError: MDupdate MD already done."); return; }
|
||||
/* Add count to MDp->count */
|
||||
tmp = count;
|
||||
p = MDp->count;
|
||||
while (tmp)
|
||||
{ tmp += *p;
|
||||
*p++ = tmp;
|
||||
tmp = tmp >> 8;
|
||||
}
|
||||
/* Process data */
|
||||
if (count == 512)
|
||||
{ /* Full block of data to handle */
|
||||
MDblock(MDp,(unsigned int *)X);
|
||||
}
|
||||
else if (count > 512) /* Check for count too large */
|
||||
{ printf("\nError: MDupdate called with illegal count value %d."
|
||||
,count);
|
||||
return;
|
||||
}
|
||||
else /* partial block -- must be last block so finish up */
|
||||
{ /* Find out how many bytes and residual bits there are */
|
||||
byte = count >> 3;
|
||||
bit = count & 7;
|
||||
/* Copy X into XX since we need to modify it */
|
||||
for (i=0;i<=byte;i++) XX[i] = X[i];
|
||||
for (i=byte+1;i<64;i++) XX[i] = 0;
|
||||
/* Add padding '1' bit and low-order zeros in last byte */
|
||||
mask = 1 << (7 - bit);
|
||||
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
|
||||
/* If room for bit count, finish up with this block */
|
||||
if (byte <= 55)
|
||||
{ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,(unsigned int *)XX);
|
||||
}
|
||||
else /* need to do two blocks to finish up */
|
||||
{ MDblock(MDp,(unsigned int *)XX);
|
||||
for (i=0;i<56;i++) XX[i] = 0;
|
||||
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,(unsigned int *)XX);
|
||||
}
|
||||
/* Set flag saying we're done with MD computation */
|
||||
MDp->done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** End of md4.c
|
||||
*/
|
||||
#else
|
||||
void md4_dummy() {;}
|
||||
#endif
|
222
source3/lib/system.c
Normal file
222
source3/lib/system.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Samba system utilities
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
/*
|
||||
The idea is that this file will eventually have wrappers around all
|
||||
important system calls in samba. The aim is twofold:
|
||||
|
||||
- to enable easier porting by putting OS dependent stuff in here
|
||||
|
||||
- to allow for hooks into other "pseudo-filesystems"
|
||||
|
||||
- to allow easier integration of things like the japanese extensions
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
this replaces the normal select() system call
|
||||
return if some data has arrived on one of the file descriptors
|
||||
return -1 means error
|
||||
********************************************************************/
|
||||
#ifdef NO_SELECT
|
||||
static int pollfd(int fd)
|
||||
{
|
||||
int r=0;
|
||||
|
||||
#ifdef HAS_RDCHK
|
||||
r = rdchk(fd);
|
||||
#elif defined(TCRDCHK)
|
||||
(void)ioctl(fd, TCRDCHK, &r);
|
||||
#else
|
||||
(void)ioctl(fd, FIONREAD, &r);
|
||||
#endif
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
int sys_select(fd_set *fds,struct timeval *tval)
|
||||
{
|
||||
fd_set fds2;
|
||||
int counter=0;
|
||||
int found=0;
|
||||
|
||||
FD_ZERO(&fds2);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<255;i++) {
|
||||
if (FD_ISSET(i,fds) && pollfd(i)>0) {
|
||||
found++;
|
||||
FD_SET(i,&fds2);
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
memcpy((void *)fds,(void *)&fds2,sizeof(fds2));
|
||||
return(found);
|
||||
}
|
||||
|
||||
if (tval && tval.tv_sec < counter) return(0);
|
||||
sleep(1);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
int sys_select(fd_set *fds,struct timeval *tval)
|
||||
{
|
||||
struct timeval t2;
|
||||
int selrtn;
|
||||
|
||||
do {
|
||||
if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
|
||||
errno = 0;
|
||||
selrtn = select(16,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
|
||||
} while (selrtn<0 && errno == EINTR);
|
||||
|
||||
return(selrtn);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
just a unlink wrapper
|
||||
********************************************************************/
|
||||
int sys_unlink(char *fname)
|
||||
{
|
||||
return(unlink(dos_to_unix(fname,False)));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
a simple open() wrapper
|
||||
********************************************************************/
|
||||
int sys_open(char *fname,int flags,int mode)
|
||||
{
|
||||
return(open(dos_to_unix(fname,False),flags,mode));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
a simple opendir() wrapper
|
||||
********************************************************************/
|
||||
DIR *sys_opendir(char *dname)
|
||||
{
|
||||
return(opendir(dos_to_unix(dname,False)));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
and a stat() wrapper
|
||||
********************************************************************/
|
||||
int sys_stat(char *fname,struct stat *sbuf)
|
||||
{
|
||||
return(stat(dos_to_unix(fname,False),sbuf));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
don't forget lstat()
|
||||
********************************************************************/
|
||||
int sys_lstat(char *fname,struct stat *sbuf)
|
||||
{
|
||||
return(lstat(dos_to_unix(fname,False),sbuf));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
mkdir() gets a wrapper
|
||||
********************************************************************/
|
||||
int sys_mkdir(char *dname,int mode)
|
||||
{
|
||||
return(mkdir(dos_to_unix(dname,False),mode));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
do does rmdir()
|
||||
********************************************************************/
|
||||
int sys_rmdir(char *dname)
|
||||
{
|
||||
return(rmdir(dos_to_unix(dname,False)));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
I almost forgot chdir()
|
||||
********************************************************************/
|
||||
int sys_chdir(char *dname)
|
||||
{
|
||||
return(chdir(dos_to_unix(dname,False)));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
now for utime()
|
||||
********************************************************************/
|
||||
int sys_utime(char *fname,struct utimbuf *times)
|
||||
{
|
||||
return(utime(dos_to_unix(fname,False),times));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
for rename()
|
||||
********************************************************************/
|
||||
int sys_rename(char *from, char *to)
|
||||
{
|
||||
#ifdef KANJI
|
||||
pstring zfrom, zto;
|
||||
strcpy (zfrom, dos_to_unix (from, False));
|
||||
strcpy (zto, dos_to_unix (to, False));
|
||||
return rename (zfrom, zto);
|
||||
#else
|
||||
return rename (from, to);
|
||||
#endif /* KANJI */
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
chown isn't used much but OS/2 doesn't have it
|
||||
********************************************************************/
|
||||
int sys_chown(char *fname,int uid,int gid)
|
||||
{
|
||||
#ifdef NO_CHOWN
|
||||
DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid));
|
||||
#else
|
||||
return(chown(fname,uid,gid));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
os/2 also doesn't have chroot
|
||||
********************************************************************/
|
||||
int sys_chroot(char *dname)
|
||||
{
|
||||
#ifdef NO_CHROOT
|
||||
DEBUG(1,("Warning - chroot(%s) not done\n",dname));
|
||||
#else
|
||||
return(chroot(dname));
|
||||
#endif
|
||||
}
|
782
source3/lib/ufc.c
Normal file
782
source3/lib/ufc.c
Normal file
@ -0,0 +1,782 @@
|
||||
/*
|
||||
This bit of code was derived from the UFC-crypt package which
|
||||
carries the following copyright
|
||||
|
||||
Modified for use by Samba by Andrew Tridgell, October 1994
|
||||
|
||||
Note that this routine is only faster on some machines. Under Linux 1.1.51
|
||||
libc 4.5.26 I actually found this routine to be slightly slower.
|
||||
|
||||
Under SunOS I found a huge speedup by using these routines
|
||||
(a factor of 20 or so)
|
||||
|
||||
Warning: I've had a report from Steve Kennedy <steve@gbnet.org>
|
||||
that this crypt routine may sometimes get the wrong answer. Only
|
||||
use UFC_CRYT if you really need it.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef UFC_CRYPT
|
||||
|
||||
/*
|
||||
* UFC-crypt: ultra fast crypt(3) implementation
|
||||
*
|
||||
* Copyright (C) 1991, 1992, Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* @(#)crypt_util.c 2.31 02/08/92
|
||||
*
|
||||
* Support routines
|
||||
*
|
||||
*/
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
#ifndef long32
|
||||
#define long32 int32
|
||||
#endif
|
||||
|
||||
#ifndef long64
|
||||
#define long64 int64
|
||||
#endif
|
||||
|
||||
#ifndef ufc_long
|
||||
#define ufc_long unsigned
|
||||
#endif
|
||||
|
||||
#ifndef _UFC_64_
|
||||
#define _UFC_32_
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Permutation done once on the 56 bit
|
||||
* key derived from the original 8 byte ASCII key.
|
||||
*/
|
||||
static int pc1[56] = {
|
||||
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
|
||||
};
|
||||
|
||||
/*
|
||||
* How much to rotate each 28 bit half of the pc1 permutated
|
||||
* 56 bit key before using pc2 to give the i' key
|
||||
*/
|
||||
static int rots[16] = {
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Permutation giving the key
|
||||
* of the i' DES round
|
||||
*/
|
||||
static int pc2[48] = {
|
||||
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
|
||||
};
|
||||
|
||||
/*
|
||||
* The E expansion table which selects
|
||||
* bits from the 32 bit intermediate result.
|
||||
*/
|
||||
static int esel[48] = {
|
||||
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
|
||||
};
|
||||
static int e_inverse[64];
|
||||
|
||||
/*
|
||||
* Permutation done on the
|
||||
* result of sbox lookups
|
||||
*/
|
||||
static int perm32[32] = {
|
||||
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
|
||||
};
|
||||
|
||||
/*
|
||||
* The sboxes
|
||||
*/
|
||||
static int sbox[8][4][16]= {
|
||||
{ { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
|
||||
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
|
||||
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
|
||||
{ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
|
||||
},
|
||||
|
||||
{ { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
|
||||
{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
|
||||
{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
|
||||
{ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
|
||||
},
|
||||
|
||||
{ { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
|
||||
{ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
|
||||
{ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
|
||||
{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
|
||||
},
|
||||
|
||||
{ { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
|
||||
{ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
|
||||
{ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
|
||||
{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
|
||||
},
|
||||
|
||||
{ { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
|
||||
{ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
|
||||
{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
|
||||
{ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
|
||||
},
|
||||
|
||||
{ { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
|
||||
{ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
|
||||
{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
|
||||
{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
|
||||
},
|
||||
|
||||
{ { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
|
||||
{ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
|
||||
{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
|
||||
{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
|
||||
},
|
||||
|
||||
{ { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
|
||||
{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
|
||||
{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
|
||||
{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the final
|
||||
* permutation matrix
|
||||
*/
|
||||
static int final_perm[64] = {
|
||||
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
|
||||
};
|
||||
|
||||
/*
|
||||
* The 16 DES keys in BITMASK format
|
||||
*/
|
||||
#ifdef _UFC_32_
|
||||
long32 _ufc_keytab[16][2];
|
||||
#endif
|
||||
|
||||
#ifdef _UFC_64_
|
||||
long64 _ufc_keytab[16];
|
||||
#endif
|
||||
|
||||
|
||||
#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
|
||||
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
|
||||
|
||||
/* Macro to set a bit (0..23) */
|
||||
#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) )
|
||||
|
||||
/*
|
||||
* sb arrays:
|
||||
*
|
||||
* Workhorses of the inner loop of the DES implementation.
|
||||
* They do sbox lookup, shifting of this value, 32 bit
|
||||
* permutation and E permutation for the next round.
|
||||
*
|
||||
* Kept in 'BITMASK' format.
|
||||
*/
|
||||
|
||||
#ifdef _UFC_32_
|
||||
long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192];
|
||||
static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
|
||||
#endif
|
||||
|
||||
#ifdef _UFC_64_
|
||||
long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096];
|
||||
static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* eperm32tab: do 32 bit permutation and E selection
|
||||
*
|
||||
* The first index is the byte number in the 32 bit value to be permuted
|
||||
* - second - is the value of this byte
|
||||
* - third - selects the two 32 bit values
|
||||
*
|
||||
* The table is used and generated internally in init_des to speed it up
|
||||
*/
|
||||
static ufc_long eperm32tab[4][256][2];
|
||||
|
||||
/*
|
||||
* do_pc1: permform pc1 permutation in the key schedule generation.
|
||||
*
|
||||
* The first index is the byte number in the 8 byte ASCII key
|
||||
* - second - - the two 28 bits halfs of the result
|
||||
* - third - selects the 7 bits actually used of each byte
|
||||
*
|
||||
* The result is kept with 28 bit per 32 bit with the 4 most significant
|
||||
* bits zero.
|
||||
*/
|
||||
static ufc_long do_pc1[8][2][128];
|
||||
|
||||
/*
|
||||
* do_pc2: permform pc2 permutation in the key schedule generation.
|
||||
*
|
||||
* The first index is the septet number in the two 28 bit intermediate values
|
||||
* - second - - - septet values
|
||||
*
|
||||
* Knowledge of the structure of the pc2 permutation is used.
|
||||
*
|
||||
* The result is kept with 28 bit per 32 bit with the 4 most significant
|
||||
* bits zero.
|
||||
*/
|
||||
static ufc_long do_pc2[8][128];
|
||||
|
||||
/*
|
||||
* efp: undo an extra e selection and do final
|
||||
* permutation giving the DES result.
|
||||
*
|
||||
* Invoked 6 bit a time on two 48 bit values
|
||||
* giving two 32 bit longs.
|
||||
*/
|
||||
static ufc_long efp[16][64][2];
|
||||
|
||||
static unsigned char bytemask[8] = {
|
||||
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
|
||||
};
|
||||
|
||||
static ufc_long longmask[32] = {
|
||||
0x80000000, 0x40000000, 0x20000000, 0x10000000,
|
||||
0x08000000, 0x04000000, 0x02000000, 0x01000000,
|
||||
0x00800000, 0x00400000, 0x00200000, 0x00100000,
|
||||
0x00080000, 0x00040000, 0x00020000, 0x00010000,
|
||||
0x00008000, 0x00004000, 0x00002000, 0x00001000,
|
||||
0x00000800, 0x00000400, 0x00000200, 0x00000100,
|
||||
0x00000080, 0x00000040, 0x00000020, 0x00000010,
|
||||
0x00000008, 0x00000004, 0x00000002, 0x00000001
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Silly rewrite of 'bzero'. I do so
|
||||
* because some machines don't have
|
||||
* bzero and some don't have memset.
|
||||
*/
|
||||
|
||||
static void clearmem(start, cnt)
|
||||
char *start;
|
||||
int cnt;
|
||||
{ while(cnt--)
|
||||
*start++ = '\0';
|
||||
}
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
/* lookup a 6 bit value in sbox */
|
||||
|
||||
#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
|
||||
|
||||
/*
|
||||
* Initialize unit - may be invoked directly
|
||||
* by fcrypt users.
|
||||
*/
|
||||
|
||||
static void ufc_init_des()
|
||||
{ int comes_from_bit;
|
||||
int bit, sg;
|
||||
ufc_long j;
|
||||
ufc_long mask1, mask2;
|
||||
|
||||
/*
|
||||
* Create the do_pc1 table used
|
||||
* to affect pc1 permutation
|
||||
* when generating keys
|
||||
*/
|
||||
for(bit = 0; bit < 56; bit++) {
|
||||
comes_from_bit = pc1[bit] - 1;
|
||||
mask1 = bytemask[comes_from_bit % 8 + 1];
|
||||
mask2 = longmask[bit % 28 + 4];
|
||||
for(j = 0; j < 128; j++) {
|
||||
if(j & mask1)
|
||||
do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the do_pc2 table used
|
||||
* to affect pc2 permutation when
|
||||
* generating keys
|
||||
*/
|
||||
for(bit = 0; bit < 48; bit++) {
|
||||
comes_from_bit = pc2[bit] - 1;
|
||||
mask1 = bytemask[comes_from_bit % 7 + 1];
|
||||
mask2 = BITMASK(bit % 24);
|
||||
for(j = 0; j < 128; j++) {
|
||||
if(j & mask1)
|
||||
do_pc2[comes_from_bit / 7][j] |= mask2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now generate the table used to do combined
|
||||
* 32 bit permutation and e expansion
|
||||
*
|
||||
* We use it because we have to permute 16384 32 bit
|
||||
* longs into 48 bit in order to initialize sb.
|
||||
*
|
||||
* Looping 48 rounds per permutation becomes
|
||||
* just too slow...
|
||||
*
|
||||
*/
|
||||
|
||||
clearmem((char*)eperm32tab, sizeof(eperm32tab));
|
||||
|
||||
for(bit = 0; bit < 48; bit++) {
|
||||
ufc_long mask1,comes_from;
|
||||
|
||||
comes_from = perm32[esel[bit]-1]-1;
|
||||
mask1 = bytemask[comes_from % 8];
|
||||
|
||||
for(j = 256; j--;) {
|
||||
if(j & mask1)
|
||||
eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the sb tables:
|
||||
*
|
||||
* For each 12 bit segment of an 48 bit intermediate
|
||||
* result, the sb table precomputes the two 4 bit
|
||||
* values of the sbox lookups done with the two 6
|
||||
* bit halves, shifts them to their proper place,
|
||||
* sends them through perm32 and finally E expands
|
||||
* them so that they are ready for the next
|
||||
* DES round.
|
||||
*
|
||||
*/
|
||||
for(sg = 0; sg < 4; sg++) {
|
||||
int j1, j2;
|
||||
int s1, s2;
|
||||
|
||||
for(j1 = 0; j1 < 64; j1++) {
|
||||
s1 = s_lookup(2 * sg, j1);
|
||||
for(j2 = 0; j2 < 64; j2++) {
|
||||
ufc_long to_permute, inx;
|
||||
|
||||
s2 = s_lookup(2 * sg + 1, j2);
|
||||
to_permute = ((s1 << 4) | s2) << (24 - 8 * sg);
|
||||
|
||||
#ifdef _UFC_32_
|
||||
inx = ((j1 << 6) | j2) << 1;
|
||||
sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];
|
||||
sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];
|
||||
sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
|
||||
sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
|
||||
sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];
|
||||
sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];
|
||||
sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];
|
||||
sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];
|
||||
#endif
|
||||
#ifdef _UFC_64_
|
||||
inx = ((j1 << 6) | j2);
|
||||
sb[sg][inx] =
|
||||
((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
|
||||
(long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
|
||||
sb[sg][inx] |=
|
||||
((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
|
||||
(long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
|
||||
sb[sg][inx] |=
|
||||
((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |
|
||||
(long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];
|
||||
sb[sg][inx] |=
|
||||
((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |
|
||||
(long64)eperm32tab[3][(to_permute) & 0xff][1];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an inverse matrix for esel telling
|
||||
* where to plug out bits if undoing it
|
||||
*/
|
||||
for(bit=48; bit--;) {
|
||||
e_inverse[esel[bit] - 1 ] = bit;
|
||||
e_inverse[esel[bit] - 1 + 32] = bit + 48;
|
||||
}
|
||||
|
||||
/*
|
||||
* create efp: the matrix used to
|
||||
* undo the E expansion and effect final permutation
|
||||
*/
|
||||
clearmem((char*)efp, sizeof efp);
|
||||
for(bit = 0; bit < 64; bit++) {
|
||||
int o_bit, o_long;
|
||||
ufc_long word_value, mask1, mask2;
|
||||
int comes_from_f_bit, comes_from_e_bit;
|
||||
int comes_from_word, bit_within_word;
|
||||
|
||||
/* See where bit i belongs in the two 32 bit long's */
|
||||
o_long = bit / 32; /* 0..1 */
|
||||
o_bit = bit % 32; /* 0..31 */
|
||||
|
||||
/*
|
||||
* And find a bit in the e permutated value setting this bit.
|
||||
*
|
||||
* Note: the e selection may have selected the same bit several
|
||||
* times. By the initialization of e_inverse, we only look
|
||||
* for one specific instance.
|
||||
*/
|
||||
comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */
|
||||
comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */
|
||||
comes_from_word = comes_from_e_bit / 6; /* 0..15 */
|
||||
bit_within_word = comes_from_e_bit % 6; /* 0..5 */
|
||||
|
||||
mask1 = longmask[bit_within_word + 26];
|
||||
mask2 = longmask[o_bit];
|
||||
|
||||
for(word_value = 64; word_value--;) {
|
||||
if(word_value & mask1)
|
||||
efp[comes_from_word][word_value][o_long] |= mask2;
|
||||
}
|
||||
}
|
||||
initialized++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the elements of the sb table permuting the
|
||||
* bits swapped in the expansion by the current salt.
|
||||
*/
|
||||
|
||||
#ifdef _UFC_32_
|
||||
static void shuffle_sb(k, saltbits)
|
||||
long32 *k;
|
||||
ufc_long saltbits;
|
||||
{ ufc_long j;
|
||||
long32 x;
|
||||
for(j=4096; j--;) {
|
||||
x = (k[0] ^ k[1]) & (long32)saltbits;
|
||||
*k++ ^= x;
|
||||
*k++ ^= x;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _UFC_64_
|
||||
static void shuffle_sb(k, saltbits)
|
||||
long64 *k;
|
||||
ufc_long saltbits;
|
||||
{ ufc_long j;
|
||||
long64 x;
|
||||
for(j=4096; j--;) {
|
||||
x = ((*k >> 32) ^ *k) & (long64)saltbits;
|
||||
*k++ ^= (x << 32) | x;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the unit for a new salt
|
||||
* Hopefully we'll not see a new salt in each crypt call.
|
||||
*/
|
||||
|
||||
static unsigned char current_salt[3] = "&&"; /* invalid value */
|
||||
static ufc_long current_saltbits = 0;
|
||||
static int direction = 0;
|
||||
|
||||
static void setup_salt(char *s1)
|
||||
{ ufc_long i, j, saltbits;
|
||||
unsigned char *s2 = (unsigned char *)s1;
|
||||
|
||||
if(!initialized)
|
||||
ufc_init_des();
|
||||
|
||||
if(s2[0] == current_salt[0] && s2[1] == current_salt[1])
|
||||
return;
|
||||
current_salt[0] = s2[0]; current_salt[1] = s2[1];
|
||||
|
||||
/*
|
||||
* This is the only crypt change to DES:
|
||||
* entries are swapped in the expansion table
|
||||
* according to the bits set in the salt.
|
||||
*/
|
||||
saltbits = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
long c=ascii_to_bin(s2[i]);
|
||||
if(c < 0 || c > 63)
|
||||
c = 0;
|
||||
for(j = 0; j < 6; j++) {
|
||||
if((c >> j) & 0x1)
|
||||
saltbits |= BITMASK(6 * i + j);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Permute the sb table values
|
||||
* to reflect the changed e
|
||||
* selection table
|
||||
*/
|
||||
shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits);
|
||||
shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits);
|
||||
shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits);
|
||||
shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits);
|
||||
|
||||
current_saltbits = saltbits;
|
||||
}
|
||||
|
||||
static void ufc_mk_keytab(key)
|
||||
char *key;
|
||||
{ ufc_long v1, v2, *k1;
|
||||
int i;
|
||||
#ifdef _UFC_32_
|
||||
long32 v, *k2 = &_ufc_keytab[0][0];
|
||||
#endif
|
||||
#ifdef _UFC_64_
|
||||
long64 v, *k2 = &_ufc_keytab[0];
|
||||
#endif
|
||||
|
||||
v1 = v2 = 0; k1 = &do_pc1[0][0][0];
|
||||
for(i = 8; i--;) {
|
||||
v1 |= k1[*key & 0x7f]; k1 += 128;
|
||||
v2 |= k1[*key++ & 0x7f]; k1 += 128;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
k1 = &do_pc2[0][0];
|
||||
|
||||
v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
|
||||
v = k1[(v1 >> 21) & 0x7f]; k1 += 128;
|
||||
v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
|
||||
v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;
|
||||
v |= k1[(v1 ) & 0x7f]; k1 += 128;
|
||||
|
||||
#ifdef _UFC_32_
|
||||
*k2++ = v;
|
||||
v = 0;
|
||||
#endif
|
||||
#ifdef _UFC_64_
|
||||
v <<= 32;
|
||||
#endif
|
||||
|
||||
v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
|
||||
v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
|
||||
v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
|
||||
v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;
|
||||
v |= k1[(v2 ) & 0x7f];
|
||||
|
||||
*k2++ = v;
|
||||
}
|
||||
|
||||
direction = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Undo an extra E selection and do final permutations
|
||||
*/
|
||||
|
||||
ufc_long *_ufc_dofinalperm(l1, l2, r1, r2)
|
||||
ufc_long l1,l2,r1,r2;
|
||||
{ ufc_long v1, v2, x;
|
||||
static ufc_long ary[2];
|
||||
|
||||
x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x;
|
||||
x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x;
|
||||
|
||||
v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
|
||||
|
||||
v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
|
||||
v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
|
||||
v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
|
||||
v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
|
||||
|
||||
v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
|
||||
v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
|
||||
v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
|
||||
v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
|
||||
|
||||
v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
|
||||
v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
|
||||
v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
|
||||
v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
|
||||
|
||||
v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
|
||||
v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
|
||||
v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
|
||||
v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
|
||||
|
||||
ary[0] = v1; ary[1] = v2;
|
||||
return ary;
|
||||
}
|
||||
|
||||
/*
|
||||
* crypt only: convert from 64 bit to 11 bit ASCII
|
||||
* prefixing with the salt
|
||||
*/
|
||||
|
||||
static char *output_conversion(v1, v2, salt)
|
||||
ufc_long v1, v2;
|
||||
char *salt;
|
||||
{ static char outbuf[14];
|
||||
int i, s;
|
||||
|
||||
outbuf[0] = salt[0];
|
||||
outbuf[1] = salt[1] ? salt[1] : salt[0];
|
||||
|
||||
for(i = 0; i < 5; i++)
|
||||
outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f);
|
||||
|
||||
s = (v2 & 0xf) << 2;
|
||||
v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
|
||||
|
||||
for(i = 5; i < 10; i++)
|
||||
outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f);
|
||||
|
||||
outbuf[12] = bin_to_ascii(s);
|
||||
outbuf[13] = 0;
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
ufc_long *_ufc_doit();
|
||||
|
||||
/*
|
||||
* UNIX crypt function
|
||||
*/
|
||||
|
||||
char *ufc_crypt(char *key,char *salt)
|
||||
{ ufc_long *s;
|
||||
char ktab[9];
|
||||
|
||||
/*
|
||||
* Hack DES tables according to salt
|
||||
*/
|
||||
setup_salt(salt);
|
||||
|
||||
/*
|
||||
* Setup key schedule
|
||||
*/
|
||||
clearmem(ktab, sizeof ktab);
|
||||
StrnCpy(ktab, key, 8);
|
||||
ufc_mk_keytab(ktab);
|
||||
|
||||
/*
|
||||
* Go for the 25 DES encryptions
|
||||
*/
|
||||
s = _ufc_doit((ufc_long)0, (ufc_long)0,
|
||||
(ufc_long)0, (ufc_long)0, (ufc_long)25);
|
||||
|
||||
/*
|
||||
* And convert back to 6 bit ASCII
|
||||
*/
|
||||
return output_conversion(s[0], s[1], salt);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _UFC_32_
|
||||
|
||||
/*
|
||||
* 32 bit version
|
||||
*/
|
||||
|
||||
extern long32 _ufc_keytab[16][2];
|
||||
extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
|
||||
|
||||
#define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
|
||||
|
||||
ufc_long *_ufc_doit(l1, l2, r1, r2, itr)
|
||||
ufc_long l1, l2, r1, r2, itr;
|
||||
{ int i;
|
||||
long32 s, *k;
|
||||
|
||||
while(itr--) {
|
||||
k = &_ufc_keytab[0][0];
|
||||
for(i=8; i--; ) {
|
||||
s = *k++ ^ r1;
|
||||
l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
|
||||
l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4);
|
||||
s = *k++ ^ r2;
|
||||
l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
|
||||
l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4);
|
||||
|
||||
s = *k++ ^ l1;
|
||||
r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
|
||||
r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4);
|
||||
s = *k++ ^ l2;
|
||||
r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
|
||||
r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4);
|
||||
}
|
||||
s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
|
||||
}
|
||||
return _ufc_dofinalperm(l1, l2, r1, r2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _UFC_64_
|
||||
|
||||
/*
|
||||
* 64 bit version
|
||||
*/
|
||||
|
||||
extern long64 _ufc_keytab[16];
|
||||
extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
|
||||
|
||||
#define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
|
||||
|
||||
ufc_long *_ufc_doit(l1, l2, r1, r2, itr)
|
||||
ufc_long l1, l2, r1, r2, itr;
|
||||
{ int i;
|
||||
long64 l, r, s, *k;
|
||||
|
||||
l = (((long64)l1) << 32) | ((long64)l2);
|
||||
r = (((long64)r1) << 32) | ((long64)r2);
|
||||
|
||||
while(itr--) {
|
||||
k = &_ufc_keytab[0];
|
||||
for(i=8; i--; ) {
|
||||
s = *k++ ^ r;
|
||||
l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
|
||||
l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
|
||||
l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
|
||||
l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
|
||||
|
||||
s = *k++ ^ l;
|
||||
r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
|
||||
r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
|
||||
r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
|
||||
r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
|
||||
}
|
||||
s=l; l=r; r=s;
|
||||
}
|
||||
|
||||
l1 = l >> 32; l2 = l & 0xffffffff;
|
||||
r1 = r >> 32; r2 = r & 0xffffffff;
|
||||
return _ufc_dofinalperm(l1, l2, r1, r2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
int ufc_dummy_procedure(void)
|
||||
{return 0;}
|
||||
#endif
|
246
source3/lib/username.c
Normal file
246
source3/lib/username.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Username handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
get a users home directory. tries as-is then lower case
|
||||
****************************************************************************/
|
||||
char *get_home_dir(char *user)
|
||||
{
|
||||
static struct passwd *pass;
|
||||
|
||||
pass = Get_Pwnam(user,False);
|
||||
|
||||
if (!pass) return(NULL);
|
||||
return(pass->pw_dir);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
map a username from a dos name to a unix name by looking in the username
|
||||
map
|
||||
********************************************************************/
|
||||
void map_username(char *user)
|
||||
{
|
||||
static int depth=0;
|
||||
static BOOL initialised=False;
|
||||
static fstring last_from,last_to;
|
||||
FILE *f;
|
||||
char *s;
|
||||
char *mapfile = lp_username_map();
|
||||
if (!*mapfile || depth) return;
|
||||
|
||||
if (!*user) return;
|
||||
|
||||
if (!initialised) {
|
||||
*last_from = *last_to = 0;
|
||||
initialised = True;
|
||||
}
|
||||
|
||||
if (strequal(user,last_to)) return;
|
||||
|
||||
if (strequal(user,last_from)) {
|
||||
DEBUG(3,("Mapped user %s to %s\n",user,last_to));
|
||||
strcpy(user,last_to);
|
||||
return;
|
||||
}
|
||||
|
||||
f = fopen(mapfile,"r");
|
||||
if (!f) {
|
||||
DEBUG(0,("can't open username map %s\n",mapfile));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(4,("Scanning username map %s\n",mapfile));
|
||||
|
||||
depth++;
|
||||
|
||||
for (; (s=fgets_slash(NULL,80,f)); free(s)) {
|
||||
char *unixname = s;
|
||||
char *dosname = strchr(unixname,'=');
|
||||
|
||||
if (!dosname) continue;
|
||||
*dosname++ = 0;
|
||||
|
||||
while (isspace(*unixname)) unixname++;
|
||||
if (!*unixname || strchr("#;",*unixname)) continue;
|
||||
|
||||
{
|
||||
int l = strlen(unixname);
|
||||
while (l && isspace(unixname[l-1])) {
|
||||
unixname[l-1] = 0;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(dosname,'*') || user_in_list(user,dosname)) {
|
||||
DEBUG(3,("Mapped user %s to %s\n",user,unixname));
|
||||
StrnCpy(last_from,user,sizeof(last_from)-1);
|
||||
sscanf(unixname,"%s",user);
|
||||
StrnCpy(last_to,user,sizeof(last_to)-1);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
depth--;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
internals of Get_Pwnam wrapper
|
||||
****************************************************************************/
|
||||
static struct passwd *_Get_Pwnam(char *s)
|
||||
{
|
||||
struct passwd *ret;
|
||||
|
||||
ret = getpwnam(s);
|
||||
if (ret)
|
||||
{
|
||||
#ifdef GETPWANAM
|
||||
struct passwd_adjunct *pwret;
|
||||
pwret = getpwanam(s);
|
||||
if (pwret)
|
||||
{
|
||||
free(ret->pw_passwd);
|
||||
ret->pw_passwd = pwret->pwa_passwd;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
a wrapper for getpwnam() that tries with all lower and all upper case
|
||||
if the initial name fails. Also tried with first letter capitalised
|
||||
Note that this changes user!
|
||||
****************************************************************************/
|
||||
struct passwd *Get_Pwnam(char *user,BOOL allow_change)
|
||||
{
|
||||
fstring user2;
|
||||
|
||||
struct passwd *ret;
|
||||
|
||||
if (!user || !(*user))
|
||||
return(NULL);
|
||||
|
||||
StrnCpy(user2,user,sizeof(user2)-1);
|
||||
|
||||
if (!allow_change) {
|
||||
user = &user2[0];
|
||||
}
|
||||
|
||||
map_username(user);
|
||||
|
||||
ret = _Get_Pwnam(user);
|
||||
if (ret) return(ret);
|
||||
|
||||
strlower(user);
|
||||
ret = _Get_Pwnam(user);
|
||||
if (ret) return(ret);
|
||||
|
||||
strupper(user);
|
||||
ret = _Get_Pwnam(user);
|
||||
if (ret) return(ret);
|
||||
|
||||
/* try with first letter capitalised */
|
||||
if (strlen(user) > 1)
|
||||
strlower(user+1);
|
||||
ret = _Get_Pwnam(user);
|
||||
if (ret) return(ret);
|
||||
|
||||
if (allow_change)
|
||||
strcpy(user,user2);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
check if a user is in a user list
|
||||
****************************************************************************/
|
||||
BOOL user_in_list(char *user,char *list)
|
||||
{
|
||||
pstring tok;
|
||||
char *p=list;
|
||||
|
||||
while (next_token(&p,tok,LIST_SEP))
|
||||
{
|
||||
if (strequal(user,tok))
|
||||
return(True);
|
||||
|
||||
#ifdef NETGROUP
|
||||
if (*tok == '@')
|
||||
{
|
||||
static char *mydomain = NULL;
|
||||
if (mydomain == 0)
|
||||
yp_get_default_domain(&mydomain);
|
||||
|
||||
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
|
||||
user, mydomain, &tok[1]));
|
||||
DEBUG(5,("innetgr is %s\n",
|
||||
innetgr(&tok[1], (char *) 0, user, mydomain)
|
||||
? "TRUE" : "FALSE"));
|
||||
|
||||
if (innetgr(&tok[1], (char *)0, user, mydomain))
|
||||
return (True);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if HAVE_GETGRNAM
|
||||
if (*tok == '@')
|
||||
{
|
||||
struct group *gptr;
|
||||
char **member;
|
||||
struct passwd *pass = Get_Pwnam(user,False);
|
||||
|
||||
if (pass) {
|
||||
gptr = getgrgid(pass->pw_gid);
|
||||
if (gptr && strequal(gptr->gr_name,&tok[1]))
|
||||
return(True);
|
||||
}
|
||||
|
||||
gptr = (struct group *)getgrnam(&tok[1]);
|
||||
|
||||
if (gptr)
|
||||
{
|
||||
member = gptr->gr_mem;
|
||||
while (member && *member)
|
||||
{
|
||||
if (strequal(*member,user))
|
||||
return(True);
|
||||
member++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
4510
source3/lib/util.c
Normal file
4510
source3/lib/util.c
Normal file
File diff suppressed because it is too large
Load Diff
936
source3/libsmb/nmblib.c
Normal file
936
source3/libsmb/nmblib.c
Normal file
@ -0,0 +1,936 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios library routines
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "nameserv.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
int num_good_sends=0;
|
||||
int num_good_receives=0;
|
||||
static uint16 name_trn_id = 0;
|
||||
BOOL CanRecurse = True;
|
||||
extern pstring scope;
|
||||
|
||||
/*******************************************************************
|
||||
handle "compressed" name pointers
|
||||
******************************************************************/
|
||||
static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
|
||||
BOOL *got_pointer,int *ret)
|
||||
{
|
||||
int loop_count=0;
|
||||
|
||||
while ((ubuf[*offset] & 0xC0) == 0xC0) {
|
||||
if (!*got_pointer) (*ret) += 2;
|
||||
(*got_pointer)=True;
|
||||
(*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
|
||||
if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
return(True);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
parse a nmb name from "compressed" format to something readable
|
||||
return the space taken by the name, or 0 if the name is invalid
|
||||
******************************************************************/
|
||||
static int parse_nmb_name(char *inbuf,int offset,int length,
|
||||
struct nmb_name *name)
|
||||
{
|
||||
int m,n=0;
|
||||
unsigned char *ubuf = (unsigned char *)inbuf;
|
||||
int ret = 0;
|
||||
BOOL got_pointer=False;
|
||||
|
||||
if (length - offset < 2) return(0);
|
||||
|
||||
/* handle initial name pointers */
|
||||
if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
|
||||
|
||||
m = ubuf[offset];
|
||||
|
||||
if (!m) return(0);
|
||||
if ((m & 0xC0) || offset+m+2 > length) return(0);
|
||||
|
||||
bzero((char *)name,sizeof(*name));
|
||||
|
||||
/* the "compressed" part */
|
||||
if (!got_pointer) ret += m + 2;
|
||||
offset++;
|
||||
while (m) {
|
||||
unsigned char c1,c2;
|
||||
c1 = ubuf[offset++]-'A';
|
||||
c2 = ubuf[offset++]-'A';
|
||||
if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
|
||||
name->name[n++] = (c1<<4) | c2;
|
||||
m -= 2;
|
||||
}
|
||||
name->name[n] = 0;
|
||||
|
||||
if (n==16) {
|
||||
/* parse out the name type,
|
||||
its always in the 16th byte of the name */
|
||||
name->name_type = name->name[15];
|
||||
|
||||
/* remove trailing spaces */
|
||||
name->name[15] = 0;
|
||||
n = 14;
|
||||
while (n && name->name[n]==' ') name->name[n--] = 0;
|
||||
}
|
||||
|
||||
/* now the domain parts (if any) */
|
||||
n = 0;
|
||||
while ((m=ubuf[offset])) {
|
||||
/* we can have pointers within the domain part as well */
|
||||
if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
|
||||
|
||||
if (!got_pointer) ret += m+1;
|
||||
if (n) name->scope[n++] = '.';
|
||||
if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
|
||||
offset++;
|
||||
while (m--) name->scope[n++] = (char)ubuf[offset++];
|
||||
}
|
||||
name->scope[n++] = 0;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
put a compressed nmb name into a buffer. return the length of the
|
||||
compressed name
|
||||
|
||||
compressed names are really weird. The "compression" doubles the
|
||||
size. The idea is that it also means that compressed names conform
|
||||
to the doman name system. See RFC1002.
|
||||
******************************************************************/
|
||||
static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
|
||||
{
|
||||
int ret,m;
|
||||
fstring buf1;
|
||||
char *p;
|
||||
|
||||
if (name->name[0] == '*') {
|
||||
/* special case for wildcard name */
|
||||
bzero(buf1,20);
|
||||
buf1[0] = '*';
|
||||
} else {
|
||||
sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
|
||||
}
|
||||
|
||||
buf[offset] = 0x20;
|
||||
|
||||
ret = 34;
|
||||
|
||||
for (m=0;m<16;m++) {
|
||||
buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
|
||||
buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
|
||||
}
|
||||
offset += 33;
|
||||
|
||||
buf[offset] = 0;
|
||||
|
||||
if (name->scope[0]) {
|
||||
/* XXXX this scope handling needs testing */
|
||||
ret += strlen(name->scope) + 1;
|
||||
strcpy(&buf[offset+1],name->scope);
|
||||
|
||||
p = &buf[offset+1];
|
||||
while ((p = strchr(p,'.'))) {
|
||||
buf[offset] = PTR_DIFF(p,&buf[offset]);
|
||||
offset += buf[offset];
|
||||
p = &buf[offset+1];
|
||||
}
|
||||
buf[offset] = strlen(&buf[offset+1]);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
useful for debugging messages
|
||||
******************************************************************/
|
||||
char *namestr(struct nmb_name *n)
|
||||
{
|
||||
static int i=0;
|
||||
static fstring ret[4];
|
||||
char *p = ret[i];
|
||||
|
||||
if (!n->scope[0])
|
||||
sprintf(p,"%s(%x)",n->name,n->name_type);
|
||||
else
|
||||
sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope);
|
||||
|
||||
i = (i+1)%4;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
allocate are parse some resource records
|
||||
******************************************************************/
|
||||
static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
|
||||
struct res_rec **recs,
|
||||
int count)
|
||||
{
|
||||
int i;
|
||||
*recs = (struct res_rec *)malloc(sizeof(**recs)*count);
|
||||
if (!*recs) return(False);
|
||||
|
||||
bzero(*recs,sizeof(**recs)*count);
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
|
||||
(*offset) += l;
|
||||
if (!l || (*offset)+10 > length) {
|
||||
free(*recs);
|
||||
return(False);
|
||||
}
|
||||
(*recs)[i].rr_type = RSVAL(inbuf,(*offset));
|
||||
(*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
|
||||
(*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
|
||||
(*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
|
||||
(*offset) += 10;
|
||||
if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
|
||||
(*offset)+(*recs)[i].rdlength > length) {
|
||||
free(*recs);
|
||||
return(False);
|
||||
}
|
||||
memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
|
||||
(*offset) += (*recs)[i].rdlength;
|
||||
}
|
||||
return(True);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
put a resource record into a packet
|
||||
******************************************************************/
|
||||
static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
|
||||
{
|
||||
int ret=0;
|
||||
int i;
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
int l = put_nmb_name(buf,offset,&recs[i].rr_name);
|
||||
offset += l;
|
||||
ret += l;
|
||||
RSSVAL(buf,offset,recs[i].rr_type);
|
||||
RSSVAL(buf,offset+2,recs[i].rr_class);
|
||||
RSIVAL(buf,offset+4,recs[i].ttl);
|
||||
RSSVAL(buf,offset+8,recs[i].rdlength);
|
||||
memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
|
||||
offset += 10+recs[i].rdlength;
|
||||
ret += 10+recs[i].rdlength;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
parse a dgram packet. Return False if the packet can't be parsed
|
||||
or is invalid for some reason, True otherwise
|
||||
|
||||
this is documented in section 4.4.1 of RFC1002
|
||||
******************************************************************/
|
||||
static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
|
||||
{
|
||||
int offset;
|
||||
int flags;
|
||||
|
||||
bzero((char *)dgram,sizeof(*dgram));
|
||||
|
||||
if (length < 14) return(False);
|
||||
|
||||
dgram->header.msg_type = CVAL(inbuf,0);
|
||||
flags = CVAL(inbuf,1);
|
||||
dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
|
||||
if (flags & 1) dgram->header.flags.more = True;
|
||||
if (flags & 2) dgram->header.flags.first = True;
|
||||
dgram->header.dgm_id = RSVAL(inbuf,2);
|
||||
putip((char *)&dgram->header.source_ip,inbuf+4);
|
||||
dgram->header.source_port = RSVAL(inbuf,8);
|
||||
dgram->header.dgm_length = RSVAL(inbuf,10);
|
||||
dgram->header.packet_offset = RSVAL(inbuf,12);
|
||||
|
||||
offset = 14;
|
||||
|
||||
if (dgram->header.msg_type == 0x10 ||
|
||||
dgram->header.msg_type == 0x11 ||
|
||||
dgram->header.msg_type == 0x12) {
|
||||
offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
|
||||
offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
|
||||
}
|
||||
|
||||
if (offset >= length || (length-offset > sizeof(dgram->data)))
|
||||
return(False);
|
||||
|
||||
dgram->datasize = length-offset;
|
||||
memcpy(dgram->data,inbuf+offset,dgram->datasize);
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
parse a nmb packet. Return False if the packet can't be parsed
|
||||
or is invalid for some reason, True otherwise
|
||||
******************************************************************/
|
||||
static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
|
||||
{
|
||||
int nm_flags,offset;
|
||||
|
||||
bzero((char *)nmb,sizeof(*nmb));
|
||||
|
||||
if (length < 12) return(False);
|
||||
|
||||
/* parse the header */
|
||||
nmb->header.name_trn_id = RSVAL(inbuf,0);
|
||||
nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
|
||||
nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
|
||||
nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
|
||||
nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
|
||||
nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
|
||||
nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
|
||||
nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
|
||||
nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
|
||||
nmb->header.rcode = CVAL(inbuf,3) & 0xF;
|
||||
nmb->header.qdcount = RSVAL(inbuf,4);
|
||||
nmb->header.ancount = RSVAL(inbuf,6);
|
||||
nmb->header.nscount = RSVAL(inbuf,8);
|
||||
nmb->header.arcount = RSVAL(inbuf,10);
|
||||
|
||||
if (nmb->header.qdcount) {
|
||||
offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
|
||||
if (!offset) return(False);
|
||||
|
||||
if (length - (12+offset) < 4) return(False);
|
||||
nmb->question.question_type = RSVAL(inbuf,12+offset);
|
||||
nmb->question.question_class = RSVAL(inbuf,12+offset+2);
|
||||
|
||||
offset += 12+4;
|
||||
} else {
|
||||
offset = 12;
|
||||
}
|
||||
|
||||
/* and any resource records */
|
||||
if (nmb->header.ancount &&
|
||||
!parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
|
||||
nmb->header.ancount))
|
||||
return(False);
|
||||
|
||||
if (nmb->header.nscount &&
|
||||
!parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
|
||||
nmb->header.nscount))
|
||||
return(False);
|
||||
|
||||
if (nmb->header.arcount &&
|
||||
!parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
|
||||
nmb->header.arcount))
|
||||
return(False);
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
free up any resources associated with an nmb packet
|
||||
******************************************************************/
|
||||
void free_nmb_packet(struct nmb_packet *nmb)
|
||||
{
|
||||
if (nmb->answers) free(nmb->answers);
|
||||
if (nmb->nsrecs) free(nmb->nsrecs);
|
||||
if (nmb->additional) free(nmb->additional);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
free up any resources associated with a packet
|
||||
******************************************************************/
|
||||
void free_packet(struct packet_struct *packet)
|
||||
{
|
||||
if (packet->packet_type == NMB_PACKET)
|
||||
free_nmb_packet(&packet->packet.nmb);
|
||||
free(packet);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
read a packet from a socket and parse it, returning a packet ready
|
||||
to be used or put on the queue. This assumes a UDP socket
|
||||
******************************************************************/
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
|
||||
{
|
||||
extern struct in_addr lastip;
|
||||
extern int lastport;
|
||||
struct packet_struct *packet;
|
||||
char buf[MAX_DGRAM_SIZE];
|
||||
int length;
|
||||
BOOL ok=False;
|
||||
|
||||
length = read_udp_socket(fd,buf,sizeof(buf));
|
||||
if (length < MIN_DGRAM_SIZE) return(NULL);
|
||||
|
||||
packet = (struct packet_struct *)malloc(sizeof(*packet));
|
||||
if (!packet) return(NULL);
|
||||
|
||||
packet->next = NULL;
|
||||
packet->prev = NULL;
|
||||
packet->ip = lastip;
|
||||
packet->port = lastport;
|
||||
packet->fd = fd;
|
||||
packet->timestamp = time(NULL);
|
||||
packet->packet_type = packet_type;
|
||||
switch (packet_type)
|
||||
{
|
||||
case NMB_PACKET:
|
||||
ok = parse_nmb(buf,length,&packet->packet.nmb);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
ok = parse_dgram(buf,length,&packet->packet.dgram);
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
free(packet);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
num_good_receives++;
|
||||
|
||||
DEBUG(4,("%s received a packet of len %d from (%s) port %d\n",
|
||||
timestring(),length,inet_ntoa(packet->ip),packet->port));
|
||||
|
||||
return(packet);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
send a udp packet on a already open socket
|
||||
******************************************************************/
|
||||
static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
|
||||
{
|
||||
BOOL ret;
|
||||
struct sockaddr_in sock_out;
|
||||
|
||||
/* set the address and port */
|
||||
bzero((char *)&sock_out,sizeof(sock_out));
|
||||
putip((char *)&sock_out.sin_addr,(char *)&ip);
|
||||
sock_out.sin_port = htons( port );
|
||||
sock_out.sin_family = AF_INET;
|
||||
|
||||
DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n",
|
||||
timestring(),len,inet_ntoa(ip),port));
|
||||
|
||||
ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
|
||||
sizeof(sock_out)) >= 0);
|
||||
|
||||
if (!ret)
|
||||
DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
|
||||
inet_ntoa(ip),port,strerror(errno)));
|
||||
|
||||
if (ret)
|
||||
num_good_sends++;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
build a dgram packet ready for sending
|
||||
|
||||
XXXX This currently doesn't handle packets too big for one
|
||||
datagram. It should split them and use the packet_offset, more and
|
||||
first flags to handle the fragmentation. Yuck.
|
||||
******************************************************************/
|
||||
static int build_dgram(char *buf,struct packet_struct *p)
|
||||
{
|
||||
struct dgram_packet *dgram = &p->packet.dgram;
|
||||
unsigned char *ubuf = (unsigned char *)buf;
|
||||
int offset=0;
|
||||
|
||||
/* put in the header */
|
||||
ubuf[0] = dgram->header.msg_type;
|
||||
ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
|
||||
if (dgram->header.flags.more) ubuf[1] |= 1;
|
||||
if (dgram->header.flags.first) ubuf[1] |= 2;
|
||||
RSSVAL(ubuf,2,dgram->header.dgm_id);
|
||||
putip(ubuf+4,(char *)&dgram->header.source_ip);
|
||||
RSSVAL(ubuf,8,dgram->header.source_port);
|
||||
RSSVAL(ubuf,12,dgram->header.packet_offset);
|
||||
|
||||
offset = 14;
|
||||
|
||||
if (dgram->header.msg_type == 0x10 ||
|
||||
dgram->header.msg_type == 0x11 ||
|
||||
dgram->header.msg_type == 0x12) {
|
||||
offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
|
||||
offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
|
||||
}
|
||||
|
||||
memcpy(ubuf+offset,dgram->data,dgram->datasize);
|
||||
offset += dgram->datasize;
|
||||
|
||||
/* automatically set the dgm_length */
|
||||
dgram->header.dgm_length = offset;
|
||||
RSSVAL(ubuf,10,dgram->header.dgm_length);
|
||||
|
||||
return(offset);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
build a nmb name
|
||||
******************************************************************/
|
||||
void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
|
||||
{
|
||||
strcpy(n->name,name);
|
||||
strupper(n->name);
|
||||
n->name_type = type;
|
||||
strcpy(n->scope,this_scope);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
build a nmb packet ready for sending
|
||||
|
||||
XXXX this currently relies on not being passed something that expands
|
||||
to a packet too big for the buffer. Eventually this should be
|
||||
changed to set the trunc bit so the receiver can request the rest
|
||||
via tcp (when that becomes supported)
|
||||
******************************************************************/
|
||||
static int build_nmb(char *buf,struct packet_struct *p)
|
||||
{
|
||||
struct nmb_packet *nmb = &p->packet.nmb;
|
||||
unsigned char *ubuf = (unsigned char *)buf;
|
||||
int offset=0;
|
||||
|
||||
/* put in the header */
|
||||
RSSVAL(ubuf,offset,nmb->header.name_trn_id);
|
||||
ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
|
||||
if (nmb->header.response) ubuf[offset+2] |= (1<<7);
|
||||
if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4;
|
||||
if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
|
||||
if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
|
||||
if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
|
||||
if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
|
||||
ubuf[offset+3] |= (nmb->header.rcode & 0xF);
|
||||
RSSVAL(ubuf,offset+4,nmb->header.qdcount);
|
||||
RSSVAL(ubuf,offset+6,nmb->header.ancount);
|
||||
RSSVAL(ubuf,offset+8,nmb->header.nscount);
|
||||
RSSVAL(ubuf,offset+10,nmb->header.arcount);
|
||||
|
||||
offset += 12;
|
||||
if (nmb->header.qdcount) {
|
||||
/* XXXX this doesn't handle a qdcount of > 1 */
|
||||
offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
|
||||
RSSVAL(ubuf,offset,nmb->question.question_type);
|
||||
RSSVAL(ubuf,offset+2,nmb->question.question_class);
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
if (nmb->header.ancount)
|
||||
offset += put_res_rec((char *)ubuf,offset,nmb->answers,
|
||||
nmb->header.ancount);
|
||||
|
||||
if (nmb->header.nscount)
|
||||
offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
|
||||
nmb->header.nscount);
|
||||
|
||||
if (nmb->header.arcount)
|
||||
offset += put_res_rec((char *)ubuf,offset,nmb->additional,
|
||||
nmb->header.arcount);
|
||||
|
||||
return(offset);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
send a packet_struct
|
||||
******************************************************************/
|
||||
BOOL send_packet(struct packet_struct *p)
|
||||
{
|
||||
char buf[1024];
|
||||
int len=0;
|
||||
|
||||
bzero(buf,sizeof(buf));
|
||||
|
||||
switch (p->packet_type)
|
||||
{
|
||||
case NMB_PACKET:
|
||||
len = build_nmb(buf,p);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
len = build_dgram(buf,p);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!len) return(False);
|
||||
|
||||
return(send_udp(p->fd,buf,len,p->ip,p->port));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
receive a packet with timeout on a open UDP filedescriptor
|
||||
The timeout is in milliseconds
|
||||
***************************************************************************/
|
||||
struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
|
||||
{
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd,&fds);
|
||||
timeout.tv_sec = t/1000;
|
||||
timeout.tv_usec = 1000*(t%1000);
|
||||
|
||||
sys_select(&fds,&timeout);
|
||||
|
||||
if (FD_ISSET(fd,&fds))
|
||||
return(read_packet(fd,type));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
interpret a node status response
|
||||
****************************************************************************/
|
||||
static void interpret_node_status(char *p, char *master,char *rname)
|
||||
{
|
||||
int level = (master||rname)?4:0;
|
||||
int numnames = CVAL(p,0);
|
||||
DEBUG(level,("received %d names\n",numnames));
|
||||
|
||||
if (rname) *rname = 0;
|
||||
if (master) *master = 0;
|
||||
|
||||
p += 1;
|
||||
while (numnames--)
|
||||
{
|
||||
char qname[17];
|
||||
int type;
|
||||
fstring flags;
|
||||
*flags = 0;
|
||||
StrnCpy(qname,p,15);
|
||||
type = CVAL(p,15);
|
||||
p += 16;
|
||||
|
||||
if (p[0] & 0x80) strcat(flags,"<GROUP> ");
|
||||
if ((p[0] & 0x60) == 0) strcat(flags,"B ");
|
||||
if ((p[0] & 0x60) == 1) strcat(flags,"P ");
|
||||
if ((p[0] & 0x60) == 2) strcat(flags,"M ");
|
||||
if ((p[0] & 0x60) == 3) strcat(flags,"_ ");
|
||||
if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
|
||||
if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
|
||||
if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
|
||||
if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
|
||||
|
||||
if (master && !*master && type == 0x1d) {
|
||||
StrnCpy(master,qname,15);
|
||||
trim_string(master,NULL," ");
|
||||
}
|
||||
|
||||
if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
|
||||
StrnCpy(rname,qname,15);
|
||||
trim_string(rname,NULL," ");
|
||||
}
|
||||
|
||||
DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
|
||||
p+=2;
|
||||
}
|
||||
DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
|
||||
IVAL(p,20),IVAL(p,24)));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a netbios name status query on a host
|
||||
|
||||
the "master" parameter is a hack used for finding workgroups.
|
||||
**************************************************************************/
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)())
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 2;
|
||||
int retry_time = 5000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = False;
|
||||
nmb->header.nm_flags.recursion_available = CanRecurse;
|
||||
nmb->header.nm_flags.recursion_desired = recurse;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = 0x21;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(False);
|
||||
|
||||
retries--;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries) break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount ||
|
||||
nmb2->answers->rr_type != 0x21) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
interpret_node_status(&nmb2->answers->rdata[0], master,rname);
|
||||
free_packet(p2);
|
||||
return(True);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEBUG(0,("No status response (this is not unusual)\n"));
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a netbios name query to find someones IP
|
||||
****************************************************************************/
|
||||
BOOL name_query(int fd,char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, struct in_addr *ip,void (*fn)())
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 3;
|
||||
int retry_time = bcast?250:2000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = bcast;
|
||||
nmb->header.nm_flags.recursion_available = CanRecurse;
|
||||
nmb->header.nm_flags.recursion_desired = recurse;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = 0x20;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(False);
|
||||
|
||||
retries--;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries) break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later
|
||||
(put it on the queue?) */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ip) {
|
||||
putip((char *)ip,&nmb2->answers->rdata[2]);
|
||||
DEBUG(fn?3:2,("Got a positive name query response from %s",
|
||||
inet_ntoa(p2->ip)));
|
||||
DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
|
||||
}
|
||||
found=True; retries=0;
|
||||
free_packet(p2);
|
||||
if (fn) break;
|
||||
}
|
||||
}
|
||||
|
||||
return(found);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
construct and send a netbios DGRAM
|
||||
|
||||
Note that this currently sends all answers to port 138. thats the
|
||||
wrong things to do! I should send to the requestors port. XXX
|
||||
**************************************************************************/
|
||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
|
||||
char *srcname,char *dstname,
|
||||
int src_type,int dest_type,
|
||||
struct in_addr dest_ip,
|
||||
struct in_addr src_ip)
|
||||
{
|
||||
struct packet_struct p;
|
||||
struct dgram_packet *dgram = &p.packet.dgram;
|
||||
char *ptr,*p2;
|
||||
char tmp[4];
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
|
||||
dgram->header.flags.node_type = M_NODE;
|
||||
dgram->header.flags.first = True;
|
||||
dgram->header.flags.more = False;
|
||||
dgram->header.dgm_id = name_trn_id++;
|
||||
dgram->header.source_ip = src_ip;
|
||||
dgram->header.source_port = DGRAM_PORT;
|
||||
dgram->header.dgm_length = 0; /* let build_dgram() handle this */
|
||||
dgram->header.packet_offset = 0;
|
||||
|
||||
make_nmb_name(&dgram->source_name,srcname,src_type,scope);
|
||||
make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
|
||||
|
||||
ptr = &dgram->data[0];
|
||||
|
||||
/* now setup the smb part */
|
||||
ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
|
||||
memcpy(tmp,ptr,4);
|
||||
set_message(ptr,17,17 + len,True);
|
||||
memcpy(ptr,tmp,4);
|
||||
|
||||
CVAL(ptr,smb_com) = SMBtrans;
|
||||
SSVAL(ptr,smb_vwv1,len);
|
||||
SSVAL(ptr,smb_vwv11,len);
|
||||
SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
|
||||
SSVAL(ptr,smb_vwv13,3);
|
||||
SSVAL(ptr,smb_vwv14,1);
|
||||
SSVAL(ptr,smb_vwv15,1);
|
||||
SSVAL(ptr,smb_vwv16,2);
|
||||
p2 = smb_buf(ptr);
|
||||
strcpy(p2,mailslot);
|
||||
p2 = skip_string(p2,1);
|
||||
|
||||
memcpy(p2,buf,len);
|
||||
p2 += len;
|
||||
|
||||
dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
|
||||
|
||||
p.ip = dest_ip;
|
||||
p.port = DGRAM_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = DGRAM_PACKET;
|
||||
|
||||
return(send_packet(&p));
|
||||
}
|
||||
|
||||
|
202
source3/libsmb/smbencrypt.c
Normal file
202
source3/libsmb/smbencrypt.c
Normal file
@ -0,0 +1,202 @@
|
||||
#ifdef SMB_PASSWD
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
SMB parameters and setup
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
Modified by Jeremy Allison 1995.
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
#include "des.h"
|
||||
#include "md4.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#ifndef int16
|
||||
#define int16 unsigned short
|
||||
#endif
|
||||
#ifndef uint16
|
||||
#define uint16 unsigned short
|
||||
#endif
|
||||
#ifndef uint32
|
||||
#define uint32 unsigned int
|
||||
#endif
|
||||
|
||||
#include "byteorder.h"
|
||||
|
||||
void str_to_key(uchar *str,uchar *key)
|
||||
{
|
||||
void des_set_odd_parity(des_cblock *);
|
||||
int i;
|
||||
|
||||
key[0] = str[0]>>1;
|
||||
key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
|
||||
key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
|
||||
key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
|
||||
key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
|
||||
key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
|
||||
key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
|
||||
key[7] = str[6]&0x7F;
|
||||
for (i=0;i<8;i++) {
|
||||
key[i] = (key[i]<<1);
|
||||
}
|
||||
des_set_odd_parity((des_cblock *)key);
|
||||
}
|
||||
|
||||
void D1(uchar *k, uchar *d, uchar *out)
|
||||
{
|
||||
des_key_schedule ks;
|
||||
des_cblock deskey;
|
||||
|
||||
str_to_key(k,(uchar *)deskey);
|
||||
des_set_key(deskey,ks);
|
||||
des_ecb_encrypt(d, out, ks, DES_DECRYPT);
|
||||
}
|
||||
|
||||
void E1(uchar *k, uchar *d, uchar *out)
|
||||
{
|
||||
des_key_schedule ks;
|
||||
des_cblock deskey;
|
||||
|
||||
str_to_key(k,(uchar *)deskey);
|
||||
des_set_key(deskey,ks);
|
||||
des_ecb_encrypt(d, out, ks, DES_ENCRYPT);
|
||||
}
|
||||
|
||||
void E_P16(uchar *p14,uchar *p16)
|
||||
{
|
||||
uchar sp7[7];
|
||||
/* the following constant makes us compatible with other
|
||||
implementations. Note that publishing this constant does not reduce the
|
||||
security of the encryption mechanism */
|
||||
uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE};
|
||||
uchar x[8];
|
||||
|
||||
memset(sp7,'\0',7);
|
||||
|
||||
D1(sp7, sp8, x);
|
||||
E1(p14, x, p16);
|
||||
E1(p14+7, x, p16+8);
|
||||
}
|
||||
|
||||
void E_P24(uchar *p21, uchar *c8, uchar *p24)
|
||||
{
|
||||
E1(p21, c8, p24);
|
||||
E1(p21+7, c8, p24+8);
|
||||
E1(p21+14, c8, p24+16);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This implements the X/Open SMB password encryption
|
||||
It takes a password, a 8 byte "crypt key" and puts 24 bytes of
|
||||
encrypted password into p24 */
|
||||
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
|
||||
{
|
||||
uchar p14[15], p21[21];
|
||||
|
||||
memset(p21,'\0',21);
|
||||
memset(p14,'\0',14);
|
||||
StrnCpy((char *)p14,(char *)passwd,14);
|
||||
|
||||
strupper((char *)p14);
|
||||
E_P16(p14, p21);
|
||||
E_P24(p21, c8, p24);
|
||||
}
|
||||
|
||||
/* Routines for Windows NT MD4 Hash functions. */
|
||||
static int _my_wcslen(int16 *str)
|
||||
{
|
||||
int len = 0;
|
||||
while(*str++ != 0)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string into an NT UNICODE string.
|
||||
* Note that regardless of processor type
|
||||
* this must be in intel (little-endian)
|
||||
* format.
|
||||
*/
|
||||
|
||||
static int _my_mbstowcs(int16 *dst, uchar *src, int len)
|
||||
{
|
||||
int i;
|
||||
int16 val;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
val = *src;
|
||||
SSVAL(dst,0,val);
|
||||
dst++;
|
||||
src++;
|
||||
if(val == 0)
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates the MD4 Hash of the users password in NT UNICODE.
|
||||
*/
|
||||
|
||||
void E_md4hash(uchar *passwd, uchar *p16)
|
||||
{
|
||||
int i, len;
|
||||
int16 wpwd[129];
|
||||
MDstruct MD;
|
||||
|
||||
/* Password cannot be longer than 128 characters */
|
||||
len = strlen(passwd);
|
||||
if(len > 128)
|
||||
len = 128;
|
||||
/* Password must be converted to NT unicode */
|
||||
_my_mbstowcs( wpwd, passwd, len);
|
||||
wpwd[len] = 0; /* Ensure string is null terminated */
|
||||
/* Calculate length in bytes */
|
||||
len = _my_wcslen(wpwd) * sizeof(int16);
|
||||
|
||||
MDbegin(&MD);
|
||||
for(i = 0; i + 64 <= len; i += 64)
|
||||
MDupdate(&MD,wpwd + (i/2), 512);
|
||||
MDupdate(&MD,wpwd + (i/2),(len-i)*8);
|
||||
SIVAL(p16,0,MD.buffer[0]);
|
||||
SIVAL(p16,4,MD.buffer[1]);
|
||||
SIVAL(p16,8,MD.buffer[2]);
|
||||
SIVAL(p16,12,MD.buffer[3]);
|
||||
}
|
||||
|
||||
/* Does the NT MD4 hash then des encryption. */
|
||||
|
||||
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
|
||||
{
|
||||
uchar p21[21];
|
||||
|
||||
memset(p21,'\0',21);
|
||||
|
||||
E_md4hash(passwd, p21);
|
||||
E_P24(p21, c8, p24);
|
||||
}
|
||||
|
||||
#else
|
||||
void smbencrypt_dummy(void){}
|
||||
#endif
|
330
source3/locking/locking.c
Normal file
330
source3/locking/locking.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Locking functions
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
extern int DEBUGLEVEL;
|
||||
extern connection_struct Connections[];
|
||||
extern files_struct Files[];
|
||||
|
||||
pstring share_del_pending="";
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
utility function called to see if a file region is locked
|
||||
****************************************************************************/
|
||||
BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
|
||||
{
|
||||
int snum = SNUM(cnum);
|
||||
|
||||
if (count == 0)
|
||||
return(False);
|
||||
|
||||
if (!lp_locking(snum) || !lp_strict_locking(snum))
|
||||
return(False);
|
||||
|
||||
return(fcntl_lock(Files[fnum].fd,F_GETLK,offset,count,
|
||||
(Files[fnum].can_write?F_WRLCK:F_RDLCK)));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
utility function called by locking requests
|
||||
****************************************************************************/
|
||||
BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
|
||||
{
|
||||
BOOL ok = False;
|
||||
|
||||
if (!lp_locking(SNUM(cnum)))
|
||||
return(True);
|
||||
|
||||
if (count == 0) {
|
||||
*eclass = ERRDOS;
|
||||
*ecode = ERRnoaccess;
|
||||
return False;
|
||||
}
|
||||
|
||||
if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
|
||||
ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count,
|
||||
(Files[fnum].can_write?F_WRLCK:F_RDLCK));
|
||||
|
||||
if (!ok) {
|
||||
*eclass = ERRDOS;
|
||||
*ecode = ERRlock;
|
||||
return False;
|
||||
}
|
||||
return True; /* Got lock */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
utility function called by unlocking requests
|
||||
****************************************************************************/
|
||||
BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
|
||||
{
|
||||
BOOL ok = False;
|
||||
|
||||
if (!lp_locking(SNUM(cnum)))
|
||||
return(True);
|
||||
|
||||
if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
|
||||
ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count,F_UNLCK);
|
||||
|
||||
if (!ok) {
|
||||
*eclass = ERRDOS;
|
||||
*ecode = ERRlock;
|
||||
return False;
|
||||
}
|
||||
return True; /* Did unlock */
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
name a share file
|
||||
******************************************************************/
|
||||
static BOOL share_name(int cnum,struct stat *st,char *name)
|
||||
{
|
||||
strcpy(name,lp_lockdir());
|
||||
standard_sub(cnum,name);
|
||||
trim_string(name,"","/");
|
||||
if (!*name) return(False);
|
||||
name += strlen(name);
|
||||
|
||||
sprintf(name,"/share.%d.%d",(int)st->st_dev,(int)st->st_ino);
|
||||
return(True);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
use the fnum to get the share file name
|
||||
******************************************************************/
|
||||
static BOOL share_name_fnum(int fnum,char *name)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat(Files[fnum].fd,&st) != 0) return(False);
|
||||
return(share_name(Files[fnum].cnum,&st,name));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
get the share mode of a file using the fnum
|
||||
******************************************************************/
|
||||
int get_share_mode_by_fnum(int cnum,int fnum,int *pid)
|
||||
{
|
||||
struct stat sbuf;
|
||||
if (fstat(Files[fnum].fd,&sbuf) == -1) return(0);
|
||||
return(get_share_mode(cnum,&sbuf,pid));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
get the share mode of a file using the files name
|
||||
******************************************************************/
|
||||
int get_share_mode_byname(int cnum,char *fname,int *pid)
|
||||
{
|
||||
struct stat sbuf;
|
||||
if (stat(fname,&sbuf) == -1) return(0);
|
||||
return(get_share_mode(cnum,&sbuf,pid));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
get the share mode of a file
|
||||
********************************************************************/
|
||||
int get_share_mode(int cnum,struct stat *sbuf,int *pid)
|
||||
{
|
||||
pstring fname;
|
||||
int fd2;
|
||||
char buf[16];
|
||||
int ret;
|
||||
time_t t;
|
||||
|
||||
*pid = 0;
|
||||
|
||||
if (!share_name(cnum,sbuf,fname)) return(0);
|
||||
|
||||
fd2 = open(fname,O_RDONLY,0);
|
||||
if (fd2 < 0) return(0);
|
||||
|
||||
if (read(fd2,buf,16) != 16) {
|
||||
close(fd2);
|
||||
unlink(fname);
|
||||
return(0);
|
||||
}
|
||||
close(fd2);
|
||||
|
||||
t = IVAL(buf,0);
|
||||
ret = IVAL(buf,4);
|
||||
*pid = IVAL(buf,8);
|
||||
|
||||
if (IVAL(buf,12) != LOCKING_VERSION) {
|
||||
if (!unlink(fname)) DEBUG(2,("Deleted old locking file %s",fname));
|
||||
*pid = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (*pid && !process_exists(*pid)) {
|
||||
ret=0;
|
||||
*pid = 0;
|
||||
}
|
||||
|
||||
if (! *pid) unlink(fname); /* XXXXX race, race */
|
||||
|
||||
if (*pid)
|
||||
DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname,ret,*pid));
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
del the share mode of a file, if we set it last
|
||||
********************************************************************/
|
||||
void del_share_mode(int fnum)
|
||||
{
|
||||
pstring fname;
|
||||
int fd2;
|
||||
char buf[16];
|
||||
time_t t=0;
|
||||
int pid=0;
|
||||
BOOL del = False;
|
||||
|
||||
if (!share_name_fnum(fnum,fname)) return;
|
||||
|
||||
fd2 = open(fname,O_RDONLY,0);
|
||||
if (fd2 < 0) return;
|
||||
if (read(fd2,buf,16) != 16)
|
||||
del = True;
|
||||
close(fd2);
|
||||
|
||||
if (!del) {
|
||||
t = IVAL(buf,0);
|
||||
pid = IVAL(buf,8);
|
||||
}
|
||||
|
||||
if (!del)
|
||||
if (IVAL(buf,12) != LOCKING_VERSION || !pid || !process_exists(pid))
|
||||
del = True;
|
||||
|
||||
if (!del && t == Files[fnum].open_time && pid==(int)getpid())
|
||||
del = True;
|
||||
|
||||
if (del) {
|
||||
if (!unlink(fname))
|
||||
DEBUG(2,("Deleted share file %s\n",fname));
|
||||
else {
|
||||
DEBUG(3,("Pending delete share file %s\n",fname));
|
||||
if (*share_del_pending) DEBUG(0,("Share del clash!\n"));
|
||||
strcpy(share_del_pending,fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
set the share mode of a file
|
||||
********************************************************************/
|
||||
BOOL set_share_mode(int fnum,int mode)
|
||||
{
|
||||
pstring fname;
|
||||
int fd2;
|
||||
char buf[16];
|
||||
int pid = (int)getpid();
|
||||
|
||||
if (!share_name_fnum(fnum,fname)) return(False);
|
||||
|
||||
{
|
||||
int old_umask = umask(0);
|
||||
fd2 = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644);
|
||||
umask(old_umask);
|
||||
}
|
||||
if (fd2 < 0) {
|
||||
DEBUG(2,("Failed to create share file %s\n",fname));
|
||||
return(False);
|
||||
}
|
||||
|
||||
SIVAL(buf,0,Files[fnum].open_time);
|
||||
SIVAL(buf,4,mode);
|
||||
SIVAL(buf,8,pid);
|
||||
SIVAL(buf,12,LOCKING_VERSION);
|
||||
|
||||
if (write(fd2,buf,16) != 16) {
|
||||
close(fd2);
|
||||
unlink(fname);
|
||||
return(False);
|
||||
}
|
||||
|
||||
write(fd2,Files[fnum].name,strlen(Files[fnum].name)+1);
|
||||
|
||||
close(fd2);
|
||||
|
||||
DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname,mode,pid));
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
cleanup any stale share files
|
||||
********************************************************************/
|
||||
void clean_share_files(void)
|
||||
{
|
||||
char *lockdir = lp_lockdir();
|
||||
void *dir;
|
||||
char *s;
|
||||
|
||||
if (!*lockdir) return;
|
||||
|
||||
dir = opendir(lockdir);
|
||||
if (!dir) return;
|
||||
|
||||
while ((s=readdirname(dir))) {
|
||||
char buf[16];
|
||||
int pid;
|
||||
int fd;
|
||||
pstring lname;
|
||||
int dev,inode;
|
||||
|
||||
if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue;
|
||||
|
||||
strcpy(lname,lp_lockdir());
|
||||
trim_string(lname,NULL,"/");
|
||||
strcat(lname,"/");
|
||||
strcat(lname,s);
|
||||
|
||||
fd = open(lname,O_RDONLY,0);
|
||||
if (fd < 0) continue;
|
||||
|
||||
if (read(fd,buf,16) != 16) {
|
||||
close(fd);
|
||||
if (!unlink(lname))
|
||||
printf("Deleted corrupt share file %s\n",s);
|
||||
continue;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
pid = IVAL(buf,8);
|
||||
|
||||
if (IVAL(buf,12) != LOCKING_VERSION || !process_exists(pid)) {
|
||||
if (!unlink(lname))
|
||||
printf("Deleted stale share file %s\n",s);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
58
source3/md4.h
Normal file
58
source3/md4.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
This code is from rfc1186.
|
||||
*/
|
||||
|
||||
/*
|
||||
** ********************************************************************
|
||||
** md4.h -- Header file for implementation of **
|
||||
** MD4 Message Digest Algorithm **
|
||||
** Updated: 2/13/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
/* MDstruct is the data structure for a message digest computation.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int buffer[4]; /* Holds 4-word result of MD computation */
|
||||
unsigned char count[8]; /* Number of bits processed so far */
|
||||
unsigned int done; /* Nonzero means MD computation finished */
|
||||
} MDstruct, *MDptr;
|
||||
|
||||
/* MDbegin(MD)
|
||||
|
||||
|
||||
|
||||
** Input: MD -- an MDptr
|
||||
** Initialize the MDstruct prepatory to doing a message digest
|
||||
** computation.
|
||||
*/
|
||||
extern void MDbegin();
|
||||
|
||||
/* MDupdate(MD,X,count)
|
||||
** Input: MD -- an MDptr
|
||||
** X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use (an unsigned int).
|
||||
** Updates MD using the first "count" bits of X.
|
||||
** The array pointed to by X is not modified.
|
||||
** If count is not a multiple of 8, MDupdate uses high bits of
|
||||
** last byte.
|
||||
** This is the basic input routine for a user.
|
||||
** The routine terminates the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MDupdate with a
|
||||
** count less than 512. Zero is OK for a count.
|
||||
*/
|
||||
extern void MDupdate();
|
||||
|
||||
/* MDprint(MD)
|
||||
** Input: MD -- an MDptr
|
||||
** Prints message digest buffer MD as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte
|
||||
** of buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
*/
|
||||
extern void MDprint();
|
||||
|
||||
/*
|
||||
** End of md4.h
|
||||
*/
|
2318
source3/nameserv.c
Normal file
2318
source3/nameserv.c
Normal file
File diff suppressed because it is too large
Load Diff
303
source3/nmbsync.c
Normal file
303
source3/nmbsync.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios routines to synchronise browse lists
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
#include "nameserv.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
struct server_record *add_server_entry(char *name,int servertype,
|
||||
int ttl,char *comment,BOOL replace);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
call a remote api
|
||||
****************************************************************************/
|
||||
static BOOL call_remote_api(int fd,int cnum,int uid,int timeout,
|
||||
char *inbuf,char *outbuf,
|
||||
int prcnt,int drcnt,
|
||||
int mprcnt,int mdrcnt,
|
||||
int *rprcnt,int *rdrcnt,
|
||||
char *param,char *data,
|
||||
char **rparam,char **rdata)
|
||||
{
|
||||
char *p1,*p2;
|
||||
|
||||
/* send a SMBtrans command */
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,14,0,True);
|
||||
CVAL(outbuf,smb_com) = SMBtrans;
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
SSVAL(outbuf,smb_uid,uid);
|
||||
|
||||
p1 = smb_buf(outbuf);
|
||||
strcpy(p1,"\\PIPE\\LANMAN");
|
||||
p1 = skip_string(p1,1);
|
||||
p2 = p1 + prcnt;
|
||||
|
||||
if (prcnt > 0)
|
||||
memcpy(p1,param,prcnt);
|
||||
if (drcnt > 0)
|
||||
memcpy(p2,data,drcnt);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,prcnt); /* param count */
|
||||
SSVAL(outbuf,smb_vwv1,drcnt); /* data count */
|
||||
SSVAL(outbuf,smb_vwv2,mprcnt); /* mprcnt */
|
||||
SSVAL(outbuf,smb_vwv3,mdrcnt); /* mdrcnt */
|
||||
SSVAL(outbuf,smb_vwv4,0); /* msrcnt */
|
||||
SSVAL(outbuf,smb_vwv5,0); /* flags */
|
||||
SSVAL(outbuf,smb_vwv9,prcnt); /* pscnt */
|
||||
SSVAL(outbuf,smb_vwv10,smb_offset(p1,outbuf)); /* psoff */
|
||||
SSVAL(outbuf,smb_vwv11,drcnt); /* dscnt */
|
||||
SSVAL(outbuf,smb_vwv12,smb_offset(p2,outbuf)); /* dsoff */
|
||||
CVAL(outbuf,smb_vwv13) = 0; /* suwcnt */
|
||||
|
||||
set_message(outbuf,14,PTR_DIFF(p2+drcnt,smb_buf(outbuf)),False);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
|
||||
if (receive_smb(fd,inbuf,timeout) &&
|
||||
CVAL(inbuf,smb_rcls) == 0)
|
||||
{
|
||||
if (rparam)
|
||||
*rparam = inbuf+4 + SVAL(inbuf,smb_vwv4);
|
||||
if (rdata)
|
||||
*rdata = inbuf+4 + SVAL(inbuf,smb_vwv7);
|
||||
if (rprcnt)
|
||||
*rprcnt = SVAL(inbuf,smb_vwv3);
|
||||
if (rdrcnt)
|
||||
*rdrcnt = SVAL(inbuf,smb_vwv6);
|
||||
return(True);
|
||||
}
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
synchronise browse lists with another browse server
|
||||
******************************************************************/
|
||||
void sync_browse_lists(char *name,int name_type,char *myname,
|
||||
char *domain,struct in_addr ip)
|
||||
{
|
||||
char *protocol = "LM1.2X002";
|
||||
char *service = "IPC$";
|
||||
char *dev = "IPC";
|
||||
int timeout=2000;
|
||||
char *inbuf=NULL;
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
int len;
|
||||
uint32 sesskey;
|
||||
int cnum,uid;
|
||||
BOOL ret;
|
||||
|
||||
int fd = open_socket_out(SOCK_STREAM, &ip, SMB_PORT);
|
||||
if (fd < 0) {
|
||||
DEBUG(3,("Failed to connect to %s at %s\n",name,inet_ntoa(ip)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(inbuf = (char *)malloc(0xFFFF+1024))) return;
|
||||
|
||||
/* put in the destination name */
|
||||
len = 4;
|
||||
p = outbuf+len;
|
||||
name_mangle(name,p,name_type);
|
||||
len += name_len(p);
|
||||
|
||||
/* and my name */
|
||||
p = outbuf+len;
|
||||
name_mangle(myname,p,0x20);
|
||||
len += name_len(p);
|
||||
|
||||
_smb_setlen(outbuf,len);
|
||||
CVAL(outbuf,0) = 0x81;
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
receive_smb(fd,inbuf,5000);
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
|
||||
/* setup the protocol string */
|
||||
set_message(outbuf,0,strlen(protocol)+2,True);
|
||||
p = smb_buf(outbuf);
|
||||
*p++ = 2;
|
||||
strcpy(p,protocol);
|
||||
|
||||
CVAL(outbuf,smb_com) = SMBnegprot;
|
||||
CVAL(outbuf,smb_flg) = 0x8;
|
||||
SSVAL(outbuf,smb_flg2,0x1);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
bzero(inbuf,smb_size);
|
||||
ret = receive_smb(fd,inbuf,timeout);
|
||||
|
||||
if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) {
|
||||
DEBUG(3,("%s rejected the protocol\n",name));
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
sesskey = IVAL(inbuf,smb_vwv6);
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,10,2,True);
|
||||
CVAL(outbuf,smb_com) = SMBsesssetupX;
|
||||
|
||||
CVAL(outbuf,smb_vwv0) = 0xFF;
|
||||
SSVAL(outbuf,smb_vwv2,0xFFFF);
|
||||
SSVAL(outbuf,smb_vwv3,2);
|
||||
SSVAL(outbuf,smb_vwv4,1);
|
||||
SIVAL(outbuf,smb_vwv5,sesskey);
|
||||
SSVAL(outbuf,smb_vwv7,1);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
bzero(inbuf,smb_size);
|
||||
ret = receive_smb(fd,inbuf,timeout);
|
||||
if (!ret || CVAL(inbuf,smb_rcls)) {
|
||||
DEBUG(3,("%s rejected session setup\n",name));
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
uid = SVAL(inbuf,smb_uid);
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,4,2 + (2 + strlen(name) + 1 + strlen(service)) +
|
||||
1 + strlen(dev),True);
|
||||
CVAL(outbuf,smb_com) = SMBtconX;
|
||||
SSVAL(outbuf,smb_uid,uid);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,0xFF);
|
||||
SSVAL(outbuf,smb_vwv3,1);
|
||||
|
||||
p = smb_buf(outbuf) + 1;
|
||||
strcpy(p, "\\\\");
|
||||
strcat(p, name);
|
||||
strcat(p, "\\");
|
||||
strcat(p,service);
|
||||
p = skip_string(p,1);
|
||||
strcpy(p,dev);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
bzero(inbuf,smb_size);
|
||||
ret = receive_smb(fd,inbuf,timeout);
|
||||
if (!ret || CVAL(inbuf,smb_rcls)) {
|
||||
DEBUG(3,("%s rejected IPC connect (%d,%d)\n",name,
|
||||
CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err)));
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
cnum = SVAL(inbuf,smb_tid);
|
||||
|
||||
/* now I need to send a NetServerEnum */
|
||||
{
|
||||
fstring param;
|
||||
uint32 *typep;
|
||||
char *rparam,*rdata;
|
||||
|
||||
p = param;
|
||||
SSVAL(p,0,0x68); /* api number */
|
||||
p += 2;
|
||||
strcpy(p,"WrLehDz");
|
||||
p = skip_string(p,1);
|
||||
|
||||
strcpy(p,"B16BBDz");
|
||||
|
||||
p = skip_string(p,1);
|
||||
SSVAL(p,0,1); /* level 1 */
|
||||
SSVAL(p,2,0xFFFF - 500); /* buf length */
|
||||
p += 4;
|
||||
typep = (uint32 *)p;
|
||||
p += 4;
|
||||
strcpy(p,domain);
|
||||
strupper(p);
|
||||
p = skip_string(p,1);
|
||||
|
||||
SIVAL(typep,0,0x80000000); /* domain list */
|
||||
|
||||
if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
|
||||
PTR_DIFF(p,param),0,
|
||||
8,0xFFFF - 500,
|
||||
NULL,NULL,
|
||||
param,NULL,
|
||||
&rparam,&rdata) && SVAL(rparam,0)==0)
|
||||
{
|
||||
int converter=SVAL(rparam,2);
|
||||
int count=SVAL(rparam,4);
|
||||
int i;
|
||||
char *p2 = rdata;
|
||||
for (i=0;i<count;i++) {
|
||||
char *sname = p2;
|
||||
uint32 type = IVAL(p2,18);
|
||||
int comment_offset = IVAL(p2,22) & 0xFFFF;
|
||||
char *comment = comment_offset?(rdata+comment_offset-converter):"";
|
||||
|
||||
add_server_entry(sname,type,lp_max_ttl(),comment,False);
|
||||
p2 += 26;
|
||||
}
|
||||
}
|
||||
|
||||
SIVAL(typep,0,0xFFFFFFFF); /* server list */
|
||||
|
||||
if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
|
||||
PTR_DIFF(p,param),0,
|
||||
8,0xFFFF - 500,
|
||||
NULL,NULL,
|
||||
param,NULL,
|
||||
&rparam,&rdata) && SVAL(rparam,0)==0)
|
||||
{
|
||||
int converter=SVAL(rparam,2);
|
||||
int count=SVAL(rparam,4);
|
||||
int i;
|
||||
|
||||
p = rdata;
|
||||
for (i=0;i<count;i++) {
|
||||
char *sname = p;
|
||||
uint32 type = IVAL(p,18);
|
||||
int comment_offset = IVAL(p,22) & 0xFFFF;
|
||||
char *comment = comment_offset?(rdata+comment_offset-converter):"";
|
||||
|
||||
add_server_entry(sname,type,lp_max_ttl(),comment,False);
|
||||
p += 26;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close up */
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,0,0,True);
|
||||
CVAL(outbuf,smb_com) = SMBtdis;
|
||||
SSVAL(outbuf,smb_uid,uid);
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
send_smb(fd,outbuf);
|
||||
receive_smb(fd,inbuf,1000);
|
||||
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
}
|
1891
source3/param/loadparm.c
Normal file
1891
source3/param/loadparm.c
Normal file
File diff suppressed because it is too large
Load Diff
335
source3/param/params.c
Normal file
335
source3/param/params.c
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Parameter loading utlities
|
||||
Copyright (C) Karl Auer 1993,1994
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
PARAMS.C
|
||||
|
||||
Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer
|
||||
|
||||
This module provides for streamlines retrieval of information from a
|
||||
Windows-like parameter files. There is a function which will search for
|
||||
all sections in the file and call a specified function with each. There is
|
||||
a similar function which will call a specified function for all parameters
|
||||
in a section. The idea is that you pass the addresses of suitable functions
|
||||
to a single function in this module which will then enumerate all sections,
|
||||
and within each section all parameters, to your program.
|
||||
|
||||
Parameter files contain text lines (newline delimited) which consist of
|
||||
either a section name in square brackets or a parameter name, delimited
|
||||
from the parameter value by an equals sign. Blank lines or lines where the
|
||||
first non-whitespace character is a colon are ignored. All whitespace in
|
||||
section names and parameter names is compressed to single spaces. Leading
|
||||
and trailing whitespace on parameter names and parameter values is stripped.
|
||||
|
||||
Only the first equals sign in a parameter line is significant - parameter
|
||||
values may contain equals signs, square brackets and semicolons. Internal
|
||||
whitespace is retained in parameter values. Parameter names may not start
|
||||
with a square bracket, an equals sign or a semicolon, for obvious reasons.
|
||||
|
||||
A sample parameter file might look like this:
|
||||
|
||||
[things]
|
||||
this=1
|
||||
that=2
|
||||
[other things]
|
||||
the other = 3
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "smb.h"
|
||||
#include "params.h"
|
||||
|
||||
/* local variable pointing to passed filename */
|
||||
static char *pszParmFile = NULL;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
/* local prototypes */
|
||||
static BOOL enumerate_parameters(FILE *infile, PM_PARMFUNC pfunc);
|
||||
static BOOL enumerate_sections(FILE *infile,
|
||||
PM_SECFUNC sfunc, PM_PARMFUNC pfunc);
|
||||
|
||||
/* prototypes for local toolbox functions */
|
||||
static void trimleft(char *psz);
|
||||
static void trimright(char *psz);
|
||||
static void collapse_spaces(char *psz);
|
||||
static int firstnonwhite(char *psz);
|
||||
|
||||
/**************************************************************************
|
||||
Identifies all parameters in the current section, calls the parameter
|
||||
function for each. Ignores comment lines, stops and backs up in file when
|
||||
a section is encountered. Returns True on success, False on error.
|
||||
**************************************************************************/
|
||||
static BOOL enumerate_parameters(FILE *fileIn, PM_PARMFUNC pfunc)
|
||||
{
|
||||
pstring szBuf;
|
||||
char *pszTemp;
|
||||
BOOL bRetval;
|
||||
long lFileOffset;
|
||||
int cTemp;
|
||||
BOOL bParmFound;
|
||||
|
||||
bRetval = False;
|
||||
bParmFound = False;
|
||||
while (True)
|
||||
{
|
||||
/* first remember where we are */
|
||||
if ((lFileOffset = ftell(fileIn)) >= 0L)
|
||||
{
|
||||
/* then get and check a line */
|
||||
if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL)
|
||||
{
|
||||
/* stop - return OK unless file error */
|
||||
bRetval = !ferror(fileIn);
|
||||
if (!bRetval)
|
||||
DEBUG(0,( "Read error on configuration file (enumerating parameters)!\n"));
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* if first non-white is a '[', stop (new section) */
|
||||
if ((cTemp = firstnonwhite(szBuf)) == '[')
|
||||
{
|
||||
/* restore position to start of new section */
|
||||
if (fseek(fileIn, lFileOffset, SEEK_SET) < 0L)
|
||||
{
|
||||
DEBUG(0,( "Seek error on configuration file!\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* return success */
|
||||
bRetval = True;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* if it's a semicolon or line is blank, ignore the line */
|
||||
if (!cTemp || strchr(";#",cTemp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
/* if no equals sign and line contains non-whitespace */
|
||||
/* then line is badly formed */
|
||||
if ((pszTemp = strchr(szBuf, '=')) == NULL)
|
||||
{
|
||||
DEBUG(0,( "Ignoring badly formed line: %s", szBuf));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Note that we have found a parameter */
|
||||
bParmFound = True;
|
||||
/* cut line at the equals sign */
|
||||
*pszTemp++ = '\0';
|
||||
/* trim leading and trailing space from both halves */
|
||||
trimright(szBuf);
|
||||
trimleft(szBuf);
|
||||
trimright(pszTemp);
|
||||
trimleft(pszTemp);
|
||||
/* process the parameter iff passed pointer not NULL */
|
||||
if (pfunc != NULL)
|
||||
if (!pfunc(szBuf, pszTemp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (bRetval);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Close up s by n chars, at offset start.
|
||||
***********************************************************************/
|
||||
static void closestr(char *s, int start, int n)
|
||||
{
|
||||
char *src;
|
||||
char *dest;
|
||||
int len;
|
||||
|
||||
if (n > 0)
|
||||
if ((src = dest = s) != NULL)
|
||||
{
|
||||
len = strlen(s);
|
||||
if (start >= 0 && start < len - n)
|
||||
{
|
||||
src += start + n;
|
||||
dest += start;
|
||||
|
||||
while (*src)
|
||||
*dest++ = *src++;
|
||||
*dest = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Identifies all sections in the parameter file, calls passed section_func()
|
||||
for each, passing the section name, then calls enumerate_parameters().
|
||||
Returns True on success, False on failure. Note that the section and
|
||||
parameter names will have all internal whitespace areas collapsed to a
|
||||
single space for processing.
|
||||
**************************************************************************/
|
||||
static BOOL enumerate_sections(FILE *fileIn,
|
||||
PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
|
||||
{
|
||||
pstring szBuf;
|
||||
BOOL bRetval;
|
||||
BOOL bSectionFound;
|
||||
|
||||
/* this makes sure we get include lines right */
|
||||
enumerate_parameters(fileIn, pfunc);
|
||||
|
||||
bRetval = False;
|
||||
bSectionFound = False;
|
||||
while (True)
|
||||
{
|
||||
if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL)
|
||||
{
|
||||
/* stop - return OK unless file error */
|
||||
bRetval = !ferror(fileIn);
|
||||
if (!bRetval)
|
||||
DEBUG(0,( "Read error on configuration file (enumerating sections)!\n"));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
trimleft(szBuf);
|
||||
trimright(szBuf);
|
||||
if (szBuf[0] == '[')
|
||||
{
|
||||
closestr(szBuf, 0, 1);
|
||||
if (strlen(szBuf) > 1)
|
||||
if (szBuf[strlen(szBuf) - 1] == ']')
|
||||
{
|
||||
/* found a section - note the fact */
|
||||
bSectionFound = True;
|
||||
/* remove trailing metabracket */
|
||||
szBuf[strlen(szBuf) - 1] = '\0';
|
||||
/* remove leading and trailing whitespace from name */
|
||||
trimleft(szBuf);
|
||||
trimright(szBuf);
|
||||
/* reduce all internal whitespace to one space */
|
||||
collapse_spaces(szBuf);
|
||||
/* process it - stop if the processing fails */
|
||||
if (sfunc != NULL)
|
||||
if (!sfunc(szBuf))
|
||||
break;
|
||||
if (!enumerate_parameters(fileIn, pfunc))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (bRetval);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Process the passed parameter file.
|
||||
|
||||
Returns True if successful, else False.
|
||||
**************************************************************************/
|
||||
BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
|
||||
{
|
||||
FILE *fileIn;
|
||||
BOOL bRetval;
|
||||
|
||||
bRetval = False;
|
||||
|
||||
/* record the filename for use in error messages one day... */
|
||||
pszParmFile = pszFileName;
|
||||
|
||||
if (pszParmFile == NULL || strlen(pszParmFile) < 1)
|
||||
DEBUG(0,( "No configuration filename specified!\n"));
|
||||
else
|
||||
if ((fileIn = fopen(pszParmFile, "r")) == NULL)
|
||||
DEBUG(0,( "Unable to open configuration file \"%s\"!\n", pszParmFile));
|
||||
else
|
||||
{
|
||||
DEBUG(2,( "Processing configuration file \"%s\"\n", pszParmFile));
|
||||
bRetval = enumerate_sections(fileIn, sfunc, pfunc);
|
||||
fclose(fileIn);
|
||||
}
|
||||
|
||||
if (!bRetval)
|
||||
DEBUG(0,("pm_process retuned false\n"));
|
||||
return (bRetval);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Strip all leading whitespace from a string.
|
||||
**************************************************************************/
|
||||
static void trimleft(char *psz)
|
||||
{
|
||||
char *pszDest;
|
||||
|
||||
pszDest = psz;
|
||||
if (psz != NULL)
|
||||
{
|
||||
while (*psz != '\0' && isspace(*psz))
|
||||
psz++;
|
||||
while (*psz != '\0')
|
||||
*pszDest++ = *psz++;
|
||||
*pszDest = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Strip all trailing whitespace from a string.
|
||||
**************************************************************************/
|
||||
static void trimright(char *psz)
|
||||
{
|
||||
char *pszTemp;
|
||||
|
||||
if (psz != NULL && psz[0] != '\0')
|
||||
{
|
||||
pszTemp = psz + strlen(psz) - 1;
|
||||
while (isspace(*pszTemp))
|
||||
*pszTemp-- = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Collapse each whitespace area in a string to a single space.
|
||||
***********************************************************************/
|
||||
static void collapse_spaces(char *psz)
|
||||
{
|
||||
while (*psz)
|
||||
if (isspace(*psz))
|
||||
{
|
||||
*psz++ = ' ';
|
||||
trimleft(psz);
|
||||
}
|
||||
else
|
||||
psz++;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Return the value of the first non-white character in the specified string.
|
||||
The terminating NUL counts as non-white for the purposes of this function.
|
||||
Note - no check for a NULL string! What would we return?
|
||||
**************************************************************************/
|
||||
static int firstnonwhite(char *psz)
|
||||
{
|
||||
while (isspace(*psz) && (*psz != '\0'))
|
||||
psz++;
|
||||
return (*psz);
|
||||
}
|
304
source3/passdb/smbpass.c
Normal file
304
source3/passdb/smbpass.c
Normal file
@ -0,0 +1,304 @@
|
||||
#ifdef SMB_PASSWD
|
||||
/*
|
||||
* Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
|
||||
* Copyright (C) Andrew Tridgell 1992-1995 Modified by Jeremy Allison 1995.
|
||||
*
|
||||
* 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., 675
|
||||
* Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
int gotalarm;
|
||||
|
||||
void
|
||||
gotalarm_sig()
|
||||
{
|
||||
gotalarm = 1;
|
||||
}
|
||||
|
||||
int
|
||||
do_pw_lock(int fd, int waitsecs, int type)
|
||||
{
|
||||
struct flock lock;
|
||||
int ret;
|
||||
|
||||
gotalarm = 0;
|
||||
signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
|
||||
|
||||
lock.l_type = type;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 1;
|
||||
lock.l_pid = 0;
|
||||
|
||||
alarm(5);
|
||||
ret = fcntl(fd, F_SETLKW, &lock);
|
||||
alarm(0);
|
||||
signal(SIGALRM, SIGNAL_CAST SIG_DFL);
|
||||
|
||||
if (gotalarm) {
|
||||
DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
|
||||
type == F_UNLCK ? "unlock" : "lock"));
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
pw_file_lock(char *name, int type, int secs)
|
||||
{
|
||||
int fd = open(name, O_RDWR | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
return (-1);
|
||||
if (do_pw_lock(fd, secs, type)) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
pw_file_unlock(int fd)
|
||||
{
|
||||
do_pw_lock(fd, 5, F_UNLCK);
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine to get the next 32 hex characters and turn them
|
||||
* into a 16 byte array.
|
||||
*/
|
||||
|
||||
static int gethexpwd(char *p, char *pwd)
|
||||
{
|
||||
int i;
|
||||
unsigned char lonybble, hinybble;
|
||||
char *hexchars = "0123456789ABCDEF";
|
||||
char *p1, *p2;
|
||||
|
||||
for (i = 0; i < 32; i += 2) {
|
||||
hinybble = toupper(p[i]);
|
||||
lonybble = toupper(p[i + 1]);
|
||||
|
||||
p1 = strchr(hexchars, hinybble);
|
||||
p2 = strchr(hexchars, lonybble);
|
||||
if (!p1 || !p2)
|
||||
return (False);
|
||||
hinybble = PTR_DIFF(p1, hexchars);
|
||||
lonybble = PTR_DIFF(p2, hexchars);
|
||||
|
||||
pwd[i / 2] = (hinybble << 4) | lonybble;
|
||||
}
|
||||
return (True);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine to search the smbpasswd file for an entry matching the username.
|
||||
*/
|
||||
struct smb_passwd *
|
||||
get_smbpwnam(char *name)
|
||||
{
|
||||
/* Static buffers we will return. */
|
||||
static struct smb_passwd pw_buf;
|
||||
static pstring user_name;
|
||||
static unsigned char smbpwd[16];
|
||||
static unsigned char smbntpwd[16];
|
||||
char linebuf[256];
|
||||
char readbuf[16 * 1024];
|
||||
unsigned char c;
|
||||
unsigned char *p;
|
||||
long uidval;
|
||||
long linebuf_len;
|
||||
FILE *fp;
|
||||
int lockfd;
|
||||
char *pfile = lp_smb_passwd_file();
|
||||
|
||||
if (!*pfile) {
|
||||
DEBUG(0, ("No SMB password file set\n"));
|
||||
return (NULL);
|
||||
}
|
||||
DEBUG(10, ("get_smbpwnam: opening file %s\n", pfile));
|
||||
|
||||
fp = fopen(pfile, "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
DEBUG(0, ("get_smbpwnam: unable to open file %s\n", pfile));
|
||||
return NULL;
|
||||
}
|
||||
/* Set a 16k buffer to do more efficient reads */
|
||||
setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
|
||||
|
||||
if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) {
|
||||
DEBUG(0, ("get_smbpwnam: unable to lock file %s\n", pfile));
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
/* make sure it is only rw by the owner */
|
||||
chmod(pfile, 0600);
|
||||
|
||||
/* We have a read lock on the file. */
|
||||
/*
|
||||
* Scan the file, a line at a time and check if the name matches.
|
||||
*/
|
||||
while (!feof(fp)) {
|
||||
linebuf[0] = '\0';
|
||||
|
||||
fgets(linebuf, 256, fp);
|
||||
if (ferror(fp)) {
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Check if the string is terminated with a newline - if not
|
||||
* then we must keep reading and discard until we get one.
|
||||
*/
|
||||
linebuf_len = strlen(linebuf);
|
||||
if (linebuf[linebuf_len - 1] != '\n') {
|
||||
c = '\0';
|
||||
while (!ferror(fp) && !feof(fp)) {
|
||||
c = fgetc(fp);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
} else
|
||||
linebuf[linebuf_len - 1] = '\0';
|
||||
|
||||
#ifdef DEBUG_PASSWORD
|
||||
DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
|
||||
#endif
|
||||
if ((linebuf[0] == 0) && feof(fp)) {
|
||||
DEBUG(4, ("get_smbpwnam: end of file reached\n"));
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* The line we have should be of the form :-
|
||||
*
|
||||
* username:uid:[32hex bytes]:....other flags presently
|
||||
* ignored....
|
||||
*
|
||||
* or,
|
||||
*
|
||||
* username:uid:[32hex bytes]:[32hex bytes]:....ignored....
|
||||
*
|
||||
* if Windows NT compatible passwords are also present.
|
||||
*/
|
||||
|
||||
if (linebuf[0] == '#' || linebuf[0] == '\0') {
|
||||
DEBUG(6, ("get_smbpwnam: skipping comment or blank line\n"));
|
||||
continue;
|
||||
}
|
||||
p = (unsigned char *) strchr(linebuf, ':');
|
||||
if (p == NULL) {
|
||||
DEBUG(0, ("get_smbpwnam: malformed password entry (no :)\n"));
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* As 256 is shorter than a pstring we don't need to check
|
||||
* length here - if this ever changes....
|
||||
*/
|
||||
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
|
||||
user_name[PTR_DIFF(p, linebuf)] = '\0';
|
||||
if (!strequal(user_name, name))
|
||||
continue;
|
||||
|
||||
/* User name matches - get uid and password */
|
||||
p++; /* Go past ':' */
|
||||
if (!isdigit(*p)) {
|
||||
DEBUG(0, ("get_smbpwnam: malformed password entry (uid not number)\n"));
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
uidval = atoi((char *) p);
|
||||
while (*p && isdigit(*p))
|
||||
p++;
|
||||
if (*p != ':') {
|
||||
DEBUG(0, ("get_smbpwnam: malformed password entry (no : after uid)\n"));
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Now get the password value - this should be 32 hex digits
|
||||
* which are the ascii representations of a 16 byte string.
|
||||
* Get two at a time and put them into the password.
|
||||
*/
|
||||
p++;
|
||||
if (*p == '*' || *p == 'X') {
|
||||
/* Password deliberately invalid - end here. */
|
||||
DEBUG(10, ("get_smbpwnam: entry invalidated for user %s\n", user_name));
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
|
||||
DEBUG(0, ("get_smbpwnam: malformed password entry (passwd too short)\n"));
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return (False);
|
||||
}
|
||||
if (p[32] != ':') {
|
||||
DEBUG(0, ("get_smbpwnam: malformed password entry (no terminating :)\n"));
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
|
||||
pw_buf.smb_passwd = NULL;
|
||||
} else {
|
||||
if(!gethexpwd(p,smbpwd)) {
|
||||
DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n"));
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
pw_buf.smb_passwd = smbpwd;
|
||||
}
|
||||
pw_buf.smb_name = user_name;
|
||||
pw_buf.smb_userid = uidval;
|
||||
pw_buf.smb_nt_passwd = NULL;
|
||||
|
||||
/* Now check if the NT compatible password is
|
||||
available. */
|
||||
p += 33; /* Move to the first character of the line after
|
||||
the lanman password. */
|
||||
if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
|
||||
if (*p != '*' && *p != 'X') {
|
||||
if(gethexpwd(p,smbntpwd))
|
||||
pw_buf.smb_nt_passwd = smbntpwd;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n",
|
||||
user_name, uidval));
|
||||
return &pw_buf;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
pw_file_unlock(lockfd);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
void
|
||||
smbpass_dummy(void)
|
||||
{
|
||||
} /* To avoid compiler complaints */
|
||||
#endif
|
383
source3/printing/pcap.c
Normal file
383
source3/printing/pcap.c
Normal file
@ -0,0 +1,383 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
printcap parsing
|
||||
Copyright (C) Karl Auer 1993,1994
|
||||
|
||||
Re-working by Martin Kiff, 1994
|
||||
|
||||
Re-written again by Andrew Tridgell
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parse printcap file.
|
||||
*
|
||||
* This module does exactly one thing - it looks into the printcap file
|
||||
* and tells callers if a specified string appears as a printer name.
|
||||
*
|
||||
* The way this module looks at the printcap file is very simplistic.
|
||||
* Only the local printcap file is inspected (no searching of NIS
|
||||
* databases etc).
|
||||
*
|
||||
* There are assumed to be one or more printer names per record, held
|
||||
* as a set of sub-fields separated by vertical bar symbols ('|') in the
|
||||
* first field of the record. The field separator is assumed to be a colon
|
||||
* ':' and the record separator a newline.
|
||||
*
|
||||
* Lines ending with a backspace '\' are assumed to flag that the following
|
||||
* line is a continuation line so that a set of lines can be read as one
|
||||
* printcap entry.
|
||||
*
|
||||
* A line stating with a hash '#' is assumed to be a comment and is ignored
|
||||
* Comments are discarded before the record is strung together from the
|
||||
* set of continuation lines.
|
||||
*
|
||||
* Opening a pipe for "lpc status" and reading that would probably
|
||||
* be pretty effective. Code to do this already exists in the freely
|
||||
* distributable PCNFS server code.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "smb.h"
|
||||
#include "loadparm.h"
|
||||
#include "pcap.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
#ifdef AIX
|
||||
/* ******************************************
|
||||
Extend for AIX system and qconfig file
|
||||
from 'boulard@univ-rennes1.fr
|
||||
****************************************** */
|
||||
static int strlocate(char *xpLine,char *xpS)
|
||||
{
|
||||
int iS,iL,i,iRet;
|
||||
char *p;
|
||||
iS = strlen(xpS);
|
||||
iL = strlen(xpLine);
|
||||
|
||||
iRet = 0;
|
||||
p = xpLine;
|
||||
while (iL >= iS)
|
||||
{
|
||||
if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
|
||||
p++;
|
||||
iL--;
|
||||
}
|
||||
/*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
|
||||
|
||||
return(iRet);
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************* */
|
||||
/* * Scan qconfig and search all virtual printer (device printer) * */
|
||||
/* ******************************************************************* */
|
||||
static void ScanQconfig_fn(char *psz,void (*fn)())
|
||||
{
|
||||
int iLg,iEtat;
|
||||
FILE *pfile;
|
||||
char *line,*p;
|
||||
pstring name,comment;
|
||||
line = NULL;
|
||||
*name = 0;
|
||||
*comment = 0;
|
||||
|
||||
if ((pfile = fopen(psz, "r")) == NULL)
|
||||
{
|
||||
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
|
||||
return;
|
||||
}
|
||||
|
||||
iEtat = 0;
|
||||
/* scan qconfig file for searching <printername>: */
|
||||
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
|
||||
{
|
||||
if (*line == '*' || *line == 0)
|
||||
continue;
|
||||
switch (iEtat)
|
||||
{
|
||||
case 0: /* locate an entry */
|
||||
if (*line == '\t' || *line == ' ') continue;
|
||||
if ((p=strchr(line,':')))
|
||||
{
|
||||
*p = '\0';
|
||||
p = strtok(line,":");
|
||||
if (strcmp(p,"bsh")!=0)
|
||||
{
|
||||
strcpy(name,p);
|
||||
iEtat = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: /* scanning device stanza */
|
||||
if (*line == '*' || *line == 0) continue;
|
||||
if (*line != '\t' && *line != ' ')
|
||||
{
|
||||
/* name is found without stanza device */
|
||||
/* probably a good printer ??? */
|
||||
fn(name,comment);
|
||||
iEtat = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlocate(line,"backend"))
|
||||
{
|
||||
/* it's a device, not a virtual printer*/
|
||||
iEtat = 0;
|
||||
}
|
||||
else if (strlocate(line,"device"))
|
||||
{
|
||||
/* it's a good virtual printer */
|
||||
fn(name,comment);
|
||||
iEtat = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(pfile);
|
||||
}
|
||||
|
||||
/* Scan qconfig file and locate de printername */
|
||||
|
||||
static BOOL ScanQconfig(char *psz,char *pszPrintername)
|
||||
{
|
||||
int iLg,iEtat;
|
||||
FILE *pfile;
|
||||
char *pName;
|
||||
char *line;
|
||||
|
||||
pName = NULL;
|
||||
line = NULL;
|
||||
if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
|
||||
pName = malloc(iLg+10);
|
||||
if (pName == NULL)
|
||||
{
|
||||
DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
|
||||
return(False);
|
||||
}
|
||||
if ((pfile = fopen(psz, "r")) == NULL)
|
||||
{
|
||||
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
|
||||
free(pName);
|
||||
return(False);
|
||||
}
|
||||
sprintf(pName,"%s:",pszPrintername);
|
||||
iLg = strlen(pName);
|
||||
/*DEBUG(3,( " Looking for entry %s\n",pName));*/
|
||||
iEtat = 0;
|
||||
/* scan qconfig file for searching <printername>: */
|
||||
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
|
||||
{
|
||||
if (*line == '*' || *line == 0)
|
||||
continue;
|
||||
switch (iEtat)
|
||||
{
|
||||
case 0: /* scanning entry */
|
||||
if (strncmp(line,pName,iLg) == 0)
|
||||
{
|
||||
iEtat = 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 1: /* scanning device stanza */
|
||||
if (*line == '*' || *line == 0) continue;
|
||||
if (*line != '\t' && *line != ' ')
|
||||
{
|
||||
/* name is found without stanza device */
|
||||
/* probably a good printer ??? */
|
||||
free (line);
|
||||
free(pName);
|
||||
fclose(pfile);
|
||||
return(True);
|
||||
}
|
||||
|
||||
if (strlocate(line,"backend"))
|
||||
{
|
||||
/* it's a device, not a virtual printer*/
|
||||
iEtat = 0;
|
||||
}
|
||||
else if (strlocate(line,"device"))
|
||||
{
|
||||
/* it's a good virtual printer */
|
||||
free (line);
|
||||
free(pName);
|
||||
fclose(pfile);
|
||||
return(True);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free (pName);
|
||||
fclose(pfile);
|
||||
return(False);
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
Scan printcap file pszPrintcapname for a printer called pszPrintername.
|
||||
Return True if found, else False. Returns False on error, too, after logging
|
||||
the error at level 0. For generality, the printcap name may be passed - if
|
||||
passed as NULL, the configuration will be queried for the name.
|
||||
***************************************************************************/
|
||||
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
|
||||
{
|
||||
char *line=NULL;
|
||||
char *psz;
|
||||
char *p,*q;
|
||||
FILE *pfile;
|
||||
|
||||
if (pszPrintername == NULL || pszPrintername[0] == '\0')
|
||||
{
|
||||
DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* only go looking if no printcap name supplied */
|
||||
if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
|
||||
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
|
||||
{
|
||||
DEBUG(0,( "No printcap file name configured!\n"));
|
||||
return(False);
|
||||
}
|
||||
#ifdef AIX
|
||||
if (strlocate(psz,"/qconfig") != NULL)
|
||||
return(ScanQconfig(psz,pszPrintername));
|
||||
#endif
|
||||
if ((pfile = fopen(psz, "r")) == NULL)
|
||||
{
|
||||
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
|
||||
return(False);
|
||||
}
|
||||
|
||||
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
|
||||
{
|
||||
if (*line == '#' || *line == 0)
|
||||
continue;
|
||||
|
||||
/* now we have a real printer line - cut it off at the first : */
|
||||
p = strchr(line,':');
|
||||
if (p) *p = 0;
|
||||
|
||||
/* now just check if the name is in the list */
|
||||
/* NOTE: I avoid strtok as the fn calling this one may be using it */
|
||||
for (p=line; p; p=q)
|
||||
{
|
||||
if ((q = strchr(p,'|'))) *q++ = 0;
|
||||
|
||||
if (strequal(p,pszPrintername))
|
||||
{
|
||||
/* normalise the case */
|
||||
strcpy(pszPrintername,p);
|
||||
free(line);
|
||||
fclose(pfile);
|
||||
return(True);
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fclose(pfile);
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
run a function on each printer name in the printcap file. The function is
|
||||
passed the primary name and the comment (if possible)
|
||||
***************************************************************************/
|
||||
void pcap_printer_fn(void (*fn)())
|
||||
{
|
||||
pstring name,comment;
|
||||
char *line;
|
||||
char *psz;
|
||||
char *p,*q;
|
||||
FILE *pfile;
|
||||
|
||||
/* only go looking if no printcap name supplied */
|
||||
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
|
||||
{
|
||||
DEBUG(0,( "No printcap file name configured!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef AIX
|
||||
if (strlocate(psz,"/qconfig") != NULL)
|
||||
{
|
||||
ScanQconfig_fn(psz,fn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((pfile = fopen(psz, "r")) == NULL)
|
||||
{
|
||||
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
|
||||
return;
|
||||
}
|
||||
|
||||
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
|
||||
{
|
||||
if (*line == '#' || *line == 0)
|
||||
continue;
|
||||
|
||||
/* now we have a real printer line - cut it off at the first : */
|
||||
p = strchr(line,':');
|
||||
if (p) *p = 0;
|
||||
|
||||
/* now find the most likely printer name and comment
|
||||
this is pure guesswork, but it's better than nothing */
|
||||
*name = 0;
|
||||
*comment = 0;
|
||||
for (p=line; p; p=q)
|
||||
{
|
||||
BOOL has_punctuation;
|
||||
if ((q = strchr(p,'|'))) *q++ = 0;
|
||||
|
||||
has_punctuation = (strchr(p,' ') || strchr(p,'(') || strchr(p,')'));
|
||||
|
||||
if (strlen(p)>strlen(comment) && has_punctuation)
|
||||
{
|
||||
StrnCpy(comment,p,sizeof(comment)-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen(p) <= 8 && strlen(p)>strlen(name) && !has_punctuation)
|
||||
{
|
||||
if (!*comment) strcpy(comment,name);
|
||||
strcpy(name,p);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strchr(comment,' ') &&
|
||||
strlen(p) > strlen(comment))
|
||||
{
|
||||
StrnCpy(comment,p,sizeof(comment)-1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
comment[60] = 0;
|
||||
name[8] = 0;
|
||||
|
||||
if (*name)
|
||||
fn(name,comment);
|
||||
}
|
||||
fclose(pfile);
|
||||
}
|
859
source3/printing/printing.c
Normal file
859
source3/printing/printing.c
Normal file
@ -0,0 +1,859 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
printing routines
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
extern int DEBUGLEVEL;
|
||||
extern connection_struct Connections[];
|
||||
extern files_struct Files[];
|
||||
|
||||
static BOOL * lpq_cache_reset=NULL;
|
||||
|
||||
static int check_lpq_cache(int snum) {
|
||||
static int lpq_caches=0;
|
||||
|
||||
if (lpq_caches <= snum) {
|
||||
BOOL * p;
|
||||
p = (BOOL *) Realloc(lpq_cache_reset,(snum+1)*sizeof(BOOL));
|
||||
if (p) {
|
||||
lpq_cache_reset=p;
|
||||
lpq_caches = snum+1;
|
||||
}
|
||||
}
|
||||
return lpq_caches;
|
||||
}
|
||||
|
||||
void lpq_reset(int snum)
|
||||
{
|
||||
if (check_lpq_cache(snum) > snum) lpq_cache_reset[snum]=True;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Build the print command in the supplied buffer. This means getting the
|
||||
print command for the service and inserting the printer name and the
|
||||
print file name. Return NULL on error, else the passed buffer pointer.
|
||||
****************************************************************************/
|
||||
static char *build_print_command(int cnum, char *command, char *syscmd, char *filename1)
|
||||
{
|
||||
int snum = SNUM(cnum);
|
||||
char *tstr;
|
||||
pstring filename;
|
||||
|
||||
/* get the print command for the service. */
|
||||
tstr = command;
|
||||
if (!syscmd || !tstr) {
|
||||
DEBUG(0,("No print command for service `%s'\n", SERVICE(snum)));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* copy the command into the buffer for extensive meddling. */
|
||||
StrnCpy(syscmd, tstr, sizeof(pstring) - 1);
|
||||
|
||||
/* look for "%s" in the string. If there is no %s, we cannot print. */
|
||||
if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) {
|
||||
DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
|
||||
}
|
||||
|
||||
if (strstr(syscmd,"%s")) {
|
||||
int iOffset = strstr(syscmd, "%s") - syscmd;
|
||||
|
||||
/* construct the full path for the filename, shouldn't be necessary unless
|
||||
the subshell causes a "cd" to be executed.
|
||||
Only use the full path if there isn't a / preceding the %s */
|
||||
if (iOffset==0 || syscmd[iOffset-1] != '/') {
|
||||
StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1);
|
||||
trim_string(filename,"","/");
|
||||
strcat(filename,"/");
|
||||
strcat(filename,filename1);
|
||||
}
|
||||
else
|
||||
strcpy(filename,filename1);
|
||||
|
||||
string_sub(syscmd, "%s", filename);
|
||||
}
|
||||
|
||||
string_sub(syscmd, "%f", filename1);
|
||||
|
||||
/* Does the service have a printername? If not, make a fake and empty */
|
||||
/* printer name. That way a %p is treated sanely if no printer */
|
||||
/* name was specified to replace it. This eventuality is logged. */
|
||||
tstr = PRINTERNAME(snum);
|
||||
if (tstr == NULL || tstr[0] == '\0') {
|
||||
DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum)));
|
||||
tstr = SERVICE(snum);
|
||||
}
|
||||
|
||||
string_sub(syscmd, "%p", tstr);
|
||||
|
||||
standard_sub(cnum,syscmd);
|
||||
|
||||
return (syscmd);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
print a file - called on closing the file
|
||||
****************************************************************************/
|
||||
void print_file(int fnum)
|
||||
{
|
||||
pstring syscmd;
|
||||
int cnum = Files[fnum].cnum;
|
||||
int snum=SNUM(cnum);
|
||||
char *tempstr;
|
||||
|
||||
*syscmd = 0;
|
||||
|
||||
if (file_size(Files[fnum].name) <= 0) {
|
||||
DEBUG(3,("Discarding null print job %s\n",Files[fnum].name));
|
||||
sys_unlink(Files[fnum].name);
|
||||
return;
|
||||
}
|
||||
|
||||
tempstr = build_print_command(cnum, PRINTCOMMAND(snum), syscmd, Files[fnum].name);
|
||||
if (tempstr != NULL)
|
||||
{
|
||||
int ret = smbrun(syscmd,NULL);
|
||||
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
|
||||
}
|
||||
else
|
||||
DEBUG(0,("Null print command?\n"));
|
||||
|
||||
lpq_reset(snum);
|
||||
}
|
||||
|
||||
static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
process time fields
|
||||
********************************************************************/
|
||||
static time_t EntryTime(string tok[], int ptr, int count, int minimum)
|
||||
{
|
||||
time_t jobtime;
|
||||
|
||||
jobtime = time(NULL); /* default case: take current time */
|
||||
if (count >= minimum) {
|
||||
struct tm *t;
|
||||
int i, day, hour, min, sec;
|
||||
char *c;
|
||||
|
||||
for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
|
||||
if (i<12) {
|
||||
t = localtime(&jobtime);
|
||||
day = atoi(tok[ptr+1]);
|
||||
c=(char *)(tok[ptr+2]);
|
||||
*(c+2)=0;
|
||||
hour = atoi(c);
|
||||
*(c+5)=0;
|
||||
min = atoi(c+3);
|
||||
if(*(c+6) != 0)sec = atoi(c+6);
|
||||
else sec=0;
|
||||
|
||||
if ((t->tm_mon < i)||
|
||||
((t->tm_mon == i)&&
|
||||
((t->tm_mday < day)||
|
||||
((t->tm_mday == day)&&
|
||||
(t->tm_hour*60+t->tm_min < hour*60+min)))))
|
||||
t->tm_year--; /* last year's print job */
|
||||
|
||||
t->tm_mon = i;
|
||||
t->tm_mday = day;
|
||||
t->tm_hour = hour;
|
||||
t->tm_min = min;
|
||||
t->tm_sec = sec;
|
||||
jobtime = mktime(t);
|
||||
}
|
||||
}
|
||||
return jobtime;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
parse a lpq line
|
||||
|
||||
here is an example of lpq output under bsd
|
||||
|
||||
Warning: no daemon present
|
||||
Rank Owner Job Files Total Size
|
||||
1st tridge 148 README 8096 bytes
|
||||
|
||||
here is an example of lpq output under osf/1
|
||||
|
||||
Warning: no daemon present
|
||||
Rank Pri Owner Job Files Total Size
|
||||
1st 0 tridge 148 README 8096 bytes
|
||||
****************************************************************************/
|
||||
static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
|
||||
{
|
||||
#ifdef OSF1
|
||||
#define RANKTOK 0
|
||||
#define PRIOTOK 1
|
||||
#define USERTOK 2
|
||||
#define JOBTOK 3
|
||||
#define FILETOK 4
|
||||
#define TOTALTOK 5
|
||||
#define NTOK 6
|
||||
#else /* OSF1 */
|
||||
#define RANKTOK 0
|
||||
#define USERTOK 1
|
||||
#define JOBTOK 2
|
||||
#define FILETOK 3
|
||||
#define TOTALTOK 4
|
||||
#define NTOK 5
|
||||
#endif /* OSF1 */
|
||||
|
||||
string tok[NTOK];
|
||||
int count=0;
|
||||
|
||||
#ifdef OSF1
|
||||
int length;
|
||||
length = strlen(line);
|
||||
if (line[length-3] == ':')
|
||||
return(False);
|
||||
#endif /* OSF1 */
|
||||
|
||||
/* handle the case of "(standard input)" as a filename */
|
||||
string_sub(line,"standard input","STDIN");
|
||||
string_sub(line,"(","\"");
|
||||
string_sub(line,")","\"");
|
||||
|
||||
for (count=0; count<NTOK && next_token(&line,tok[count],NULL); count++) ;
|
||||
|
||||
/* we must get NTOK tokens */
|
||||
if (count < NTOK)
|
||||
return(False);
|
||||
|
||||
/* the Job and Total columns must be integer */
|
||||
if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);
|
||||
|
||||
/* if the fname contains a space then use STDIN */
|
||||
if (strchr(tok[FILETOK],' '))
|
||||
strcpy(tok[FILETOK],"STDIN");
|
||||
|
||||
/* only take the last part of the filename */
|
||||
{
|
||||
string tmp;
|
||||
char *p = strrchr(tok[FILETOK],'/');
|
||||
if (p)
|
||||
{
|
||||
strcpy(tmp,p+1);
|
||||
strcpy(tok[FILETOK],tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf->job = atoi(tok[JOBTOK]);
|
||||
buf->size = atoi(tok[TOTALTOK]);
|
||||
buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
|
||||
buf->time = time(NULL);
|
||||
StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1);
|
||||
StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1);
|
||||
#ifdef PRIOTOK
|
||||
buf->priority = atoi(tok[PRIOTOK]);
|
||||
#else
|
||||
buf->priority = 1;
|
||||
#endif
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
parse lpq on an aix system
|
||||
|
||||
Queue Dev Status Job Files User PP % Blks Cp Rnk
|
||||
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
|
||||
lazer lazer READY
|
||||
lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
|
||||
QUEUED 538 C.ps root@IEDVB 124 1 2
|
||||
QUEUED 539 E.ps root@IEDVB 28 1 3
|
||||
QUEUED 540 L.ps root@IEDVB 172 1 4
|
||||
QUEUED 541 P.ps root@IEDVB 22 1 5
|
||||
********************************************************************/
|
||||
static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
|
||||
{
|
||||
string tok[11];
|
||||
int count=0;
|
||||
|
||||
/* handle the case of "(standard input)" as a filename */
|
||||
string_sub(line,"standard input","STDIN");
|
||||
string_sub(line,"(","\"");
|
||||
string_sub(line,")","\"");
|
||||
|
||||
for (count=0; count<10 && next_token(&line,tok[count],NULL); count++) ;
|
||||
|
||||
/* we must get 6 tokens */
|
||||
if (count < 10)
|
||||
{
|
||||
if ((count == 7) && (strcmp(tok[0],"QUEUED") == 0))
|
||||
{
|
||||
/* the 2nd and 5th columns must be integer */
|
||||
if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False);
|
||||
buf->size = atoi(tok[4]) * 1024;
|
||||
/* if the fname contains a space then use STDIN */
|
||||
if (strchr(tok[2],' '))
|
||||
strcpy(tok[2],"STDIN");
|
||||
|
||||
/* only take the last part of the filename */
|
||||
{
|
||||
string tmp;
|
||||
char *p = strrchr(tok[2],'/');
|
||||
if (p)
|
||||
{
|
||||
strcpy(tmp,p+1);
|
||||
strcpy(tok[2],tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf->job = atoi(tok[1]);
|
||||
buf->status = LPQ_QUEUED;
|
||||
buf->priority = 0;
|
||||
buf->time = time(NULL);
|
||||
StrnCpy(buf->user,tok[3],sizeof(buf->user)-1);
|
||||
StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(6,("parse_lpq_aix count=%d\n", count));
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the 4th and 9th columns must be integer */
|
||||
if (!isdigit(*tok[3]) || !isdigit(*tok[8])) return(False);
|
||||
buf->size = atoi(tok[8]) * 1024;
|
||||
/* if the fname contains a space then use STDIN */
|
||||
if (strchr(tok[4],' '))
|
||||
strcpy(tok[4],"STDIN");
|
||||
|
||||
/* only take the last part of the filename */
|
||||
{
|
||||
string tmp;
|
||||
char *p = strrchr(tok[4],'/');
|
||||
if (p)
|
||||
{
|
||||
strcpy(tmp,p+1);
|
||||
strcpy(tok[4],tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf->job = atoi(tok[3]);
|
||||
buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
|
||||
buf->priority = 0;
|
||||
buf->time = time(NULL);
|
||||
StrnCpy(buf->user,tok[5],sizeof(buf->user)-1);
|
||||
StrnCpy(buf->file,tok[4],sizeof(buf->file)-1);
|
||||
}
|
||||
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
parse a lpq line
|
||||
here is an example of lpq output under hpux; note there's no space after -o !
|
||||
$> lpstat -oljplus
|
||||
ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
|
||||
util.c 125697 bytes
|
||||
server.c 110712 bytes
|
||||
ljplus-2154 user priority 0 Jan 19 08:14 from client
|
||||
(standard input) 7551 bytes
|
||||
****************************************************************************/
|
||||
static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
|
||||
{
|
||||
/* must read two lines to process, therefore keep some values static */
|
||||
static BOOL header_line_ok=False, base_prio_reset=False;
|
||||
static string jobuser;
|
||||
static int jobid;
|
||||
static int jobprio;
|
||||
static time_t jobtime;
|
||||
static int jobstat=LPQ_QUEUED;
|
||||
/* to store minimum priority to print, lpstat command should be invoked
|
||||
with -p option first, to work */
|
||||
static int base_prio;
|
||||
|
||||
int count;
|
||||
char TAB = '\011';
|
||||
string tok[12];
|
||||
|
||||
/* If a line begins with a horizontal TAB, it is a subline type */
|
||||
|
||||
if (line[0] == TAB) { /* subline */
|
||||
/* check if it contains the base priority */
|
||||
if (!strncmp(line,"\tfence priority : ",18)) {
|
||||
base_prio=atoi(&line[18]);
|
||||
DEBUG(4, ("fence priority set at %d\n", base_prio));
|
||||
}
|
||||
if (!header_line_ok) return (False); /* incorrect header line */
|
||||
/* handle the case of "(standard input)" as a filename */
|
||||
string_sub(line,"standard input","STDIN");
|
||||
string_sub(line,"(","\"");
|
||||
string_sub(line,")","\"");
|
||||
|
||||
for (count=0; count<2 && next_token(&line,tok[count],NULL); count++) ;
|
||||
/* we must get 2 tokens */
|
||||
if (count < 2) return(False);
|
||||
|
||||
/* the 2nd column must be integer */
|
||||
if (!isdigit(*tok[1])) return(False);
|
||||
|
||||
/* if the fname contains a space then use STDIN */
|
||||
if (strchr(tok[0],' '))
|
||||
strcpy(tok[0],"STDIN");
|
||||
|
||||
buf->size = atoi(tok[1]);
|
||||
StrnCpy(buf->file,tok[0],sizeof(buf->file)-1);
|
||||
|
||||
/* fill things from header line */
|
||||
buf->time = jobtime;
|
||||
buf->job = jobid;
|
||||
buf->status = jobstat;
|
||||
buf->priority = jobprio;
|
||||
StrnCpy(buf->user,jobuser,sizeof(buf->user)-1);
|
||||
|
||||
return(True);
|
||||
}
|
||||
else { /* header line */
|
||||
header_line_ok=False; /* reset it */
|
||||
if (first) {
|
||||
if (!base_prio_reset) {
|
||||
base_prio=0; /* reset it */
|
||||
base_prio_reset=True;
|
||||
}
|
||||
}
|
||||
else if (base_prio) base_prio_reset=False;
|
||||
|
||||
/* handle the dash in the job id */
|
||||
string_sub(line,"-"," ");
|
||||
|
||||
for (count=0; count<12 && next_token(&line,tok[count],NULL); count++) ;
|
||||
|
||||
/* we must get 8 tokens */
|
||||
if (count < 8) return(False);
|
||||
|
||||
/* first token must be printer name (cannot check ?) */
|
||||
/* the 2nd, 5th & 7th column must be integer */
|
||||
if (!isdigit(*tok[1]) || !isdigit(*tok[4]) || !isdigit(*tok[6])) return(False);
|
||||
jobid = atoi(tok[1]);
|
||||
StrnCpy(jobuser,tok[2],sizeof(buf->user)-1);
|
||||
jobprio = atoi(tok[4]);
|
||||
|
||||
/* process time */
|
||||
jobtime=EntryTime(tok, 5, count, 8);
|
||||
if (jobprio < base_prio) {
|
||||
jobstat = LPQ_PAUSED;
|
||||
DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat));
|
||||
}
|
||||
else {
|
||||
jobstat = LPQ_QUEUED;
|
||||
if ((count >8) && (((strequal(tok[8],"on")) ||
|
||||
((strequal(tok[8],"from")) &&
|
||||
((count > 10)&&(strequal(tok[10],"on")))))))
|
||||
jobstat = LPQ_PRINTING;
|
||||
}
|
||||
|
||||
header_line_ok=True; /* information is correct */
|
||||
return(False); /* need subline info to include into queuelist */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
parse a lpq line
|
||||
|
||||
here is an example of "lpstat -o dcslw" output under sysv
|
||||
|
||||
dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
|
||||
dcslw-897 tridge 4712 Dec 20 10:30:30 being held
|
||||
|
||||
****************************************************************************/
|
||||
static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
|
||||
{
|
||||
string tok[9];
|
||||
int count=0;
|
||||
char *p;
|
||||
|
||||
/* handle the dash in the job id */
|
||||
string_sub(line,"-"," ");
|
||||
|
||||
for (count=0; count<9 && next_token(&line,tok[count],NULL); count++) ;
|
||||
|
||||
/* we must get 7 tokens */
|
||||
if (count < 7)
|
||||
return(False);
|
||||
|
||||
/* the 2nd and 4th, 6th columns must be integer */
|
||||
if (!isdigit(*tok[1]) || !isdigit(*tok[3])) return(False);
|
||||
if (!isdigit(*tok[5])) return(False);
|
||||
|
||||
/* if the user contains a ! then trim the first part of it */
|
||||
if ((p=strchr(tok[2],'!')))
|
||||
{
|
||||
string tmp;
|
||||
strcpy(tmp,p+1);
|
||||
strcpy(tok[2],tmp);
|
||||
}
|
||||
|
||||
|
||||
buf->job = atoi(tok[1]);
|
||||
buf->size = atoi(tok[3]);
|
||||
if (count > 7 && strequal(tok[7],"on"))
|
||||
buf->status = LPQ_PRINTING;
|
||||
else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held"))
|
||||
buf->status = LPQ_PAUSED;
|
||||
else
|
||||
buf->status = LPQ_QUEUED;
|
||||
buf->priority = 0;
|
||||
buf->time = EntryTime(tok, 4, count, 7);
|
||||
StrnCpy(buf->user,tok[2],sizeof(buf->user)-1);
|
||||
StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
parse a lpq line
|
||||
|
||||
here is an example of lpq output under qnx
|
||||
Spooler: /qnx/spooler, on node 1
|
||||
Printer: txt (ready)
|
||||
0000: root [job #1 ] active 1146 bytes /etc/profile
|
||||
0001: root [job #2 ] ready 2378 bytes /etc/install
|
||||
0002: root [job #3 ] ready 1146 bytes -- standard input --
|
||||
****************************************************************************/
|
||||
static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
|
||||
{
|
||||
string tok[7];
|
||||
int count=0;
|
||||
|
||||
DEBUG(0,("antes [%s]\n", line));
|
||||
|
||||
/* handle the case of "-- standard input --" as a filename */
|
||||
string_sub(line,"standard input","STDIN");
|
||||
DEBUG(0,("despues [%s]\n", line));
|
||||
string_sub(line,"-- ","\"");
|
||||
string_sub(line," --","\"");
|
||||
DEBUG(0,("despues 1 [%s]\n", line));
|
||||
|
||||
string_sub(line,"[job #","");
|
||||
string_sub(line,"]","");
|
||||
DEBUG(0,("despues 2 [%s]\n", line));
|
||||
|
||||
|
||||
|
||||
for (count=0; count<7 && next_token(&line,tok[count],NULL); count++) ;
|
||||
|
||||
/* we must get 7 tokens */
|
||||
if (count < 7)
|
||||
return(False);
|
||||
|
||||
/* the 3rd and 5th columns must be integer */
|
||||
if (!isdigit(*tok[2]) || !isdigit(*tok[4])) return(False);
|
||||
|
||||
/* only take the last part of the filename */
|
||||
{
|
||||
string tmp;
|
||||
char *p = strrchr(tok[6],'/');
|
||||
if (p)
|
||||
{
|
||||
strcpy(tmp,p+1);
|
||||
strcpy(tok[6],tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf->job = atoi(tok[2]);
|
||||
buf->size = atoi(tok[4]);
|
||||
buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
|
||||
buf->priority = 0;
|
||||
buf->time = time(NULL);
|
||||
StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
|
||||
StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
|
||||
char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
|
||||
char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
|
||||
|
||||
/****************************************************************************
|
||||
parse a lpq line. Choose printing style
|
||||
****************************************************************************/
|
||||
static BOOL parse_lpq_entry(int snum,char *line,
|
||||
print_queue_struct *buf,
|
||||
print_status_struct *status,BOOL first)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
switch (lp_printing())
|
||||
{
|
||||
case PRINT_SYSV:
|
||||
ret = parse_lpq_sysv(line,buf,first);
|
||||
break;
|
||||
case PRINT_AIX:
|
||||
ret = parse_lpq_aix(line,buf,first);
|
||||
break;
|
||||
case PRINT_HPUX:
|
||||
ret = parse_lpq_hpux(line,buf,first);
|
||||
break;
|
||||
case PRINT_QNX:
|
||||
ret = parse_lpq_qnx(line,buf,first);
|
||||
break;
|
||||
default:
|
||||
ret = parse_lpq_bsd(line,buf,first);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef LPQ_GUEST_TO_USER
|
||||
if (ret) {
|
||||
extern pstring sesssetup_user;
|
||||
/* change guest entries to the current logged in user to make
|
||||
them appear deletable to windows */
|
||||
if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum)))
|
||||
strcpy(buf->user,sesssetup_user);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status && !ret)
|
||||
{
|
||||
/* a few simple checks to see if the line might be a
|
||||
printer status line:
|
||||
handle them so that most severe condition is shown */
|
||||
int i;
|
||||
strlower(line);
|
||||
|
||||
switch (status->status) {
|
||||
case LPSTAT_OK:
|
||||
for (i=0; stat0_strings[i]; i++)
|
||||
if (strstr(line,stat0_strings[i])) {
|
||||
StrnCpy(status->message,line,sizeof(status->message)-1);
|
||||
status->status=LPSTAT_OK;
|
||||
}
|
||||
case LPSTAT_STOPPED:
|
||||
for (i=0; stat1_strings[i]; i++)
|
||||
if (strstr(line,stat1_strings[i])) {
|
||||
StrnCpy(status->message,line,sizeof(status->message)-1);
|
||||
status->status=LPSTAT_STOPPED;
|
||||
}
|
||||
case LPSTAT_ERROR:
|
||||
for (i=0; stat2_strings[i]; i++)
|
||||
if (strstr(line,stat2_strings[i])) {
|
||||
StrnCpy(status->message,line,sizeof(status->message)-1);
|
||||
status->status=LPSTAT_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get a printer queue
|
||||
****************************************************************************/
|
||||
int get_printqueue(int snum,int cnum,print_queue_struct **queue,
|
||||
print_status_struct *status)
|
||||
{
|
||||
char *lpq_command = lp_lpqcommand(snum);
|
||||
char *printername = PRINTERNAME(snum);
|
||||
int ret=0,count=0;
|
||||
pstring syscmd;
|
||||
fstring outfile;
|
||||
pstring line;
|
||||
FILE *f;
|
||||
struct stat sbuf;
|
||||
BOOL dorun=True;
|
||||
int cachetime = lp_lpqcachetime();
|
||||
int lfd = -1;
|
||||
|
||||
*line = 0;
|
||||
check_lpq_cache(snum);
|
||||
|
||||
if (!printername || !*printername)
|
||||
{
|
||||
DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
|
||||
lp_servicename(snum),snum));
|
||||
printername = lp_servicename(snum);
|
||||
}
|
||||
|
||||
if (!lpq_command || !(*lpq_command))
|
||||
{
|
||||
DEBUG(5,("No lpq command\n"));
|
||||
return(0);
|
||||
}
|
||||
|
||||
strcpy(syscmd,lpq_command);
|
||||
string_sub(syscmd,"%p",printername);
|
||||
|
||||
standard_sub(cnum,syscmd);
|
||||
|
||||
sprintf(outfile,"/tmp/lpq.%08x",str_checksum(syscmd));
|
||||
|
||||
if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf))
|
||||
{
|
||||
if (time(NULL) - sbuf.st_mtime < cachetime) {
|
||||
DEBUG(3,("Using cached lpq output\n"));
|
||||
dorun = False;
|
||||
}
|
||||
|
||||
if (dorun) {
|
||||
lfd = file_lock(outfile,LPQ_LOCK_TIMEOUT);
|
||||
if (lfd<0 ||
|
||||
(!fstat(lfd,&sbuf) && (time(NULL) - sbuf.st_mtime)<cachetime)) {
|
||||
DEBUG(3,("Using cached lpq output\n"));
|
||||
dorun = False;
|
||||
file_unlock(lfd); lfd = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dorun) {
|
||||
ret = smbrun(syscmd,outfile);
|
||||
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
|
||||
}
|
||||
|
||||
lpq_cache_reset[snum] = False;
|
||||
|
||||
f = fopen(outfile,"r");
|
||||
if (!f) {
|
||||
if (lfd >= 0) file_unlock(lfd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
strcpy(status->message,"");
|
||||
status->status = LPSTAT_OK;
|
||||
}
|
||||
|
||||
while (fgets(line,sizeof(pstring),f))
|
||||
{
|
||||
DEBUG(6,("QUEUE2: %s\n",line));
|
||||
|
||||
*queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1));
|
||||
if (! *queue)
|
||||
{
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
bzero((char *)&(*queue)[count],sizeof(**queue));
|
||||
|
||||
/* parse it */
|
||||
if (!parse_lpq_entry(snum,line,&(*queue)[count],status,count==0))
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (lfd >= 0) file_unlock(lfd);
|
||||
|
||||
if (!cachetime)
|
||||
unlink(outfile);
|
||||
else
|
||||
chmod(outfile,0666);
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
delete a printer queue entry
|
||||
****************************************************************************/
|
||||
void del_printqueue(int cnum,int snum,int jobid)
|
||||
{
|
||||
char *lprm_command = lp_lprmcommand(snum);
|
||||
char *printername = PRINTERNAME(snum);
|
||||
pstring syscmd;
|
||||
char jobstr[20];
|
||||
int ret;
|
||||
|
||||
if (!printername || !*printername)
|
||||
{
|
||||
DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
|
||||
lp_servicename(snum),snum));
|
||||
printername = lp_servicename(snum);
|
||||
}
|
||||
|
||||
if (!lprm_command || !(*lprm_command))
|
||||
{
|
||||
DEBUG(5,("No lprm command\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(jobstr,"%d",jobid);
|
||||
|
||||
strcpy(syscmd,lprm_command);
|
||||
string_sub(syscmd,"%p",printername);
|
||||
string_sub(syscmd,"%j",jobstr);
|
||||
standard_sub(cnum,syscmd);
|
||||
|
||||
ret = smbrun(syscmd,NULL);
|
||||
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
|
||||
lpq_reset(snum); /* queue has changed */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
change status of a printer queue entry
|
||||
****************************************************************************/
|
||||
void status_printjob(int cnum,int snum,int jobid,int status)
|
||||
{
|
||||
char *lpstatus_command =
|
||||
(status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum));
|
||||
char *printername = PRINTERNAME(snum);
|
||||
pstring syscmd;
|
||||
char jobstr[20];
|
||||
int ret;
|
||||
|
||||
if (!printername || !*printername)
|
||||
{
|
||||
DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
|
||||
lp_servicename(snum),snum));
|
||||
printername = lp_servicename(snum);
|
||||
}
|
||||
|
||||
if (!lpstatus_command || !(*lpstatus_command))
|
||||
{
|
||||
DEBUG(5,("No lpstatus command to %s job\n",
|
||||
(status==LPQ_PAUSED?"pause":"resume")));
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(jobstr,"%d",jobid);
|
||||
|
||||
strcpy(syscmd,lpstatus_command);
|
||||
string_sub(syscmd,"%p",printername);
|
||||
string_sub(syscmd,"%j",jobstr);
|
||||
standard_sub(cnum,syscmd);
|
||||
|
||||
ret = smbrun(syscmd,NULL);
|
||||
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
|
||||
lpq_reset(snum); /* queue has changed */
|
||||
}
|
||||
|
||||
|
74
source3/script/addtosmbpass
Normal file
74
source3/script/addtosmbpass
Normal file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/awk -f
|
||||
# edit the line above to point to your real location of awk interpreter
|
||||
|
||||
# awk program for adding new entries in smbpasswd files
|
||||
# arguments are account names to add; feed it an existent Samba password
|
||||
# file on stdin, results will be written on stdout
|
||||
#
|
||||
# Michal Jaegermann, michal@ellpspace.math.ualberta.ca, 1995-11-09
|
||||
|
||||
BEGIN {
|
||||
me = "addtosmbpass";
|
||||
count = ARGC;
|
||||
FS = ":";
|
||||
|
||||
if (count == 1) {
|
||||
print "Usage:", me,
|
||||
"name1 [name2 ....] < smbpasswd.in > smbpasswd.out";
|
||||
ARGV[1] = "/dev/null";
|
||||
ARGC = 2;
|
||||
exit;
|
||||
}
|
||||
|
||||
for(i = 1; i < count; i++) {
|
||||
names[ARGV[i]] = " ";
|
||||
delete ARGV[i];
|
||||
}
|
||||
# sane awk should work simply with 'ARGC = 1', but not every awk
|
||||
# implementation is sane - big sigh!!
|
||||
ARGV[1] = "-";
|
||||
ARGC = 2;
|
||||
#
|
||||
# If you have ypmatch but is not RPC registered (some Linux systems
|
||||
# for example) comment out the next line.
|
||||
# "which ypmatch" | getline ypmatch;
|
||||
if (1 != match(ypmatch, /^\//)) {
|
||||
ypmatch = "";
|
||||
}
|
||||
pwdf = "/etc/passwd";
|
||||
}
|
||||
#check for names already present in input
|
||||
{
|
||||
print $0;
|
||||
for(name in names) {
|
||||
if($1 ~ name) {
|
||||
delete names[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
END {
|
||||
fmt = "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:";
|
||||
fmt = fmt "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n";
|
||||
for(name in names) {
|
||||
while ((getline < pwdf) > 0) {
|
||||
if ($1 == name) {
|
||||
printf(fmt, $1, $3, $5, $6, $7);
|
||||
close(pwdf);
|
||||
notfound = "";
|
||||
break;
|
||||
}
|
||||
notfound = "n";
|
||||
}
|
||||
$0 = "";
|
||||
if (notfound && ypmatch) {
|
||||
# try to find in NIS databases
|
||||
command = ypmatch " " name " passwd";
|
||||
command | getline;
|
||||
if (NF > 0) {
|
||||
printf(fmt, $1, $3, $5, $6, $7);
|
||||
}
|
||||
close(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
source3/script/installbin.sh
Executable file
42
source3/script/installbin.sh
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
INSTALLPERMS=$1
|
||||
BASEDIR=$2
|
||||
BINDIR=$3
|
||||
LIBDIR=$4
|
||||
VARDIR=$5
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
|
||||
for d in $BASEDIR $BINDIR $LIBDIR $VARDIR; do
|
||||
if [ ! -d $d ]; then
|
||||
mkdir $d
|
||||
if [ ! -d $d ]; then
|
||||
echo Failed to make directory $d
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
for p in $*; do
|
||||
echo Installing $p as $BINDIR/$p
|
||||
if [ -f $BINDIR/$p ]; then
|
||||
mv $BINDIR/$p $BINDIR/$p.old
|
||||
fi
|
||||
cp $p $BINDIR/$p
|
||||
chmod $INSTALLPERMS $BINDIR/$p
|
||||
done
|
||||
|
||||
|
||||
cat << EOF
|
||||
======================================================================
|
||||
The binaries are installed. You may restore the old binaries (if there
|
||||
were any) using the command "make revert"
|
||||
======================================================================
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
|
35
source3/script/installman.sh
Executable file
35
source3/script/installman.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
MANDIR=$1
|
||||
SRCDIR=$2
|
||||
|
||||
echo Installing man pages in $MANDIR
|
||||
|
||||
for d in $MANDIR $MANDIR/man1 $MANDIR/man5 $MANDIR/man7 $MANDIR/man8; do
|
||||
if [ ! -d $d ]; then
|
||||
mkdir $d
|
||||
if [ ! -d $d ]; then
|
||||
echo Failed to make directory $d
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cp $SRCDIR../docs/*.1 $MANDIR/man1
|
||||
cp $SRCDIR../docs/*.5 $MANDIR/man5
|
||||
cp $SRCDIR../docs/*.8 $MANDIR/man8
|
||||
cp $SRCDIR../docs/*.7 $MANDIR/man7
|
||||
echo Setting permissions on man pages
|
||||
chmod 0644 $MANDIR/man1/smbstatus.1
|
||||
chmod 0644 $MANDIR/man1/smbclient.1
|
||||
chmod 0644 $MANDIR/man1/smbrun.1
|
||||
chmod 0644 $MANDIR/man1/testparm.1
|
||||
chmod 0644 $MANDIR/man1/testprns.1
|
||||
chmod 0644 $MANDIR/man1/smbtar.1
|
||||
chmod 0644 $MANDIR/man5/smb.conf.5
|
||||
chmod 0644 $MANDIR/man7/samba.7
|
||||
chmod 0644 $MANDIR/man8/smbd.8
|
||||
chmod 0644 $MANDIR/man8/nmbd.8
|
||||
|
||||
echo Man pages installed
|
||||
exit 0
|
||||
|
6
source3/script/mksmbpasswd.sh
Executable file
6
source3/script/mksmbpasswd.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
awk 'BEGIN {FS=":"
|
||||
printf("#\n# SMB password file.\n#\n")
|
||||
}
|
||||
{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
|
||||
'
|
15
source3/script/revert.sh
Executable file
15
source3/script/revert.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
BINDIR=$1
|
||||
shift
|
||||
|
||||
for p in $*; do
|
||||
if [ -f $BINDIR/$p.old ]; then
|
||||
echo Restoring $BINDIR/$p.old as $BINDIR/$p
|
||||
mv $BINDIR/$p $BINDIR/$p.new
|
||||
mv $BINDIR/$p.old $BINDIR/$p
|
||||
rm -f $BINDIR/$p.new
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
141
source3/script/smbtar
Normal file
141
source3/script/smbtar
Normal file
@ -0,0 +1,141 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# smbtar script - front end to smbclient
|
||||
#
|
||||
# Authors: Martin.Kraemer <Martin.Kraemer@mch.sni.de>
|
||||
# and Ricky Poulten (ricky@logcam.co.uk)
|
||||
#
|
||||
# (May need to change shell to ksh for HPUX or OSF for better getopts)
|
||||
|
||||
case $0 in
|
||||
# when called by absolute path, assume smbclient is in the same directory
|
||||
/*)
|
||||
SMBCLIENT="`dirname $0`/smbclient";;
|
||||
*) # edit this to show where your smbclient is
|
||||
SMBCLIENT="./smbclient";;
|
||||
esac
|
||||
|
||||
# These are the default values. You could fill them in if you know what
|
||||
# you're doing, but beware: better not store a plain text password!
|
||||
server=""
|
||||
service="backup" # Default: a service called "backup"
|
||||
password=""
|
||||
username=$LOGNAME # Default: same user name as in *nix
|
||||
verbose="2>/dev/null" # Default: no echo to stdout
|
||||
log="-d 2"
|
||||
newer=""
|
||||
blocksize=""
|
||||
tarcmd="c"
|
||||
tarargs=""
|
||||
cdcmd="\\"
|
||||
tapefile=${TAPE-tar.out}
|
||||
|
||||
Usage(){
|
||||
ex=$1
|
||||
shift
|
||||
echo >&2 "Usage: `basename $0` [<options>] [<include/exclude files>]
|
||||
Function: backup/restore a Windows PC directories to a local tape file
|
||||
Options: (Description) (Default)
|
||||
-r Restore from tape file to PC Save from PC to tapefile
|
||||
-i Incremental mode Full backup mode
|
||||
-v Verbose mode: echo command Don't echo anything
|
||||
-s <server> Specify PC Server $server
|
||||
-p <password> Specify PC Password $password
|
||||
-x <share> Specify PC Share $service
|
||||
-X Exclude mode Include
|
||||
-N <newer> File for date comparison `set -- $newer; echo $2`
|
||||
-b <blocksize> Specify tape's blocksize `set -- $blocksize; echo $2`
|
||||
-d <dir> Specify a directory in share $cdcmd
|
||||
-l <log> Specify a Samba Log Level `set -- $log; echo $2`
|
||||
-u <user> Specify User Name $username
|
||||
-t <tape> Specify Tape device $tapefile
|
||||
"
|
||||
echo >&2 "$@"
|
||||
exit $ex
|
||||
}
|
||||
|
||||
while getopts rivl:b:d:N:s:p:x:u:Xt: c; do
|
||||
case $c in
|
||||
r) # [r]estore to Windows (instead of the default "Save from Windows")
|
||||
tarcmd="x"
|
||||
;;
|
||||
i) # [i]ncremental
|
||||
tarargs=${tarargs}g
|
||||
;;
|
||||
l) # specify [l]og file
|
||||
log="-d $OPTARG"
|
||||
case "$OPTARG" in
|
||||
[0-9]*) ;;
|
||||
*) echo >&2 "$0: Error, log level not numeric: -l $OPTARG"
|
||||
exit 1
|
||||
esac
|
||||
;;
|
||||
d) # specify [d]irectory to change to in server's share
|
||||
cdcmd="$OPTARG"
|
||||
;;
|
||||
N) # compare with a file, test if [n]ewer
|
||||
if [ -f $OPTARG ]; then
|
||||
newer=$OPTARG
|
||||
tarargs=${tarargs}N
|
||||
else
|
||||
echo >&2 $0: Warning, $OPTARG not found
|
||||
fi
|
||||
;;
|
||||
X) # Add exclude flag
|
||||
tarargs=${tarargs}X
|
||||
;;
|
||||
s) # specify [s]erver's share to connect to - this MUST be given.
|
||||
server="$OPTARG"
|
||||
;;
|
||||
b) # specify [b]locksize
|
||||
blocksize="blocksize $OPTARG"
|
||||
case "$OPTARG" in
|
||||
[0-9]*) ;;
|
||||
*) echo >&2 "$0: Error, block size not numeric: -b $OPTARG"
|
||||
exit 1
|
||||
esac
|
||||
tarargs=${tarargs}b
|
||||
;;
|
||||
p) # specify [p]assword to use
|
||||
password="$OPTARG"
|
||||
;;
|
||||
x) # specify windows [s]hare to use
|
||||
service="$OPTARG"
|
||||
;;
|
||||
t) # specify [t]apefile on local host
|
||||
tapefile="$OPTARG"
|
||||
;;
|
||||
u) # specify [u]sername for connection
|
||||
username="$OPTARG"
|
||||
;;
|
||||
v) # be [v]erbose and display what's going on
|
||||
verbose=""
|
||||
;;
|
||||
'?') # any other switch
|
||||
Usage 2 "Invalid switch specified - abort."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift `expr $OPTIND - 1`
|
||||
|
||||
if [ "$server" = "" ] || [ "$service" = "" ]; then
|
||||
Usage 1 "No server or no service specified - abort."
|
||||
fi
|
||||
|
||||
# if the -v switch is set, the echo the current parameters
|
||||
if [ -z "$verbose" ]; then
|
||||
echo "server is $server"
|
||||
# echo "share is $service"
|
||||
echo "share is $service\\$cdcmd"
|
||||
echo "tar args is $tarargs"
|
||||
# echo "password is $password" # passwords should never be sent to screen
|
||||
echo "tape is $tapefile"
|
||||
echo "blocksize is $blocksize"
|
||||
fi
|
||||
|
||||
eval $SMBCLIENT "'\\\\$server\\$service'" "'$password'" -U "'$username'" \
|
||||
-E -N $log -D "'$cdcmd'" \
|
||||
-T${tarcmd}${tarargs} $blocksize $newer $tapefile $* $verbose
|
||||
|
||||
|
14
source3/script/updatesmbpasswd.sh
Executable file
14
source3/script/updatesmbpasswd.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
nawk 'BEGIN {FS=":"}
|
||||
{
|
||||
if( $0 ~ "^#" ) {
|
||||
print $0
|
||||
} else if( (length($4) == 32) && (($4 ~ "^[0-9A-F]*$") || ($4 ~ "^[X]*$") || ( $4 ~ "^[*]*$"))) {
|
||||
print $0
|
||||
} else {
|
||||
printf( "%s:%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", $1, $2, $3);
|
||||
for(i = 4; i <= NF; i++)
|
||||
printf("%s:", $i)
|
||||
printf("\n")
|
||||
}
|
||||
}'
|
376
source3/smbd/chgpasswd.c
Normal file
376
source3/smbd/chgpasswd.c
Normal file
@ -0,0 +1,376 @@
|
||||
/* fork a child process to exec passwd and write to its
|
||||
* tty to change a users password. This is running as the
|
||||
* user who is attempting to change the password.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code was copied/borrowed and stolen from various sources.
|
||||
* The primary source was the poppasswd.c from the authors of POPMail. This software
|
||||
* was included as a client to change passwords using the 'passwd' program
|
||||
* on the remote machine.
|
||||
*
|
||||
* This routine is called by set_user_password() in password.c only if ALLOW_PASSWORD_CHANGE
|
||||
* is defined in the compiler directives located in the Makefile.
|
||||
*
|
||||
* This code has been hacked by Bob Nance (nance@niehs.nih.gov) and Evan Patterson
|
||||
* (patters2@niehs.nih.gov) at the National Institute of Environmental Health Sciences
|
||||
* and rights to modify, distribute or incorporate this change to the CAP suite or
|
||||
* using it for any other reason are granted, so long as this disclaimer is left intact.
|
||||
*/
|
||||
|
||||
/*
|
||||
This code was hacked considerably for inclusion in Samba, primarily
|
||||
by Andrew.Tridgell@anu.edu.au. The biggest change was the addition
|
||||
of the "password chat" option, which allows the easy runtime
|
||||
specification of the expected sequence of events to change a
|
||||
password.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
#ifdef ALLOW_CHANGE_PASSWORD
|
||||
|
||||
#define MINPASSWDLENGTH 5
|
||||
#define BUFSIZE 512
|
||||
|
||||
static int findpty(char **slave)
|
||||
{
|
||||
int master;
|
||||
#ifdef SVR4
|
||||
extern char *ptsname();
|
||||
#else
|
||||
static char line[12] = "/dev/ptyXX";
|
||||
void *dirp;
|
||||
char *dpname;
|
||||
#endif
|
||||
|
||||
#ifdef SVR4
|
||||
if ((master = open("/dev/ptmx", O_RDWR)) >= 1) {
|
||||
grantpt(master);
|
||||
unlockpt(master);
|
||||
*slave = ptsname(master);
|
||||
return (master);
|
||||
}
|
||||
#else
|
||||
dirp = OpenDir("/dev");
|
||||
if (!dirp) return(-1);
|
||||
while ((dpname = ReadDirName(dirp)) != NULL) {
|
||||
if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
|
||||
line[8] = dpname[3];
|
||||
line[9] = dpname[4];
|
||||
if ((master = open(line, O_RDWR)) >= 0) {
|
||||
line[5] = 't';
|
||||
*slave = line;
|
||||
CloseDir(dirp);
|
||||
return (master);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseDir(dirp);
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int dochild(int master,char *slavedev, char *name, char *passwordprogram)
|
||||
{
|
||||
int slave;
|
||||
struct termios stermios;
|
||||
struct passwd *pass = Get_Pwnam(name,True);
|
||||
int gid = pass->pw_gid;
|
||||
int uid = pass->pw_uid;
|
||||
|
||||
#ifdef USE_SETRES
|
||||
setresuid(0,0,0);
|
||||
#else
|
||||
setuid(0);
|
||||
#endif
|
||||
|
||||
/* Start new session - gets rid of controlling terminal. */
|
||||
if (setsid() < 0) {
|
||||
DEBUG(3,("Weirdness, couldn't let go of controlling terminal\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* Open slave pty and acquire as new controlling terminal. */
|
||||
if ((slave = open(slavedev, O_RDWR)) < 0) {
|
||||
DEBUG(3,("More weirdness, could not open %s\n",
|
||||
slavedev));
|
||||
return(False);
|
||||
}
|
||||
#ifdef SVR4
|
||||
ioctl(slave, I_PUSH, "ptem");
|
||||
ioctl(slave, I_PUSH, "ldterm");
|
||||
#else
|
||||
if (ioctl(slave,TIOCSCTTY,0) <0) {
|
||||
DEBUG(3,("Error in ioctl call for slave pty\n"));
|
||||
/* return(False); */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Close master. */
|
||||
close(master);
|
||||
|
||||
/* Make slave stdin/out/err of child. */
|
||||
|
||||
if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) {
|
||||
DEBUG(3,("Could not re-direct stdin\n"));
|
||||
return(False);
|
||||
}
|
||||
if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) {
|
||||
DEBUG(3,("Could not re-direct stdout\n"));
|
||||
return(False);
|
||||
}
|
||||
if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) {
|
||||
DEBUG(3,("Could not re-direct stderr\n"));
|
||||
return(False);
|
||||
}
|
||||
if (slave > 2) close(slave);
|
||||
|
||||
/* Set proper terminal attributes - no echo, canonical input processing,
|
||||
no map NL to CR/NL on output. */
|
||||
|
||||
if (tcgetattr(0, &stermios) < 0) {
|
||||
DEBUG(3,("could not read default terminal attributes on pty\n"));
|
||||
return(False);
|
||||
}
|
||||
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
stermios.c_lflag |= ICANON;
|
||||
stermios.c_oflag &= ~(ONLCR);
|
||||
if (tcsetattr(0, TCSANOW, &stermios) < 0) {
|
||||
DEBUG(3,("could not set attributes of pty\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* make us completely into the right uid */
|
||||
#ifdef USE_SETRES
|
||||
setresgid(0,0,0);
|
||||
setresuid(0,0,0);
|
||||
setresgid(gid,gid,gid);
|
||||
setresuid(uid,uid,uid);
|
||||
#else
|
||||
setuid(0);
|
||||
seteuid(0);
|
||||
setgid(gid);
|
||||
setegid(gid);
|
||||
setuid(uid);
|
||||
seteuid(uid);
|
||||
#endif
|
||||
|
||||
/* execl() password-change application */
|
||||
if (execl("/bin/sh","sh","-c",passwordprogram,NULL) < 0) {
|
||||
DEBUG(3,("Bad status returned from %s\n",passwordprogram));
|
||||
return(False);
|
||||
}
|
||||
return(True);
|
||||
}
|
||||
|
||||
static int expect(int master,char *expected,char *buf)
|
||||
{
|
||||
int n, m;
|
||||
|
||||
n = 0;
|
||||
buf[0] = 0;
|
||||
while (1) {
|
||||
if (n >= BUFSIZE-1) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* allow 4 seconds for some output to appear */
|
||||
m = read_with_timeout(master, buf+n, 1, BUFSIZE-1-n, 4000, True);
|
||||
if (m < 0)
|
||||
return False;
|
||||
|
||||
n += m;
|
||||
buf[n] = 0;
|
||||
|
||||
{
|
||||
pstring s1,s2;
|
||||
strcpy(s1,buf);
|
||||
strcpy(s2,expected);
|
||||
if (do_match(s1, s2, False))
|
||||
return(True);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pwd_sub(char *buf)
|
||||
{
|
||||
string_sub(buf,"\\n","\n");
|
||||
string_sub(buf,"\\r","\r");
|
||||
string_sub(buf,"\\s"," ");
|
||||
string_sub(buf,"\\t","\t");
|
||||
}
|
||||
|
||||
static void writestring(int fd,char *s)
|
||||
{
|
||||
int l;
|
||||
|
||||
l = strlen (s);
|
||||
write (fd, s, l);
|
||||
}
|
||||
|
||||
|
||||
static int talktochild(int master, char *chatsequence)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
int count=0;
|
||||
char *ptr=chatsequence;
|
||||
fstring chatbuf;
|
||||
|
||||
*buf = 0;
|
||||
sleep(1);
|
||||
|
||||
while (next_token(&ptr,chatbuf,NULL)) {
|
||||
BOOL ok=True;
|
||||
count++;
|
||||
pwd_sub(chatbuf);
|
||||
if (!strequal(chatbuf,"."))
|
||||
ok = expect(master,chatbuf,buf);
|
||||
|
||||
#if DEBUG_PASSWORD
|
||||
DEBUG(100,("chatbuf=[%s] responsebuf=[%s]\n",chatbuf,buf));
|
||||
#endif
|
||||
|
||||
if (!ok) {
|
||||
DEBUG(3,("response %d incorrect\n",count));
|
||||
return(False);
|
||||
}
|
||||
|
||||
if (!next_token(&ptr,chatbuf,NULL)) break;
|
||||
pwd_sub(chatbuf);
|
||||
if (!strequal(chatbuf,"."))
|
||||
writestring(master,chatbuf);
|
||||
|
||||
#if DEBUG_PASSWORD
|
||||
DEBUG(100,("sendbuf=[%s]\n",chatbuf));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (count<1) return(False);
|
||||
|
||||
return (True);
|
||||
}
|
||||
|
||||
|
||||
BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence)
|
||||
{
|
||||
char *slavedev;
|
||||
int master;
|
||||
pid_t pid, wpid;
|
||||
int wstat;
|
||||
BOOL chstat;
|
||||
|
||||
/* allocate a pseudo-terminal device */
|
||||
if ((master = findpty (&slavedev)) < 0) {
|
||||
DEBUG(3,("Cannot Allocate pty for password change: %s",name));
|
||||
return(False);
|
||||
}
|
||||
|
||||
if ((pid = fork()) < 0) {
|
||||
DEBUG(3,("Cannot fork() child for password change: %s",name));
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* we now have a pty */
|
||||
if (pid > 0){ /* This is the parent process */
|
||||
if ((chstat = talktochild(master, chatsequence)) == False) {
|
||||
DEBUG(3,("Child failed to change password: %s\n",name));
|
||||
kill(pid, SIGKILL); /* be sure to end this process */
|
||||
return(False);
|
||||
}
|
||||
if ((wpid = waitpid(pid, &wstat, 0)) < 0) {
|
||||
DEBUG(3,("The process is no longer waiting!\n\n"));
|
||||
return(False);
|
||||
}
|
||||
if (pid != wpid) {
|
||||
DEBUG(3,("We were waiting for the wrong process ID\n"));
|
||||
return(False);
|
||||
}
|
||||
if (WIFEXITED(wstat) == 0) {
|
||||
DEBUG(3,("The process exited while we were waiting\n"));
|
||||
return(False);
|
||||
}
|
||||
if (WEXITSTATUS(wstat) != 0) {
|
||||
DEBUG(3,("The status of the process exiting was %d\n", wstat));
|
||||
return(False);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* CHILD */
|
||||
|
||||
/* make sure it doesn't freeze */
|
||||
alarm(20);
|
||||
|
||||
DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,getuid(),getgid()));
|
||||
chstat = dochild(master, slavedev, name, passwordprogram);
|
||||
}
|
||||
DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
|
||||
return (chstat);
|
||||
}
|
||||
|
||||
|
||||
BOOL chgpasswd(char *name,char *oldpass,char *newpass)
|
||||
{
|
||||
pstring passwordprogram;
|
||||
pstring chatsequence;
|
||||
|
||||
strlower(name);
|
||||
DEBUG(3,("Password change for user: %s\n",name));
|
||||
|
||||
#if DEBUG_PASSWORD
|
||||
DEBUG(100,("Passwords: old=%s new=%s\n",oldpass,newpass));
|
||||
#endif
|
||||
|
||||
/* Take the passed information and test it for minimum criteria */
|
||||
/* Minimum password length */
|
||||
if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */
|
||||
{
|
||||
DEBUG(2,("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",name));
|
||||
return (False); /* inform the user */
|
||||
}
|
||||
|
||||
/* Password is same as old password */
|
||||
if (strcmp(oldpass,newpass) == 0) /* don't allow same password */
|
||||
{
|
||||
DEBUG(2,("Password Change: %s, New password is same as old\n",name)); /* log the attempt */
|
||||
return (False); /* inform the user */
|
||||
}
|
||||
|
||||
#if (defined(PASSWD_PROGRAM) && defined(PASSWD_CHAT))
|
||||
strcpy(passwordprogram,PASSWD_PROGRAM);
|
||||
strcpy(chatsequence,PASSWD_CHAT);
|
||||
#else
|
||||
strcpy(passwordprogram,lp_passwd_program());
|
||||
strcpy(chatsequence,lp_passwd_chat());
|
||||
#endif
|
||||
|
||||
if (!*chatsequence) {
|
||||
DEBUG(2,("Null chat sequence - no password changing\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
if (!*passwordprogram) {
|
||||
DEBUG(2,("Null password program - no password changing\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
string_sub(passwordprogram,"%u",name);
|
||||
string_sub(passwordprogram,"%o",oldpass);
|
||||
string_sub(passwordprogram,"%n",newpass);
|
||||
|
||||
string_sub(chatsequence,"%u",name);
|
||||
string_sub(chatsequence,"%o",oldpass);
|
||||
string_sub(chatsequence,"%n",newpass);
|
||||
return(chat_with_program(passwordprogram,name,chatsequence));
|
||||
}
|
||||
|
||||
#else
|
||||
BOOL chgpasswd(char *name,char *oldpass,char *newpass)
|
||||
{
|
||||
DEBUG(0,("Password changing not compiled in (user=%s)\n",name));
|
||||
return(False);
|
||||
}
|
||||
#endif
|
955
source3/smbd/dir.c
Normal file
955
source3/smbd/dir.c
Normal file
@ -0,0 +1,955 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Directory handling routines
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
extern connection_struct Connections[];
|
||||
|
||||
/*
|
||||
This module implements directory related functions for Samba.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
uint32 dircounter = 0;
|
||||
|
||||
|
||||
#define NUMDIRPTRS 256
|
||||
|
||||
|
||||
static struct dptr_struct
|
||||
{
|
||||
int pid;
|
||||
int cnum;
|
||||
uint32 lastused;
|
||||
void *ptr;
|
||||
BOOL valid;
|
||||
BOOL finished;
|
||||
BOOL expect_close;
|
||||
char *wcard; /* Field only used for lanman2 trans2_findfirst/next searches */
|
||||
uint16 attr; /* Field only used for lanman2 trans2_findfirst/next searches */
|
||||
char *path;
|
||||
}
|
||||
dirptrs[NUMDIRPTRS];
|
||||
|
||||
|
||||
static int dptrs_open = 0;
|
||||
|
||||
/****************************************************************************
|
||||
initialise the dir array
|
||||
****************************************************************************/
|
||||
void init_dptrs(void)
|
||||
{
|
||||
static BOOL dptrs_init=False;
|
||||
int i;
|
||||
|
||||
if (dptrs_init) return;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
{
|
||||
dirptrs[i].valid = False;
|
||||
dirptrs[i].wcard = NULL;
|
||||
dirptrs[i].ptr = NULL;
|
||||
string_init(&dirptrs[i].path,"");
|
||||
}
|
||||
dptrs_init = True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
idle a dptr - the directory is closed but the control info is kept
|
||||
****************************************************************************/
|
||||
static void dptr_idle(int key)
|
||||
{
|
||||
if (dirptrs[key].valid && dirptrs[key].ptr) {
|
||||
DEBUG(4,("Idling dptr key %d\n",key));
|
||||
dptrs_open--;
|
||||
CloseDir(dirptrs[key].ptr);
|
||||
dirptrs[key].ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
idle the oldest dptr
|
||||
****************************************************************************/
|
||||
static void dptr_idleoldest(void)
|
||||
{
|
||||
int i;
|
||||
uint32 old=dircounter+1;
|
||||
int oldi= -1;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (dirptrs[i].valid && dirptrs[i].ptr && dirptrs[i].lastused < old) {
|
||||
old = dirptrs[i].lastused;
|
||||
oldi = i;
|
||||
}
|
||||
if (oldi != -1)
|
||||
dptr_idle(oldi);
|
||||
else
|
||||
DEBUG(0,("No dptrs available to idle??\n"));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get the dir ptr for a dir index
|
||||
****************************************************************************/
|
||||
static void *dptr_get(int key,uint32 lastused)
|
||||
{
|
||||
if (dirptrs[key].valid) {
|
||||
if (lastused) dirptrs[key].lastused = lastused;
|
||||
if (!dirptrs[key].ptr) {
|
||||
if (dptrs_open >= MAXDIR)
|
||||
dptr_idleoldest();
|
||||
DEBUG(4,("Reopening dptr key %d\n",key));
|
||||
if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path)))
|
||||
dptrs_open++;
|
||||
}
|
||||
return(dirptrs[key].ptr);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get the dir path for a dir index
|
||||
****************************************************************************/
|
||||
char *dptr_path(int key)
|
||||
{
|
||||
if (dirptrs[key].valid)
|
||||
return(dirptrs[key].path);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get the dir wcard for a dir index (lanman2 specific)
|
||||
****************************************************************************/
|
||||
char *dptr_wcard(int key)
|
||||
{
|
||||
if (dirptrs[key].valid)
|
||||
return(dirptrs[key].wcard);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
set the dir wcard for a dir index (lanman2 specific)
|
||||
Returns 0 on ok, 1 on fail.
|
||||
****************************************************************************/
|
||||
BOOL dptr_set_wcard(int key, char *wcard)
|
||||
{
|
||||
if (dirptrs[key].valid) {
|
||||
dirptrs[key].wcard = wcard;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
set the dir attrib for a dir index (lanman2 specific)
|
||||
Returns 0 on ok, 1 on fail.
|
||||
****************************************************************************/
|
||||
BOOL dptr_set_attr(int key, uint16 attr)
|
||||
{
|
||||
if (dirptrs[key].valid) {
|
||||
dirptrs[key].attr = attr;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get the dir attrib for a dir index (lanman2 specific)
|
||||
****************************************************************************/
|
||||
uint16 dptr_attr(int key)
|
||||
{
|
||||
if (dirptrs[key].valid)
|
||||
return(dirptrs[key].attr);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
close a dptr
|
||||
****************************************************************************/
|
||||
void dptr_close(int key)
|
||||
{
|
||||
if (dirptrs[key].valid) {
|
||||
DEBUG(4,("closing dptr key %d\n",key));
|
||||
if (dirptrs[key].ptr) {
|
||||
CloseDir(dirptrs[key].ptr);
|
||||
dptrs_open--;
|
||||
}
|
||||
/* Lanman 2 specific code */
|
||||
if (dirptrs[key].wcard)
|
||||
free(dirptrs[key].wcard);
|
||||
dirptrs[key].valid = False;
|
||||
string_set(&dirptrs[key].path,"");
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
close all dptrs for a cnum
|
||||
****************************************************************************/
|
||||
void dptr_closecnum(int cnum)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (dirptrs[i].valid && dirptrs[i].cnum == cnum)
|
||||
dptr_close(i);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
idle all dptrs for a cnum
|
||||
****************************************************************************/
|
||||
void dptr_idlecnum(int cnum)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (dirptrs[i].valid && dirptrs[i].cnum == cnum && dirptrs[i].ptr)
|
||||
dptr_idle(i);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
close a dptr that matches a given path, only if it matches the pid also
|
||||
****************************************************************************/
|
||||
void dptr_closepath(char *path,int pid)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (dirptrs[i].valid && pid == dirptrs[i].pid &&
|
||||
strequal(dirptrs[i].path,path))
|
||||
dptr_close(i);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
start a directory listing
|
||||
****************************************************************************/
|
||||
static BOOL start_dir(int cnum,char *directory)
|
||||
{
|
||||
DEBUG(5,("start_dir cnum=%d dir=%s\n",cnum,directory));
|
||||
|
||||
if (!check_name(directory,cnum))
|
||||
return(False);
|
||||
|
||||
if (! *directory)
|
||||
directory = ".";
|
||||
|
||||
Connections[cnum].dirptr = OpenDir(directory);
|
||||
if (Connections[cnum].dirptr) {
|
||||
dptrs_open++;
|
||||
string_set(&Connections[cnum].dirpath,directory);
|
||||
return(True);
|
||||
}
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
create a new dir ptr
|
||||
****************************************************************************/
|
||||
int dptr_create(int cnum,char *path, BOOL expect_close,int pid)
|
||||
{
|
||||
int i;
|
||||
uint32 old;
|
||||
int oldi;
|
||||
|
||||
if (!start_dir(cnum,path))
|
||||
return(-1);
|
||||
|
||||
if (dptrs_open >= MAXDIR)
|
||||
dptr_idleoldest();
|
||||
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (!dirptrs[i].valid)
|
||||
break;
|
||||
if (i == NUMDIRPTRS) i = -1;
|
||||
|
||||
|
||||
/* as a 2nd option, grab the oldest not marked for expect_close */
|
||||
if (i == -1) {
|
||||
old=dircounter+1;
|
||||
oldi= -1;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (!dirptrs[i].expect_close && dirptrs[i].lastused < old) {
|
||||
old = dirptrs[i].lastused;
|
||||
oldi = i;
|
||||
}
|
||||
i = oldi;
|
||||
}
|
||||
|
||||
/* a 3rd option - grab the oldest one */
|
||||
if (i == -1) {
|
||||
old=dircounter+1;
|
||||
oldi= -1;
|
||||
for (i=0;i<NUMDIRPTRS;i++)
|
||||
if (dirptrs[i].lastused < old) {
|
||||
old = dirptrs[i].lastused;
|
||||
oldi = i;
|
||||
}
|
||||
i = oldi;
|
||||
}
|
||||
|
||||
if (i == -1) {
|
||||
DEBUG(0,("Error - all dirptrs in use??\n"));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (dirptrs[i].valid)
|
||||
dptr_close(i);
|
||||
|
||||
dirptrs[i].ptr = Connections[cnum].dirptr;
|
||||
string_set(&dirptrs[i].path,path);
|
||||
dirptrs[i].lastused = dircounter++;
|
||||
dirptrs[i].finished = False;
|
||||
dirptrs[i].cnum = cnum;
|
||||
dirptrs[i].pid = pid;
|
||||
dirptrs[i].expect_close = expect_close;
|
||||
dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */
|
||||
dirptrs[i].attr = 0; /* Only used in lanman2 searches */
|
||||
dirptrs[i].valid = True;
|
||||
|
||||
DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
|
||||
i,path,expect_close));
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
#define DPTR_MASK ((uint32)(((uint32)1)<<31))
|
||||
|
||||
/****************************************************************************
|
||||
fill the 5 byte server reserved dptr field
|
||||
****************************************************************************/
|
||||
BOOL dptr_fill(char *buf1,unsigned int key)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)buf1;
|
||||
void *p = dptr_get(key,0);
|
||||
uint32 offset;
|
||||
if (!p) {
|
||||
DEBUG(1,("filling null dirptr %d\n",key));
|
||||
return(False);
|
||||
}
|
||||
offset = TellDir(p);
|
||||
DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,p,offset));
|
||||
buf[0] = key;
|
||||
SIVAL(buf,1,offset | DPTR_MASK);
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
return True is the offset is at zero
|
||||
****************************************************************************/
|
||||
BOOL dptr_zero(char *buf)
|
||||
{
|
||||
return((IVAL(buf,1)&~DPTR_MASK) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
fetch the dir ptr and seek it given the 5 byte server field
|
||||
****************************************************************************/
|
||||
void *dptr_fetch(char *buf,int *num)
|
||||
{
|
||||
unsigned int key = *(unsigned char *)buf;
|
||||
void *p = dptr_get(key,dircounter++);
|
||||
uint32 offset;
|
||||
if (!p) {
|
||||
DEBUG(3,("fetched null dirptr %d\n",key));
|
||||
return(NULL);
|
||||
}
|
||||
*num = key;
|
||||
offset = IVAL(buf,1)&~DPTR_MASK;
|
||||
SeekDir(p,offset);
|
||||
DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
|
||||
key,dptr_path(key),offset));
|
||||
return(p);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
fetch the dir ptr and seek it given the lanman2 parameter block
|
||||
****************************************************************************/
|
||||
void *dptr_fetch_lanman2(char *params,int dptr_num)
|
||||
{
|
||||
void *p = dptr_get(dptr_num,dircounter++);
|
||||
uint32 resume_key = SVAL(params,6);
|
||||
BOOL uses_resume_key = BITSETW(params+10,2);
|
||||
BOOL continue_bit = BITSETW(params+10,3);
|
||||
|
||||
if (!p) {
|
||||
DEBUG(3,("fetched null dirptr %d\n",dptr_num));
|
||||
return(NULL);
|
||||
}
|
||||
if(uses_resume_key && !continue_bit)
|
||||
SeekDir(p,resume_key);
|
||||
DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
|
||||
return(p);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get a directory entry
|
||||
****************************************************************************/
|
||||
BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend)
|
||||
{
|
||||
char *dname;
|
||||
BOOL found = False;
|
||||
struct stat sbuf;
|
||||
pstring path;
|
||||
pstring pathreal;
|
||||
BOOL isrootdir;
|
||||
pstring filename;
|
||||
BOOL matched;
|
||||
|
||||
*path = *pathreal = *filename = 0;
|
||||
|
||||
isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
|
||||
strequal(Connections[cnum].dirpath,".") ||
|
||||
strequal(Connections[cnum].dirpath,"/"));
|
||||
|
||||
if (!Connections[cnum].dirptr)
|
||||
return(False);
|
||||
|
||||
while (!found)
|
||||
{
|
||||
dname = ReadDirName(Connections[cnum].dirptr);
|
||||
|
||||
DEBUG(6,("readdir on dirptr 0x%x now at offset %d\n",
|
||||
Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
|
||||
|
||||
if (dname == NULL)
|
||||
return(False);
|
||||
|
||||
matched = False;
|
||||
|
||||
strcpy(filename,dname);
|
||||
|
||||
if ((strcmp(filename,mask) == 0) ||
|
||||
(name_map_mangle(filename,True,SNUM(cnum)) &&
|
||||
mask_match(filename,mask,False,False)))
|
||||
{
|
||||
if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
|
||||
continue;
|
||||
|
||||
strcpy(fname,filename);
|
||||
*path = 0;
|
||||
strcpy(path,Connections[cnum].dirpath);
|
||||
strcat(path,"/");
|
||||
strcpy(pathreal,path);
|
||||
strcat(path,fname);
|
||||
strcat(pathreal,dname);
|
||||
if (sys_stat(pathreal,&sbuf) != 0)
|
||||
{
|
||||
DEBUG(5,("Couldn't stat 1 [%s]\n",path));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (check_descend &&
|
||||
!strequal(fname,".") && !strequal(fname,".."))
|
||||
continue;
|
||||
|
||||
*mode = dos_mode(cnum,pathreal,&sbuf);
|
||||
|
||||
if (((*mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
|
||||
{
|
||||
DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
|
||||
continue;
|
||||
}
|
||||
*size = sbuf.st_size;
|
||||
*date = sbuf.st_mtime;
|
||||
|
||||
DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
|
||||
|
||||
found = True;
|
||||
}
|
||||
}
|
||||
|
||||
return(found);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pos;
|
||||
int numentries;
|
||||
int mallocsize;
|
||||
char *data;
|
||||
char *current;
|
||||
} Dir;
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
open a directory
|
||||
********************************************************************/
|
||||
void *OpenDir(char *name)
|
||||
{
|
||||
Dir *dirp;
|
||||
char *n;
|
||||
void *p = sys_opendir(name);
|
||||
int used=0;
|
||||
|
||||
if (!p) return(NULL);
|
||||
dirp = (Dir *)malloc(sizeof(Dir));
|
||||
if (!dirp) {
|
||||
closedir(p);
|
||||
return(NULL);
|
||||
}
|
||||
dirp->pos = dirp->numentries = dirp->mallocsize = 0;
|
||||
dirp->data = dirp->current = NULL;
|
||||
|
||||
while ((n = readdirname(p))) {
|
||||
int l = strlen(n)+1;
|
||||
if (used + l > dirp->mallocsize) {
|
||||
int s = MAX(used+l,used+2000);
|
||||
char *r;
|
||||
r = (char *)Realloc(dirp->data,s);
|
||||
if (!r) {
|
||||
DEBUG(0,("Out of memory in OpenDir\n"));
|
||||
break;
|
||||
}
|
||||
dirp->data = r;
|
||||
dirp->mallocsize = s;
|
||||
dirp->current = dirp->data;
|
||||
}
|
||||
strcpy(dirp->data+used,n);
|
||||
used += l;
|
||||
dirp->numentries++;
|
||||
}
|
||||
|
||||
closedir(p);
|
||||
return((void *)dirp);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
close a directory
|
||||
********************************************************************/
|
||||
void CloseDir(void *p)
|
||||
{
|
||||
Dir *dirp = (Dir *)p;
|
||||
if (!dirp) return;
|
||||
if (dirp->data) free(dirp->data);
|
||||
free(dirp);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
read from a directory
|
||||
********************************************************************/
|
||||
char *ReadDirName(void *p)
|
||||
{
|
||||
char *ret;
|
||||
Dir *dirp = (Dir *)p;
|
||||
|
||||
if (!dirp || !dirp->current || dirp->pos >= dirp->numentries) return(NULL);
|
||||
|
||||
ret = dirp->current;
|
||||
dirp->current = skip_string(dirp->current,1);
|
||||
dirp->pos++;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
seek a dir
|
||||
********************************************************************/
|
||||
BOOL SeekDir(void *p,int pos)
|
||||
{
|
||||
Dir *dirp = (Dir *)p;
|
||||
|
||||
if (!dirp) return(False);
|
||||
|
||||
if (pos < dirp->pos) {
|
||||
dirp->current = dirp->data;
|
||||
dirp->pos = 0;
|
||||
}
|
||||
|
||||
while (dirp->pos < pos && ReadDirName(p)) ;
|
||||
|
||||
return(dirp->pos == pos);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
tell a dir position
|
||||
********************************************************************/
|
||||
int TellDir(void *p)
|
||||
{
|
||||
Dir *dirp = (Dir *)p;
|
||||
|
||||
if (!dirp) return(-1);
|
||||
|
||||
return(dirp->pos);
|
||||
}
|
||||
|
||||
|
||||
static int dir_cache_size = 0;
|
||||
static struct dir_cache {
|
||||
struct dir_cache *next;
|
||||
struct dir_cache *prev;
|
||||
char *path;
|
||||
char *name;
|
||||
char *dname;
|
||||
int snum;
|
||||
} *dir_cache = NULL;
|
||||
|
||||
/*******************************************************************
|
||||
add an entry to the directory cache
|
||||
********************************************************************/
|
||||
void DirCacheAdd(char *path,char *name,char *dname,int snum)
|
||||
{
|
||||
struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry));
|
||||
if (!entry) return;
|
||||
entry->path = strdup(path);
|
||||
entry->name = strdup(name);
|
||||
entry->dname = strdup(dname);
|
||||
entry->snum = snum;
|
||||
if (!entry->path || !entry->name || !entry->dname) return;
|
||||
|
||||
entry->next = dir_cache;
|
||||
entry->prev = NULL;
|
||||
if (entry->next) entry->next->prev = entry;
|
||||
dir_cache = entry;
|
||||
|
||||
DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname));
|
||||
|
||||
if (dir_cache_size == DIRCACHESIZE) {
|
||||
for (entry=dir_cache; entry->next; entry=entry->next) ;
|
||||
free(entry->path);
|
||||
free(entry->name);
|
||||
free(entry->dname);
|
||||
if (entry->prev) entry->prev->next = entry->next;
|
||||
free(entry);
|
||||
} else {
|
||||
dir_cache_size++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
check for an entry in the directory cache
|
||||
********************************************************************/
|
||||
char *DirCacheCheck(char *path,char *name,int snum)
|
||||
{
|
||||
struct dir_cache *entry;
|
||||
|
||||
for (entry=dir_cache; entry; entry=entry->next) {
|
||||
if (entry->snum == snum &&
|
||||
strcmp(path,entry->path) == 0 &&
|
||||
strcmp(name,entry->name) == 0) {
|
||||
DEBUG(4,("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
|
||||
return(entry->dname);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
flush entries in the dir_cache
|
||||
********************************************************************/
|
||||
void DirCacheFlush(int snum)
|
||||
{
|
||||
struct dir_cache *entry,*next;
|
||||
|
||||
for (entry=dir_cache; entry; entry=next) {
|
||||
if (entry->snum == snum) {
|
||||
free(entry->path);
|
||||
free(entry->dname);
|
||||
free(entry->name);
|
||||
next = entry->next;
|
||||
if (entry->prev) entry->prev->next = entry->next;
|
||||
if (entry->next) entry->next->prev = entry->prev;
|
||||
if (dir_cache == entry) dir_cache = entry->next;
|
||||
free(entry);
|
||||
} else {
|
||||
next = entry->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef REPLACE_GETWD
|
||||
/* This is getcwd.c from bash. It is needed in Interactive UNIX. To
|
||||
* add support for another OS you need to determine which of the
|
||||
* conditional compilation macros you need to define. All the options
|
||||
* are defined for Interactive UNIX.
|
||||
*/
|
||||
#ifdef ISC
|
||||
#define HAVE_UNISTD_H
|
||||
#define USGr3
|
||||
#define USG
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (__STDC__)
|
||||
# define CONST const
|
||||
# define PTR void *
|
||||
#else /* !__STDC__ */
|
||||
# define CONST
|
||||
# define PTR char *
|
||||
#endif /* !__STDC__ */
|
||||
|
||||
#if !defined (PATH_MAX)
|
||||
# if defined (MAXPATHLEN)
|
||||
# define PATH_MAX MAXPATHLEN
|
||||
# else /* !MAXPATHLEN */
|
||||
# define PATH_MAX 1024
|
||||
# endif /* !MAXPATHLEN */
|
||||
#endif /* !PATH_MAX */
|
||||
|
||||
#if defined (_POSIX_VERSION) || defined (USGr3) || defined (HAVE_DIRENT_H)
|
||||
# if !defined (HAVE_DIRENT)
|
||||
# define HAVE_DIRENT
|
||||
# endif /* !HAVE_DIRENT */
|
||||
#endif /* _POSIX_VERSION || USGr3 || HAVE_DIRENT_H */
|
||||
|
||||
#if defined (HAVE_DIRENT)
|
||||
# define D_NAMLEN(d) (strlen ((d)->d_name))
|
||||
#else
|
||||
# define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* ! (_POSIX_VERSION || USGr3) */
|
||||
|
||||
#if defined (USG) || defined (USGr3)
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
#if !defined (alloca)
|
||||
extern char *alloca ();
|
||||
#endif /* alloca */
|
||||
|
||||
/* Get the pathname of the current working directory,
|
||||
and put it in SIZE bytes of BUF. Returns NULL if the
|
||||
directory couldn't be determined or SIZE was too small.
|
||||
If successful, returns BUF. In GNU, if BUF is NULL,
|
||||
an array is allocated with `malloc'; the array is SIZE
|
||||
bytes long, unless SIZE <= 0, in which case it is as
|
||||
big as necessary. */
|
||||
#if defined (__STDC__)
|
||||
char *
|
||||
getcwd (char *buf, size_t size)
|
||||
#else /* !__STDC__ */
|
||||
char *
|
||||
getcwd (buf, size)
|
||||
char *buf;
|
||||
int size;
|
||||
#endif /* !__STDC__ */
|
||||
{
|
||||
static CONST char dots[]
|
||||
= "../../../../../../../../../../../../../../../../../../../../../../../\
|
||||
../../../../../../../../../../../../../../../../../../../../../../../../../../\
|
||||
../../../../../../../../../../../../../../../../../../../../../../../../../..";
|
||||
CONST char *dotp, *dotlist;
|
||||
size_t dotsize;
|
||||
dev_t rootdev, thisdev;
|
||||
ino_t rootino, thisino;
|
||||
char path[PATH_MAX + 1];
|
||||
register char *pathp;
|
||||
char *pathbuf;
|
||||
size_t pathsize;
|
||||
struct stat st;
|
||||
|
||||
if (buf != NULL && size == 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
pathsize = sizeof (path);
|
||||
pathp = &path[pathsize];
|
||||
*--pathp = '\0';
|
||||
pathbuf = path;
|
||||
|
||||
if (stat (".", &st) < 0)
|
||||
return ((char *)NULL);
|
||||
thisdev = st.st_dev;
|
||||
thisino = st.st_ino;
|
||||
|
||||
if (stat ("/", &st) < 0)
|
||||
return ((char *)NULL);
|
||||
rootdev = st.st_dev;
|
||||
rootino = st.st_ino;
|
||||
|
||||
dotsize = sizeof (dots) - 1;
|
||||
dotp = &dots[sizeof (dots)];
|
||||
dotlist = dots;
|
||||
while (!(thisdev == rootdev && thisino == rootino))
|
||||
{
|
||||
register DIR *dirstream;
|
||||
register struct dirent *d;
|
||||
dev_t dotdev;
|
||||
ino_t dotino;
|
||||
char mount_point;
|
||||
int namlen;
|
||||
|
||||
/* Look at the parent directory. */
|
||||
if (dotp == dotlist)
|
||||
{
|
||||
/* My, what a deep directory tree you have, Grandma. */
|
||||
char *new;
|
||||
if (dotlist == dots)
|
||||
{
|
||||
new = malloc (dotsize * 2 + 1);
|
||||
if (new == NULL)
|
||||
goto lose;
|
||||
memcpy (new, dots, dotsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
new = realloc ((PTR) dotlist, dotsize * 2 + 1);
|
||||
if (new == NULL)
|
||||
goto lose;
|
||||
}
|
||||
memcpy (&new[dotsize], new, dotsize);
|
||||
dotp = &new[dotsize];
|
||||
dotsize *= 2;
|
||||
new[dotsize] = '\0';
|
||||
dotlist = new;
|
||||
}
|
||||
|
||||
dotp -= 3;
|
||||
|
||||
/* Figure out if this directory is a mount point. */
|
||||
if (stat (dotp, &st) < 0)
|
||||
goto lose;
|
||||
dotdev = st.st_dev;
|
||||
dotino = st.st_ino;
|
||||
mount_point = dotdev != thisdev;
|
||||
|
||||
/* Search for the last directory. */
|
||||
dirstream = opendir(dotp);
|
||||
if (dirstream == NULL)
|
||||
goto lose;
|
||||
while ((d = (struct dirent *)readdir(dirstream)) != NULL)
|
||||
{
|
||||
if (d->d_name[0] == '.' &&
|
||||
(d->d_name[1] == '\0' ||
|
||||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
|
||||
continue;
|
||||
if (mount_point || d->d_fileno == thisino)
|
||||
{
|
||||
char *name;
|
||||
|
||||
namlen = D_NAMLEN(d);
|
||||
name = (char *)
|
||||
alloca (dotlist + dotsize - dotp + 1 + namlen + 1);
|
||||
memcpy (name, dotp, dotlist + dotsize - dotp);
|
||||
name[dotlist + dotsize - dotp] = '/';
|
||||
memcpy (&name[dotlist + dotsize - dotp + 1],
|
||||
d->d_name, namlen + 1);
|
||||
if (lstat (name, &st) < 0)
|
||||
{
|
||||
int save = errno;
|
||||
closedir(dirstream);
|
||||
errno = save;
|
||||
goto lose;
|
||||
}
|
||||
if (st.st_dev == thisdev && st.st_ino == thisino)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == NULL)
|
||||
{
|
||||
int save = errno;
|
||||
closedir(dirstream);
|
||||
errno = save;
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t space;
|
||||
|
||||
while ((space = pathp - pathbuf) <= namlen)
|
||||
{
|
||||
char *new;
|
||||
|
||||
if (pathbuf == path)
|
||||
{
|
||||
new = malloc (pathsize * 2);
|
||||
if (!new)
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
new = realloc ((PTR) pathbuf, (pathsize * 2));
|
||||
if (!new)
|
||||
goto lose;
|
||||
pathp = new + space;
|
||||
}
|
||||
(void) memcpy (new + pathsize + space, pathp, pathsize - space);
|
||||
pathp = new + pathsize + space;
|
||||
pathbuf = new;
|
||||
pathsize *= 2;
|
||||
}
|
||||
|
||||
pathp -= namlen;
|
||||
(void) memcpy (pathp, d->d_name, namlen);
|
||||
*--pathp = '/';
|
||||
closedir(dirstream);
|
||||
}
|
||||
|
||||
thisdev = dotdev;
|
||||
thisino = dotino;
|
||||
}
|
||||
|
||||
if (pathp == &path[sizeof(path) - 1])
|
||||
*--pathp = '/';
|
||||
|
||||
if (dotlist != dots)
|
||||
free ((PTR) dotlist);
|
||||
|
||||
{
|
||||
size_t len = pathbuf + pathsize - pathp;
|
||||
if (buf == NULL)
|
||||
{
|
||||
if (len < (size_t) size)
|
||||
len = size;
|
||||
buf = (char *) malloc (len);
|
||||
if (buf == NULL)
|
||||
goto lose2;
|
||||
}
|
||||
else if ((size_t) size < len)
|
||||
{
|
||||
errno = ERANGE;
|
||||
goto lose2;
|
||||
}
|
||||
(void) memcpy((PTR) buf, (PTR) pathp, len);
|
||||
}
|
||||
|
||||
if (pathbuf != path)
|
||||
free (pathbuf);
|
||||
|
||||
return (buf);
|
||||
|
||||
lose:
|
||||
if ((dotlist != dots) && dotlist)
|
||||
{
|
||||
int e = errno;
|
||||
free ((PTR) dotlist);
|
||||
errno = e;
|
||||
}
|
||||
|
||||
lose2:
|
||||
if ((pathbuf != path) && pathbuf)
|
||||
{
|
||||
int e = errno;
|
||||
free ((PTR) pathbuf);
|
||||
errno = e;
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
#endif
|
2779
source3/smbd/ipc.c
Normal file
2779
source3/smbd/ipc.c
Normal file
File diff suppressed because it is too large
Load Diff
610
source3/smbd/mangle.c
Normal file
610
source3/smbd/mangle.c
Normal file
@ -0,0 +1,610 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
Name mangling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
extern int case_default;
|
||||
extern BOOL case_mangle;
|
||||
|
||||
/****************************************************************************
|
||||
provide a checksum on a string
|
||||
****************************************************************************/
|
||||
int str_checksum(char *s)
|
||||
{
|
||||
int res = 0;
|
||||
int c;
|
||||
int i=0;
|
||||
while (*s)
|
||||
{
|
||||
c = *s;
|
||||
res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
|
||||
s++; i++;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
return True if a name is a special msdos reserved name
|
||||
****************************************************************************/
|
||||
static BOOL is_reserved_msdos(char *fname)
|
||||
{
|
||||
char upperFname[13];
|
||||
char *p;
|
||||
|
||||
StrnCpy (upperFname, fname, 12);
|
||||
|
||||
/* lpt1.txt and con.txt etc are also illegal */
|
||||
p=strchr(upperFname,'.');
|
||||
if (p)
|
||||
*p='\0';
|
||||
strupper (upperFname);
|
||||
if ((strcmp(upperFname,"CLOCK$") == 0) ||
|
||||
(strcmp(upperFname,"CON") == 0) ||
|
||||
(strcmp(upperFname,"AUX") == 0) ||
|
||||
(strcmp(upperFname,"COM1") == 0) ||
|
||||
(strcmp(upperFname,"COM2") == 0) ||
|
||||
(strcmp(upperFname,"COM3") == 0) ||
|
||||
(strcmp(upperFname,"COM4") == 0) ||
|
||||
(strcmp(upperFname,"LPT1") == 0) ||
|
||||
(strcmp(upperFname,"LPT2") == 0) ||
|
||||
(strcmp(upperFname,"LPT3") == 0) ||
|
||||
(strcmp(upperFname,"NUL") == 0) ||
|
||||
(strcmp(upperFname,"PRN") == 0))
|
||||
return (True) ;
|
||||
|
||||
return (False);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
return True if a name is in 8.3 dos format
|
||||
****************************************************************************/
|
||||
BOOL is_8_3(char *fname)
|
||||
{
|
||||
int len;
|
||||
char *dot_pos;
|
||||
char *slash_pos = strrchr(fname,'/');
|
||||
int l;
|
||||
|
||||
if (slash_pos) fname = slash_pos+1;
|
||||
len = strlen(fname);
|
||||
|
||||
dot_pos = strchr(fname,'.');
|
||||
|
||||
DEBUG(5,("checking %s for 8.3\n",fname));
|
||||
|
||||
if (case_mangle)
|
||||
switch (case_default)
|
||||
{
|
||||
case CASE_LOWER:
|
||||
if (strhasupper(fname)) return(False);
|
||||
break;
|
||||
case CASE_UPPER:
|
||||
if (strhaslower(fname)) return(False);
|
||||
break;
|
||||
}
|
||||
|
||||
/* can't be longer than 12 chars */
|
||||
if (len == 0 || len > 12)
|
||||
return(False);
|
||||
|
||||
/* can't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
|
||||
if (is_reserved_msdos(fname))
|
||||
return(False);
|
||||
|
||||
/* can't contain invalid dos chars */
|
||||
/* Windows use the ANSI charset.
|
||||
But filenames are translated in the PC charset.
|
||||
This Translation may be more or less relaxed depending
|
||||
the Windows application. */
|
||||
|
||||
/* %%% A nice improvment to name mangling would be to translate
|
||||
filename to ANSI charset on the smb server host */
|
||||
|
||||
{
|
||||
char *p = fname;
|
||||
#ifdef KANJI
|
||||
dot_pos = 0;
|
||||
while (*p)
|
||||
{
|
||||
if (is_shift_jis (*p)) {
|
||||
p += 2;
|
||||
} else if (is_kana (*p)) {
|
||||
p ++;
|
||||
} else {
|
||||
if (*p == '.' && !dot_pos)
|
||||
dot_pos = (char *) p;
|
||||
if (!isdoschar(*p))
|
||||
return(False);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (*p)
|
||||
{
|
||||
if (!isdoschar(*p))
|
||||
return(False);
|
||||
p++;
|
||||
}
|
||||
#endif /* KANJI */
|
||||
}
|
||||
|
||||
/* no dot and less than 9 means OK */
|
||||
if (!dot_pos)
|
||||
return(len <= 8);
|
||||
|
||||
l = PTR_DIFF(dot_pos,fname);
|
||||
|
||||
/* base must be at least 1 char except special cases . and .. */
|
||||
if (l == 0)
|
||||
return(strcmp(fname,".") == 0 || strcmp(fname,"..") == 0);
|
||||
|
||||
/* base can't be greater than 8 */
|
||||
if (l > 8)
|
||||
return(False);
|
||||
|
||||
if (lp_strip_dot() &&
|
||||
len - l == 1 &&
|
||||
!strchr(dot_pos+1,'.'))
|
||||
{
|
||||
*dot_pos = 0;
|
||||
return(True);
|
||||
}
|
||||
|
||||
/* extension must be between 1 and 3 */
|
||||
if ( (len - l < 2 ) || (len - l > 4) )
|
||||
return(False);
|
||||
|
||||
/* extension can't have a dot */
|
||||
if (strchr(dot_pos+1,'.'))
|
||||
return(False);
|
||||
|
||||
/* must be in 8.3 format */
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
keep a stack of name mangling results - just
|
||||
so file moves and copies have a chance of working
|
||||
*/
|
||||
fstring *mangled_stack = NULL;
|
||||
int mangled_stack_size = 0;
|
||||
int mangled_stack_len = 0;
|
||||
|
||||
/****************************************************************************
|
||||
create the mangled stack
|
||||
****************************************************************************/
|
||||
void create_mangled_stack(int size)
|
||||
{
|
||||
if (mangled_stack)
|
||||
{
|
||||
free(mangled_stack);
|
||||
mangled_stack_size = 0;
|
||||
mangled_stack_len = 0;
|
||||
}
|
||||
if (size > 0)
|
||||
mangled_stack = (fstring *)malloc(sizeof(fstring)*size);
|
||||
if (mangled_stack) mangled_stack_size = size;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
push a mangled name onto the stack
|
||||
****************************************************************************/
|
||||
static void push_mangled_name(char *s)
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
if (!mangled_stack)
|
||||
return;
|
||||
|
||||
for (i=0;i<mangled_stack_len;i++)
|
||||
if (strcmp(s,mangled_stack[i]) == 0)
|
||||
{
|
||||
array_promote(mangled_stack[0],sizeof(fstring),i);
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(mangled_stack[1],mangled_stack[0],
|
||||
sizeof(fstring)*MIN(mangled_stack_len,mangled_stack_size-1));
|
||||
strcpy(mangled_stack[0],s);
|
||||
p = strrchr(mangled_stack[0],'.');
|
||||
if (p && (!strhasupper(p+1)) && (strlen(p+1) < 4))
|
||||
*p = 0;
|
||||
mangled_stack_len = MIN(mangled_stack_size,mangled_stack_len+1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
check for a name on the mangled name stack
|
||||
****************************************************************************/
|
||||
BOOL check_mangled_stack(char *s)
|
||||
{
|
||||
int i;
|
||||
pstring tmpname;
|
||||
char extension[5];
|
||||
char *p = strrchr(s,'.');
|
||||
BOOL check_extension = False;
|
||||
|
||||
extension[0] = 0;
|
||||
|
||||
if (!mangled_stack) return(False);
|
||||
|
||||
if (p)
|
||||
{
|
||||
check_extension = True;
|
||||
StrnCpy(extension,p,4);
|
||||
strlower(extension); /* XXXXXXX */
|
||||
}
|
||||
|
||||
for (i=0;i<mangled_stack_len;i++)
|
||||
{
|
||||
strcpy(tmpname,mangled_stack[i]);
|
||||
mangle_name_83(tmpname);
|
||||
if (strequal(tmpname,s))
|
||||
{
|
||||
strcpy(s,mangled_stack[i]);
|
||||
break;
|
||||
}
|
||||
if (check_extension && !strchr(mangled_stack[i],'.'))
|
||||
{
|
||||
strcpy(tmpname,mangled_stack[i]);
|
||||
strcat(tmpname,extension);
|
||||
mangle_name_83(tmpname);
|
||||
if (strequal(tmpname,s))
|
||||
{
|
||||
strcpy(s,mangled_stack[i]);
|
||||
strcat(s,extension);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < mangled_stack_len)
|
||||
{
|
||||
DEBUG(3,("Found %s on mangled stack as %s\n",s,mangled_stack[i]));
|
||||
array_promote(mangled_stack[0],sizeof(fstring),i);
|
||||
return(True);
|
||||
}
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
static char *map_filename(char *s, /* This is null terminated */
|
||||
char *pattern, /* This isn't. */
|
||||
int len) /* This is the length of pattern. */
|
||||
{
|
||||
static pstring matching_bit; /* The bit of the string which matches */
|
||||
/* a * in pattern if indeed there is a * */
|
||||
char *sp; /* Pointer into s. */
|
||||
char *pp; /* Pointer into p. */
|
||||
char *match_start; /* Where the matching bit starts. */
|
||||
pstring pat;
|
||||
|
||||
StrnCpy(pat, pattern, len); /* Get pattern into a proper string! */
|
||||
strcpy(matching_bit,""); /* Match but no star gets this. */
|
||||
pp = pat; /* Initialise the pointers. */
|
||||
sp = s;
|
||||
if ((len == 1) && (*pattern == '*')) {
|
||||
return NULL; /* Impossible, too ambiguous for */
|
||||
/* words! */
|
||||
}
|
||||
|
||||
while ((*sp) /* Not the end of the string. */
|
||||
&& (*pp) /* Not the end of the pattern. */
|
||||
&& (*sp == *pp) /* The two match. */
|
||||
&& (*pp != '*')) { /* No wildcard. */
|
||||
sp++; /* Keep looking. */
|
||||
pp++;
|
||||
}
|
||||
if (!*sp && !*pp) /* End of pattern. */
|
||||
return matching_bit; /* Simple match. Return empty string. */
|
||||
if (*pp == '*') {
|
||||
pp++; /* Always interrested in the chacter */
|
||||
/* after the '*' */
|
||||
if (!*pp) { /* It is at the end of the pattern. */
|
||||
StrnCpy(matching_bit, s, sp-s);
|
||||
return matching_bit;
|
||||
} else {
|
||||
/* The next character in pattern must match a character further */
|
||||
/* along s than sp so look for that character. */
|
||||
match_start = sp;
|
||||
while ((*sp) /* Not the end of s. */
|
||||
&& (*sp != *pp)) /* Not the same */
|
||||
sp++; /* Keep looking. */
|
||||
if (!*sp) { /* Got to the end without a match. */
|
||||
return NULL;
|
||||
} else { /* Still hope for a match. */
|
||||
/* Now sp should point to a matching character. */
|
||||
StrnCpy(matching_bit, match_start, sp-match_start);
|
||||
/* Back to needing a stright match again. */
|
||||
while ((*sp) /* Not the end of the string. */
|
||||
&& (*pp) /* Not the end of the pattern. */
|
||||
&& (*sp == *pp)) { /* The two match. */
|
||||
sp++; /* Keep looking. */
|
||||
pp++;
|
||||
}
|
||||
if (!*sp && !*pp) /* Both at end so it matched */
|
||||
return matching_bit;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL; /* No match. */
|
||||
}
|
||||
|
||||
|
||||
/* this is the magic char used for mangling */
|
||||
char magic_char = '~';
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
determine whther is name could be a mangled name
|
||||
****************************************************************************/
|
||||
BOOL is_mangled(char *s)
|
||||
{
|
||||
char *m = strchr(s,magic_char);
|
||||
if (!m) return(False);
|
||||
|
||||
/* we use two base 36 chars efore the extension */
|
||||
if (m[1] == '.' || m[1] == 0 ||
|
||||
m[2] == '.' || m[2] == 0 ||
|
||||
(m[3] != '.' && m[3] != 0))
|
||||
return(is_mangled(m+1));
|
||||
|
||||
/* it could be */
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
return a base 36 character. v must be from 0 to 35.
|
||||
****************************************************************************/
|
||||
static char base36(int v)
|
||||
{
|
||||
v = v % 36;
|
||||
if (v < 10)
|
||||
return('0'+v);
|
||||
else /* needed to work around a DEC C compiler bug */
|
||||
return('A' + (v-10));
|
||||
}
|
||||
|
||||
|
||||
static void do_fwd_mangled_map(char *s, char *MangledMap)
|
||||
{
|
||||
/* MangledMap is a series of name pairs in () separated by spaces.
|
||||
* If s matches the first of the pair then the name given is the
|
||||
* second of the pair. A * means any number of any character and if
|
||||
* present in the second of the pair as well as the first the
|
||||
* matching part of the first string takes the place of the * in the
|
||||
* second.
|
||||
*
|
||||
* I wanted this so that we could have RCS files which can be used
|
||||
* by UNIX and DOS programs. My mapping string is (RCS rcs) which
|
||||
* converts the UNIX RCS file subdirectory to lowercase thus
|
||||
* preventing mangling.
|
||||
*/
|
||||
char *start=MangledMap; /* Use this to search for mappings. */
|
||||
char *end; /* Used to find the end of strings. */
|
||||
char *match_string;
|
||||
pstring new_string; /* Make up the result here. */
|
||||
char *np; /* Points into new_string. */
|
||||
|
||||
DEBUG(5,("Mangled Mapping '%s' map '%s'\n", s, MangledMap));
|
||||
while (*start) {
|
||||
while ((*start) && (*start != '('))
|
||||
start++;
|
||||
start++; /* Skip the ( */
|
||||
if (!*start)
|
||||
continue; /* Always check for the end. */
|
||||
end = start; /* Search for the ' ' or a ')' */
|
||||
DEBUG(5,("Start of first in pair '%s'\n", start));
|
||||
while ((*end) && !((*end == ' ') || (*end == ')')))
|
||||
end++;
|
||||
if (!*end) {
|
||||
start = end;
|
||||
continue; /* Always check for the end. */
|
||||
}
|
||||
DEBUG(5,("End of first in pair '%s'\n", end));
|
||||
if ((match_string = map_filename(s, start, end-start))) {
|
||||
DEBUG(5,("Found a match\n"));
|
||||
/* Found a match. */
|
||||
start = end+1; /* Point to start of what it is to become. */
|
||||
DEBUG(5,("Start of second in pair '%s'\n", start));
|
||||
end = start;
|
||||
np = new_string;
|
||||
while ((*end) /* Not the end of string. */
|
||||
&& (*end != ')') /* Not the end of the pattern. */
|
||||
&& (*end != '*')) /* Not a wildcard. */
|
||||
*np++ = *end++;
|
||||
if (!*end) {
|
||||
start = end;
|
||||
continue; /* Always check for the end. */
|
||||
}
|
||||
if (*end == '*') {
|
||||
strcpy(np, match_string);
|
||||
np += strlen(match_string);
|
||||
end++; /* Skip the '*' */
|
||||
while ((*end) /* Not the end of string. */
|
||||
&& (*end != ')') /* Not the end of the pattern. */
|
||||
&& (*end != '*')) /* Not a wildcard. */
|
||||
*np++ = *end++;
|
||||
}
|
||||
if (!*end) {
|
||||
start = end;
|
||||
continue; /* Always check for the end. */
|
||||
}
|
||||
*np++ = '\0'; /* NULL terminate it. */
|
||||
DEBUG(5,("End of second in pair '%s'\n", end));
|
||||
strcpy(s, new_string); /* Substitute with the new name. */
|
||||
DEBUG(5,("s is now '%s'\n", s));
|
||||
}
|
||||
start = end; /* Skip a bit which cannot be wanted */
|
||||
/* anymore. */
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
do the actual mangling to 8.3 format
|
||||
****************************************************************************/
|
||||
void mangle_name_83(char *s)
|
||||
{
|
||||
int csum = str_checksum(s);
|
||||
char *p;
|
||||
char extension[4];
|
||||
char base[9];
|
||||
int baselen = 0;
|
||||
int extlen = 0;
|
||||
|
||||
extension[0]=0;
|
||||
base[0]=0;
|
||||
|
||||
p = strrchr(s,'.');
|
||||
if (p && (strlen(p+1)<4) )
|
||||
{
|
||||
BOOL all_normal = (strisnormal(p+1)); /* XXXXXXXXX */
|
||||
if (all_normal && p[1] != 0)
|
||||
{
|
||||
*p = 0;
|
||||
csum = str_checksum(s);
|
||||
*p = '.';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
strupper(s);
|
||||
|
||||
DEBUG(5,("Mangling name %s to ",s));
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (p == s)
|
||||
strcpy(extension,"___");
|
||||
else
|
||||
{
|
||||
*p++ = 0;
|
||||
while (*p && extlen < 3)
|
||||
{
|
||||
if (isdoschar(*p) && *p != '.')
|
||||
extension[extlen++] = *p;
|
||||
p++;
|
||||
}
|
||||
extension[extlen] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = s;
|
||||
|
||||
while (*p && baselen < 5)
|
||||
{
|
||||
if (isdoschar(*p) && *p != '.')
|
||||
base[baselen++] = *p;
|
||||
p++;
|
||||
}
|
||||
base[baselen] = 0;
|
||||
|
||||
csum = csum % (36*36);
|
||||
|
||||
sprintf(s,"%s%c%c%c",base,magic_char,base36(csum/36),base36(csum%36));
|
||||
|
||||
if (*extension)
|
||||
{
|
||||
strcat(s,".");
|
||||
strcat(s,extension);
|
||||
}
|
||||
DEBUG(5,("%s\n",s));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
work out if a name is illegal, even for long names
|
||||
******************************************************************/
|
||||
static BOOL illegal_name(char *name)
|
||||
{
|
||||
static unsigned char illegal[256];
|
||||
static BOOL initialised=False;
|
||||
unsigned char *s;
|
||||
|
||||
if (!initialised) {
|
||||
char *ill = "*\\/?<>|\":{}";
|
||||
initialised = True;
|
||||
|
||||
bzero((char *)illegal,256);
|
||||
for (s = (unsigned char *)ill; *s; s++)
|
||||
illegal[*s] = True;
|
||||
}
|
||||
|
||||
#ifdef KANJI
|
||||
for (s = (unsigned char *)name; *s;) {
|
||||
if (is_shift_jis (*s)) {
|
||||
s += 2;
|
||||
} else if (illegal[*s]) {
|
||||
return(True);
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (s = (unsigned char *)name;*s;s++)
|
||||
if (illegal[*s]) return(True);
|
||||
#endif
|
||||
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
convert a filename to DOS format. return True if successful.
|
||||
****************************************************************************/
|
||||
BOOL name_map_mangle(char *OutName,BOOL need83,int snum)
|
||||
{
|
||||
#ifdef MANGLE_LONG_FILENAMES
|
||||
if (!need83 && illegal_name(OutName)) need83 = True;
|
||||
#endif
|
||||
|
||||
/* apply any name mappings */
|
||||
{
|
||||
char *map = lp_mangled_map(snum);
|
||||
if (map && *map)
|
||||
do_fwd_mangled_map(OutName,map);
|
||||
}
|
||||
|
||||
/* check if it's already in 8.3 format */
|
||||
if (need83 && !is_8_3(OutName)) {
|
||||
if (!lp_manglednames(snum)) return(False);
|
||||
|
||||
/* mangle it into 8.3 */
|
||||
push_mangled_name(OutName);
|
||||
mangle_name_83(OutName);
|
||||
}
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
204
source3/smbd/message.c
Normal file
204
source3/smbd/message.c
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
SMB messaging
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
This file handles the messaging system calls for winpopup style
|
||||
messages
|
||||
*/
|
||||
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
/* look in server.c for some explanation of these variables */
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
|
||||
static char msgbuf[1600];
|
||||
static int msgpos=0;
|
||||
static fstring msgfrom="";
|
||||
static fstring msgto="";
|
||||
|
||||
/****************************************************************************
|
||||
deliver the message
|
||||
****************************************************************************/
|
||||
static void msg_deliver(void)
|
||||
{
|
||||
pstring s;
|
||||
fstring name;
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
if (! (*lp_msg_command()))
|
||||
{
|
||||
DEBUG(1,("no messaging command specified\n"));
|
||||
msgpos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* put it in a temporary file */
|
||||
sprintf(s,"/tmp/msg.XXXXXX");
|
||||
strcpy(name,(char *)mktemp(s));
|
||||
|
||||
f = fopen(name,"w");
|
||||
if (!f)
|
||||
{
|
||||
DEBUG(1,("can't open message file %s\n",name));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0;i<msgpos;)
|
||||
{
|
||||
if (msgbuf[i]=='\r' && i<(msgpos-1) && msgbuf[i+1]=='\n')
|
||||
i++;
|
||||
fputc(msgbuf[i++],f);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
|
||||
/* run the command */
|
||||
if (*lp_msg_command())
|
||||
{
|
||||
strcpy(s,lp_msg_command());
|
||||
string_sub(s,"%s",name);
|
||||
string_sub(s,"%f",msgfrom);
|
||||
string_sub(s,"%t",msgto);
|
||||
standard_sub(-1,s);
|
||||
smbrun(s,NULL);
|
||||
}
|
||||
|
||||
msgpos = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
reply to a sends
|
||||
****************************************************************************/
|
||||
int reply_sends(char *inbuf,char *outbuf)
|
||||
{
|
||||
int len;
|
||||
char *orig,*dest,*msg;
|
||||
int outsize = 0;
|
||||
|
||||
msgpos = 0;
|
||||
|
||||
|
||||
if (! (*lp_msg_command()))
|
||||
return(ERROR(ERRSRV,ERRmsgoff));
|
||||
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
|
||||
orig = smb_buf(inbuf)+1;
|
||||
dest = skip_string(orig,1)+1;
|
||||
msg = skip_string(dest,1)+1;
|
||||
|
||||
strcpy(msgfrom,orig);
|
||||
strcpy(msgto,dest);
|
||||
|
||||
len = SVAL(msg,0);
|
||||
len = MIN(len,1600-msgpos);
|
||||
|
||||
memcpy(&msgbuf[msgpos],msg+2,len);
|
||||
msgpos += len;
|
||||
|
||||
DEBUG(3,("%s SMBsends (from %s to %s)\n",timestring(),orig,dest));
|
||||
|
||||
msg_deliver();
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
reply to a sendstrt
|
||||
****************************************************************************/
|
||||
int reply_sendstrt(char *inbuf,char *outbuf)
|
||||
{
|
||||
char *orig,*dest;
|
||||
int outsize = 0;
|
||||
|
||||
if (! (*lp_msg_command()))
|
||||
return(ERROR(ERRSRV,ERRmsgoff));
|
||||
|
||||
outsize = set_message(outbuf,1,0,True);
|
||||
|
||||
msgpos = 0;
|
||||
|
||||
orig = smb_buf(inbuf)+1;
|
||||
dest = skip_string(orig,1)+1;
|
||||
|
||||
strcpy(msgfrom,orig);
|
||||
strcpy(msgto,dest);
|
||||
|
||||
DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),orig,dest));
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
reply to a sendtxt
|
||||
****************************************************************************/
|
||||
int reply_sendtxt(char *inbuf,char *outbuf)
|
||||
{
|
||||
int len;
|
||||
int outsize = 0;
|
||||
char *msg;
|
||||
|
||||
if (! (*lp_msg_command()))
|
||||
return(ERROR(ERRSRV,ERRmsgoff));
|
||||
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
|
||||
msg = smb_buf(inbuf) + 1;
|
||||
|
||||
len = SVAL(msg,0);
|
||||
len = MIN(len,1600-msgpos);
|
||||
|
||||
memcpy(&msgbuf[msgpos],msg+2,len);
|
||||
msgpos += len;
|
||||
|
||||
DEBUG(3,("%s SMBsendtxt\n",timestring()));
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
reply to a sendend
|
||||
****************************************************************************/
|
||||
int reply_sendend(char *inbuf,char *outbuf)
|
||||
{
|
||||
int outsize = 0;
|
||||
|
||||
if (! (*lp_msg_command()))
|
||||
return(ERROR(ERRSRV,ERRmsgoff));
|
||||
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
|
||||
DEBUG(3,("%s SMBsendend\n",timestring()));
|
||||
|
||||
msg_deliver();
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
|
1416
source3/smbd/password.c
Normal file
1416
source3/smbd/password.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user